diff --git a/pkg/commands/git_commands/stash.go b/pkg/commands/git_commands/stash.go index 176a67e52..9c7321b50 100644 --- a/pkg/commands/git_commands/stash.go +++ b/pkg/commands/git_commands/stash.go @@ -1,9 +1,7 @@ package git_commands import ( - "errors" "fmt" - "regexp" "strings" "github.com/jesseduffield/lazygit/pkg/commands/loaders" @@ -32,9 +30,8 @@ func (self *StashCommands) DropNewest() error { return self.cmd.New("git stash drop").Run() } -func (self *StashCommands) Drop(index int) (string, error) { - output, _, err := self.cmd.New(fmt.Sprintf("git stash drop stash@{%d}", index)).RunWithOutputs() - return output, err +func (self *StashCommands) Drop(index int) error { + return self.cmd.New(fmt.Sprintf("git stash drop stash@{%d}", index)).Run() } func (self *StashCommands) Pop(index int) error { @@ -58,6 +55,11 @@ func (self *StashCommands) Store(sha string, message string) error { return self.cmd.New(fmt.Sprintf("git stash store %s", self.cmd.Quote(sha))).Run() } +func (self *StashCommands) Sha(index int) (string, error) { + sha, _, err := self.cmd.New(fmt.Sprintf("git rev-parse refs/stash@{%d}", index)).DontLog().RunWithOutputs() + return strings.Trim(sha, "\r\n"), err +} + func (self *StashCommands) ShowStashEntryCmdObj(index int) oscommands.ICmdObj { cmdStr := fmt.Sprintf("git stash show -p --stat --color=%s --unified=%d stash@{%d}", self.UserConfig.Git.Paging.ColorArg, self.UserConfig.Git.DiffContextSize, index) @@ -123,21 +125,16 @@ func (self *StashCommands) SaveStagedChanges(message string) error { } func (self *StashCommands) Rename(index int, message string) error { - output, err := self.Drop(index) + sha, err := self.Sha(index) if err != nil { return err } - // `output` is in the following format: - // Dropped refs/stash@{0} (f0d0f20f2f61ffd6d6bfe0752deffa38845a3edd) - stashShaPattern := regexp.MustCompile(`\(([0-9a-f]+)\)`) - matches := stashShaPattern.FindStringSubmatch(output) - if len(matches) <= 1 { - return errors.New("Output of `git stash drop` is invalid") // Usually this error does not occur + if err := self.Drop(index); err != nil { + return err } - stashSha := matches[1] - err = self.Store(stashSha, message) + err = self.Store(sha, message) if err != nil { return err } diff --git a/pkg/commands/git_commands/stash_test.go b/pkg/commands/git_commands/stash_test.go index 41efc07db..1a4e50822 100644 --- a/pkg/commands/git_commands/stash_test.go +++ b/pkg/commands/git_commands/stash_test.go @@ -10,12 +10,10 @@ import ( func TestStashDrop(t *testing.T) { runner := oscommands.NewFakeRunner(t). - ExpectGitArgs([]string{"stash", "drop", "stash@{1}"}, "Dropped refs/stash@{1} (98e9cca532c37c766107093010c72e26f2c24c04)", nil) + ExpectGitArgs([]string{"stash", "drop", "stash@{1}"}, "Dropped refs/stash@{1} (98e9cca532c37c766107093010c72e26f2c24c04)\n", nil) instance := buildStashCommands(commonDeps{runner: runner}) - output, err := instance.Drop(1) - assert.NoError(t, err) - assert.Equal(t, "Dropped refs/stash@{1} (98e9cca532c37c766107093010c72e26f2c24c04)", output) + assert.NoError(t, instance.Drop(1)) runner.CheckForMissingCalls() } @@ -88,6 +86,17 @@ func TestStashStore(t *testing.T) { } } +func TestStashSha(t *testing.T) { + runner := oscommands.NewFakeRunner(t). + ExpectGitArgs([]string{"rev-parse", "refs/stash@{5}"}, "14d94495194651adfd5f070590df566c11d28243\n", nil) + instance := buildStashCommands(commonDeps{runner: runner}) + + sha, err := instance.Sha(5) + assert.NoError(t, err) + assert.Equal(t, "14d94495194651adfd5f070590df566c11d28243", sha) + runner.CheckForMissingCalls() +} + func TestStashStashEntryCmdObj(t *testing.T) { type scenario struct { testName string @@ -129,8 +138,9 @@ func TestStashRename(t *testing.T) { testName string index int message string + expectedShaCmd []string + shaResult string expectedDropCmd []string - dropResult string expectedStoreCmd []string } @@ -139,16 +149,18 @@ func TestStashRename(t *testing.T) { testName: "Default case", index: 3, message: "New message", + expectedShaCmd: []string{"rev-parse", "refs/stash@{3}"}, + shaResult: "f0d0f20f2f61ffd6d6bfe0752deffa38845a3edd\n", expectedDropCmd: []string{"stash", "drop", "stash@{3}"}, - dropResult: "Dropped refs/stash@{3} (f0d0f20f2f61ffd6d6bfe0752deffa38845a3edd)\n", expectedStoreCmd: []string{"stash", "store", "f0d0f20f2f61ffd6d6bfe0752deffa38845a3edd", "-m", "New message"}, }, { testName: "Empty message", index: 4, message: "", + expectedShaCmd: []string{"rev-parse", "refs/stash@{4}"}, + shaResult: "f0d0f20f2f61ffd6d6bfe0752deffa38845a3edd\n", expectedDropCmd: []string{"stash", "drop", "stash@{4}"}, - dropResult: "Dropped refs/stash@{4} (f0d0f20f2f61ffd6d6bfe0752deffa38845a3edd)\n", expectedStoreCmd: []string{"stash", "store", "f0d0f20f2f61ffd6d6bfe0752deffa38845a3edd"}, }, } @@ -157,7 +169,8 @@ func TestStashRename(t *testing.T) { s := s t.Run(s.testName, func(t *testing.T) { runner := oscommands.NewFakeRunner(t). - ExpectGitArgs(s.expectedDropCmd, s.dropResult, nil). + ExpectGitArgs(s.expectedShaCmd, s.shaResult, nil). + ExpectGitArgs(s.expectedDropCmd, "", nil). ExpectGitArgs(s.expectedStoreCmd, "", nil) instance := buildStashCommands(commonDeps{runner: runner}) diff --git a/pkg/gui/controllers/stash_controller.go b/pkg/gui/controllers/stash_controller.go index 1e4137777..68a121931 100644 --- a/pkg/gui/controllers/stash_controller.go +++ b/pkg/gui/controllers/stash_controller.go @@ -128,7 +128,7 @@ func (self *StashController) handleStashDrop(stashEntry *models.StashEntry) erro Prompt: self.c.Tr.SureDropStashEntry, HandleConfirm: func() error { self.c.LogAction(self.c.Tr.Actions.Stash) - _, err := self.git.Stash.Drop(stashEntry.Index) + err := self.git.Stash.Drop(stashEntry.Index) _ = self.c.Refresh(types.RefreshOptions{Scope: []types.RefreshableView{types.STASH}}) if err != nil { return self.c.Error(err)