1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2024-12-14 11:23:09 +02:00
lazygit/pkg/commands/git_commands/stash.go

197 lines
4.7 KiB
Go
Raw Normal View History

2022-01-08 05:00:36 +02:00
package git_commands
2020-09-29 12:03:39 +02:00
2021-12-30 08:19:01 +02:00
import (
"fmt"
2022-10-14 15:19:53 +02:00
"strings"
2021-12-30 08:19:01 +02:00
2022-01-05 02:57:32 +02:00
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
2021-12-30 08:19:01 +02:00
)
2020-09-29 12:03:39 +02:00
2022-01-02 01:34:33 +02:00
type StashCommands struct {
*GitCommon
fileLoader *FileLoader
2022-01-02 01:34:33 +02:00
workingTree *WorkingTreeCommands
}
func NewStashCommands(
gitCommon *GitCommon,
fileLoader *FileLoader,
2022-01-02 01:34:33 +02:00
workingTree *WorkingTreeCommands,
) *StashCommands {
return &StashCommands{
GitCommon: gitCommon,
2022-01-02 01:34:33 +02:00
fileLoader: fileLoader,
workingTree: workingTree,
}
}
2022-05-08 13:30:43 +02:00
func (self *StashCommands) DropNewest() error {
cmdArgs := NewGitCmd("stash").Arg("drop").ToArgv()
return self.cmd.New(cmdArgs).Run()
2022-05-08 13:30:43 +02:00
}
2022-10-16 02:11:54 +02:00
func (self *StashCommands) Drop(index int) error {
cmdArgs := NewGitCmd("stash").Arg("drop", fmt.Sprintf("stash@{%d}", index)).
ToArgv()
return self.cmd.New(cmdArgs).Run()
2022-01-02 01:34:33 +02:00
}
func (self *StashCommands) Pop(index int) error {
cmdArgs := NewGitCmd("stash").Arg("pop", fmt.Sprintf("stash@{%d}", index)).
ToArgv()
return self.cmd.New(cmdArgs).Run()
2022-01-02 01:34:33 +02:00
}
func (self *StashCommands) Apply(index int) error {
cmdArgs := NewGitCmd("stash").Arg("apply", fmt.Sprintf("stash@{%d}", index)).
ToArgv()
return self.cmd.New(cmdArgs).Run()
2020-09-29 12:03:39 +02:00
}
// Push push stash
func (self *StashCommands) Push(message string) error {
cmdArgs := NewGitCmd("stash").Arg("push", "-m", message).
ToArgv()
return self.cmd.New(cmdArgs).Run()
2022-10-14 15:19:53 +02:00
}
func (self *StashCommands) Store(sha string, message string) error {
trimmedMessage := strings.Trim(message, " \t")
cmdArgs := NewGitCmd("stash").Arg("store").
ArgIf(trimmedMessage != "", "-m", trimmedMessage).
Arg(sha).
ToArgv()
return self.cmd.New(cmdArgs).Run()
2020-09-29 12:03:39 +02:00
}
2022-10-16 02:11:54 +02:00
func (self *StashCommands) Sha(index int) (string, error) {
cmdArgs := NewGitCmd("rev-parse").
Arg(fmt.Sprintf("refs/stash@{%d}", index)).
ToArgv()
sha, _, err := self.cmd.New(cmdArgs).DontLog().RunWithOutputs()
2022-10-16 02:11:54 +02:00
return strings.Trim(sha, "\r\n"), err
}
func (self *StashCommands) ShowStashEntryCmdObj(index int) oscommands.ICmdObj {
cmdArgs := NewGitCmd("stash").Arg("show").
Arg("-p").
Arg("--stat").
Arg(fmt.Sprintf("--color=%s", self.UserConfig.Git.Paging.ColorArg)).
Arg(fmt.Sprintf("--unified=%d", self.AppState.DiffContextSize)).
ArgIf(self.AppState.IgnoreWhitespaceInDiffView, "--ignore-all-space").
Arg(fmt.Sprintf("stash@{%d}", index)).
ToArgv()
2022-01-05 02:57:32 +02:00
return self.cmd.New(cmdArgs).DontLog()
2020-09-29 12:03:39 +02:00
}
func (self *StashCommands) StashAndKeepIndex(message string) error {
cmdArgs := NewGitCmd("stash").Arg("push", "--keep-index", "-m", message).
ToArgv()
return self.cmd.New(cmdArgs).Run()
}
2022-04-14 21:45:55 +02:00
func (self *StashCommands) StashUnstagedChanges(message string) error {
if err := self.cmd.New(
NewGitCmd("commit").
Arg("--no-verify", "-m", "[lazygit] stashing unstaged changes").
ToArgv(),
).Run(); err != nil {
2022-04-14 21:45:55 +02:00
return err
}
if err := self.Push(message); err != nil {
2022-04-14 21:45:55 +02:00
return err
}
if err := self.cmd.New(
NewGitCmd("reset").Arg("--soft", "HEAD^").ToArgv(),
).Run(); err != nil {
2022-04-14 21:45:55 +02:00
return err
}
return nil
}
2022-01-02 01:34:33 +02:00
// SaveStagedChanges stashes only the currently staged changes. This takes a few steps
2020-09-29 12:03:39 +02:00
// shoutouts to Joe on https://stackoverflow.com/questions/14759748/stashing-only-staged-changes-in-git-is-it-possible
2022-01-02 01:34:33 +02:00
func (self *StashCommands) SaveStagedChanges(message string) error {
// wrap in 'writing', which uses a mutex
if err := self.cmd.New(
NewGitCmd("stash").Arg("--keep-index").ToArgv(),
).Run(); err != nil {
2020-09-29 12:03:39 +02:00
return err
}
if err := self.Push(message); err != nil {
2020-09-29 12:03:39 +02:00
return err
}
if err := self.cmd.New(
NewGitCmd("stash").Arg("apply", "stash@{1}").ToArgv(),
).Run(); err != nil {
2020-09-29 12:03:39 +02:00
return err
}
if err := self.os.PipeCommands(
self.cmd.New(NewGitCmd("stash").Arg("show", "-p").ToArgv()),
self.cmd.New(NewGitCmd("apply").Arg("-R").ToArgv()),
); err != nil {
2020-09-29 12:03:39 +02:00
return err
}
if err := self.cmd.New(
NewGitCmd("stash").Arg("drop", "stash@{1}").ToArgv(),
).Run(); err != nil {
2020-09-29 12:03:39 +02:00
return err
}
// if you had staged an untracked file, that will now appear as 'AD' in git status
// meaning it's deleted in your working tree but added in your index. Given that it's
// now safely stashed, we need to remove it.
2022-01-02 01:34:33 +02:00
files := self.fileLoader.
GetStatusFiles(GetStatusFileOptions{})
2021-12-30 08:19:01 +02:00
2020-09-29 12:03:39 +02:00
for _, file := range files {
if file.ShortStatus == "AD" {
2022-01-02 01:34:33 +02:00
if err := self.workingTree.UnStageFile(file.Names(), false); err != nil {
2020-09-29 12:03:39 +02:00
return err
}
}
}
return nil
}
2022-10-15 04:15:31 +02:00
func (self *StashCommands) StashIncludeUntrackedChanges(message string) error {
return self.cmd.New(
NewGitCmd("stash").Arg("push", "--include-untracked", "-m", message).
ToArgv(),
).Run()
}
2022-10-15 04:15:31 +02:00
func (self *StashCommands) Rename(index int, message string) error {
2022-10-16 02:11:54 +02:00
sha, err := self.Sha(index)
2022-10-15 04:15:31 +02:00
if err != nil {
return err
}
2022-10-16 02:11:54 +02:00
if err := self.Drop(index); err != nil {
return err
2022-10-15 04:15:31 +02:00
}
2022-10-16 02:11:54 +02:00
err = self.Store(sha, message)
2022-10-15 04:15:31 +02:00
if err != nil {
return err
}
return nil
}