Skip to content

Commit fb2c5ea

Browse files
authored
Fix stash operations when branch named 'stash' exists (#4641)
- **PR Description** Pretty basic fix, didn't seem to have any complications. I basically just grepped for `stash{` and all of the references seemed like they could benefit from the addition. I only added the refs/ prefix to the FullRefName() method to align with other similar methods, and to make this change not impact any user facing modals. I added one integration test for the super obvious failure behavior. I didn't feel that it was worth it to create duplicate integration tests for the other behaviors of drop, apply, pop, etc. I did manually test them though. If interested, I could add the creation of the `stash` branch to all the existing tests of stash behavior, just to prove they continue to work under those conditions. I just didn't do that on the first pass cause I could see how that could take away from the core behavior the tests are trying to demonstrate. Fixes: #4634
2 parents aa23a6e + 265557a commit fb2c5ea

File tree

12 files changed

+74
-17
lines changed

12 files changed

+74
-17
lines changed

pkg/commands/git_commands/stash.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,21 +32,21 @@ func (self *StashCommands) DropNewest() error {
3232
}
3333

3434
func (self *StashCommands) Drop(index int) error {
35-
cmdArgs := NewGitCmd("stash").Arg("drop", fmt.Sprintf("stash@{%d}", index)).
35+
cmdArgs := NewGitCmd("stash").Arg("drop", fmt.Sprintf("refs/stash@{%d}", index)).
3636
ToArgv()
3737

3838
return self.cmd.New(cmdArgs).Run()
3939
}
4040

4141
func (self *StashCommands) Pop(index int) error {
42-
cmdArgs := NewGitCmd("stash").Arg("pop", fmt.Sprintf("stash@{%d}", index)).
42+
cmdArgs := NewGitCmd("stash").Arg("pop", fmt.Sprintf("refs/stash@{%d}", index)).
4343
ToArgv()
4444

4545
return self.cmd.New(cmdArgs).Run()
4646
}
4747

4848
func (self *StashCommands) Apply(index int) error {
49-
cmdArgs := NewGitCmd("stash").Arg("apply", fmt.Sprintf("stash@{%d}", index)).
49+
cmdArgs := NewGitCmd("stash").Arg("apply", fmt.Sprintf("refs/stash@{%d}", index)).
5050
ToArgv()
5151

5252
return self.cmd.New(cmdArgs).Run()
@@ -90,7 +90,7 @@ func (self *StashCommands) ShowStashEntryCmdObj(index int) *oscommands.CmdObj {
9090
Arg(fmt.Sprintf("--unified=%d", self.AppState.DiffContextSize)).
9191
ArgIf(self.AppState.IgnoreWhitespaceInDiffView, "--ignore-all-space").
9292
Arg(fmt.Sprintf("--find-renames=%d%%", self.AppState.RenameSimilarityThreshold)).
93-
Arg(fmt.Sprintf("stash@{%d}", index)).
93+
Arg(fmt.Sprintf("refs/stash@{%d}", index)).
9494
Dir(self.repoPaths.worktreePath).
9595
ToArgv()
9696

@@ -152,7 +152,7 @@ func (self *StashCommands) SaveStagedChanges(message string) error {
152152
}
153153

154154
if err := self.cmd.New(
155-
NewGitCmd("stash").Arg("apply", "stash@{1}").ToArgv(),
155+
NewGitCmd("stash").Arg("apply", "refs/stash@{1}").ToArgv(),
156156
).Run(); err != nil {
157157
return err
158158
}
@@ -165,7 +165,7 @@ func (self *StashCommands) SaveStagedChanges(message string) error {
165165
}
166166

167167
if err := self.cmd.New(
168-
NewGitCmd("stash").Arg("drop", "stash@{1}").ToArgv(),
168+
NewGitCmd("stash").Arg("drop", "refs/stash@{1}").ToArgv(),
169169
).Run(); err != nil {
170170
return err
171171
}

pkg/commands/git_commands/stash_test.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import (
1010

1111
func TestStashDrop(t *testing.T) {
1212
runner := oscommands.NewFakeRunner(t).
13-
ExpectGitArgs([]string{"stash", "drop", "stash@{1}"}, "Dropped refs/stash@{1} (98e9cca532c37c766107093010c72e26f2c24c04)\n", nil)
13+
ExpectGitArgs([]string{"stash", "drop", "refs/stash@{1}"}, "Dropped refs/stash@{1} (98e9cca532c37c766107093010c72e26f2c24c04)\n", nil)
1414
instance := buildStashCommands(commonDeps{runner: runner})
1515

1616
assert.NoError(t, instance.Drop(1))
@@ -19,7 +19,7 @@ func TestStashDrop(t *testing.T) {
1919

2020
func TestStashApply(t *testing.T) {
2121
runner := oscommands.NewFakeRunner(t).
22-
ExpectGitArgs([]string{"stash", "apply", "stash@{1}"}, "", nil)
22+
ExpectGitArgs([]string{"stash", "apply", "refs/stash@{1}"}, "", nil)
2323
instance := buildStashCommands(commonDeps{runner: runner})
2424

2525
assert.NoError(t, instance.Apply(1))
@@ -28,7 +28,7 @@ func TestStashApply(t *testing.T) {
2828

2929
func TestStashPop(t *testing.T) {
3030
runner := oscommands.NewFakeRunner(t).
31-
ExpectGitArgs([]string{"stash", "pop", "stash@{1}"}, "", nil)
31+
ExpectGitArgs([]string{"stash", "pop", "refs/stash@{1}"}, "", nil)
3232
instance := buildStashCommands(commonDeps{runner: runner})
3333

3434
assert.NoError(t, instance.Pop(1))
@@ -113,31 +113,31 @@ func TestStashStashEntryCmdObj(t *testing.T) {
113113
contextSize: 3,
114114
similarityThreshold: 50,
115115
ignoreWhitespace: false,
116-
expected: []string{"git", "-C", "/path/to/worktree", "stash", "show", "-p", "--stat", "-u", "--color=always", "--unified=3", "--find-renames=50%", "stash@{5}"},
116+
expected: []string{"git", "-C", "/path/to/worktree", "stash", "show", "-p", "--stat", "-u", "--color=always", "--unified=3", "--find-renames=50%", "refs/stash@{5}"},
117117
},
118118
{
119119
testName: "Show diff with custom context size",
120120
index: 5,
121121
contextSize: 77,
122122
similarityThreshold: 50,
123123
ignoreWhitespace: false,
124-
expected: []string{"git", "-C", "/path/to/worktree", "stash", "show", "-p", "--stat", "-u", "--color=always", "--unified=77", "--find-renames=50%", "stash@{5}"},
124+
expected: []string{"git", "-C", "/path/to/worktree", "stash", "show", "-p", "--stat", "-u", "--color=always", "--unified=77", "--find-renames=50%", "refs/stash@{5}"},
125125
},
126126
{
127127
testName: "Show diff with custom similarity threshold",
128128
index: 5,
129129
contextSize: 3,
130130
similarityThreshold: 33,
131131
ignoreWhitespace: false,
132-
expected: []string{"git", "-C", "/path/to/worktree", "stash", "show", "-p", "--stat", "-u", "--color=always", "--unified=3", "--find-renames=33%", "stash@{5}"},
132+
expected: []string{"git", "-C", "/path/to/worktree", "stash", "show", "-p", "--stat", "-u", "--color=always", "--unified=3", "--find-renames=33%", "refs/stash@{5}"},
133133
},
134134
{
135135
testName: "Default case",
136136
index: 5,
137137
contextSize: 3,
138138
similarityThreshold: 50,
139139
ignoreWhitespace: true,
140-
expected: []string{"git", "-C", "/path/to/worktree", "stash", "show", "-p", "--stat", "-u", "--color=always", "--unified=3", "--ignore-all-space", "--find-renames=50%", "stash@{5}"},
140+
expected: []string{"git", "-C", "/path/to/worktree", "stash", "show", "-p", "--stat", "-u", "--color=always", "--unified=3", "--ignore-all-space", "--find-renames=50%", "refs/stash@{5}"},
141141
},
142142
}
143143

@@ -177,7 +177,7 @@ func TestStashRename(t *testing.T) {
177177
message: "New message",
178178
expectedHashCmd: []string{"rev-parse", "refs/stash@{3}"},
179179
hashResult: "f0d0f20f2f61ffd6d6bfe0752deffa38845a3edd\n",
180-
expectedDropCmd: []string{"stash", "drop", "stash@{3}"},
180+
expectedDropCmd: []string{"stash", "drop", "refs/stash@{3}"},
181181
expectedStoreCmd: []string{"stash", "store", "-m", "New message", "f0d0f20f2f61ffd6d6bfe0752deffa38845a3edd"},
182182
},
183183
{
@@ -186,7 +186,7 @@ func TestStashRename(t *testing.T) {
186186
message: "",
187187
expectedHashCmd: []string{"rev-parse", "refs/stash@{4}"},
188188
hashResult: "f0d0f20f2f61ffd6d6bfe0752deffa38845a3edd\n",
189-
expectedDropCmd: []string{"stash", "drop", "stash@{4}"},
189+
expectedDropCmd: []string{"stash", "drop", "refs/stash@{4}"},
190190
expectedStoreCmd: []string{"stash", "store", "f0d0f20f2f61ffd6d6bfe0752deffa38845a3edd"},
191191
},
192192
}

pkg/commands/models/stash_entry.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ type StashEntry struct {
1010
}
1111

1212
func (s *StashEntry) FullRefName() string {
13-
return s.RefName()
13+
return "refs/" + s.RefName()
1414
}
1515

1616
func (s *StashEntry) RefName() string {

pkg/gui/controllers/stash_controller.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ func (self *StashController) postStashRefresh() error {
187187
}
188188

189189
func (self *StashController) handleNewBranchOffStashEntry(stashEntry *models.StashEntry) error {
190-
return self.c.Helpers().Refs.NewBranch(stashEntry.RefName(), stashEntry.Description(), "")
190+
return self.c.Helpers().Refs.NewBranch(stashEntry.FullRefName(), stashEntry.Description(), "")
191191
}
192192

193193
func (self *StashController) handleRenameStashEntry(stashEntry *models.StashEntry) error {

pkg/integration/tests/stash/apply.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ var Apply = NewIntegrationTest(NewIntegrationTestArgs{
1212
SetupConfig: func(config *config.AppConfig) {},
1313
SetupRepo: func(shell *Shell) {
1414
shell.EmptyCommit("initial commit")
15+
shell.NewBranch("stash")
16+
shell.Checkout("master")
1517
shell.CreateFile("file", "content")
1618
shell.GitAddAll()
1719
shell.Stash("stash one")

pkg/integration/tests/stash/create_branch.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ var CreateBranch = NewIntegrationTest(NewIntegrationTestArgs{
1212
SetupConfig: func(config *config.AppConfig) {},
1313
SetupRepo: func(shell *Shell) {
1414
shell.EmptyCommit("initial commit")
15+
shell.NewBranch("stash")
16+
shell.Checkout("master")
1517
shell.CreateFile("myfile", "content")
1618
shell.GitAddAll()
1719
shell.Stash("stash one")
@@ -39,6 +41,7 @@ var CreateBranch = NewIntegrationTest(NewIntegrationTestArgs{
3941
Lines(
4042
Contains("new_branch").IsSelected(),
4143
Contains("master"),
44+
Contains("stash"),
4245
).
4346
PressEnter()
4447

pkg/integration/tests/stash/drop.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ var Drop = NewIntegrationTest(NewIntegrationTestArgs{
1212
SetupConfig: func(config *config.AppConfig) {},
1313
SetupRepo: func(shell *Shell) {
1414
shell.EmptyCommit("initial commit")
15+
shell.NewBranch("stash")
16+
shell.Checkout("master")
1517
shell.CreateFile("file", "content")
1618
shell.GitAddAll()
1719
shell.Stash("stash one")

pkg/integration/tests/stash/pop.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ var Pop = NewIntegrationTest(NewIntegrationTestArgs{
1212
SetupConfig: func(config *config.AppConfig) {},
1313
SetupRepo: func(shell *Shell) {
1414
shell.EmptyCommit("initial commit")
15+
shell.NewBranch("stash")
16+
shell.Checkout("master")
1517
shell.CreateFile("file", "content")
1618
shell.GitAddAll()
1719
shell.Stash("stash one")

pkg/integration/tests/stash/rename.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ var Rename = NewIntegrationTest(NewIntegrationTestArgs{
1313
SetupRepo: func(shell *Shell) {
1414
shell.
1515
EmptyCommit("blah").
16+
NewBranch("stash").
17+
Checkout("master").
1618
CreateFileAndAdd("file-1", "change to stash1").
1719
Stash("foo").
1820
CreateFileAndAdd("file-2", "change to stash2").
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package stash
2+
3+
import (
4+
"github.com/jesseduffield/lazygit/pkg/config"
5+
. "github.com/jesseduffield/lazygit/pkg/integration/components"
6+
)
7+
8+
var ShowWithBranchNamedStash = NewIntegrationTest(NewIntegrationTestArgs{
9+
Description: "View stash when there is a branch also named 'stash'",
10+
ExtraCmdArgs: []string{},
11+
Skip: false,
12+
SetupConfig: func(config *config.AppConfig) {},
13+
SetupRepo: func(shell *Shell) {
14+
shell.EmptyCommit("initial commit")
15+
shell.CreateFile("file", "content")
16+
shell.GitAddAll()
17+
18+
shell.NewBranch("stash")
19+
},
20+
Run: func(t *TestDriver, keys config.KeybindingConfig) {
21+
t.Views().Stash().
22+
IsEmpty()
23+
24+
t.Views().Files().
25+
Lines(
26+
Contains("file"),
27+
).
28+
Press(keys.Files.StashAllChanges)
29+
30+
t.ExpectPopup().Prompt().Title(Equals("Stash changes")).Type("my stashed file").Confirm()
31+
32+
t.Views().Stash().
33+
Lines(
34+
MatchesRegexp(`\ds .* my stashed file`),
35+
)
36+
37+
t.Views().Files().
38+
IsEmpty()
39+
40+
t.Views().Stash().Focus()
41+
t.Views().Main().ContainsLines(Equals(" file | 1 +"))
42+
},
43+
})

0 commit comments

Comments
 (0)