mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-06-02 23:27:32 +02:00
Merge pull request #1980 from ajhynes7/stash-untracked-changes
This commit is contained in:
commit
b33ec5a050
@ -123,6 +123,10 @@ func (self *StashCommands) SaveStagedChanges(message string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *StashCommands) StashIncludeUntrackedChanges(message string) error {
|
||||||
|
return self.cmd.New(fmt.Sprintf("git stash save %s --include-untracked", self.cmd.Quote(message))).Run()
|
||||||
|
}
|
||||||
|
|
||||||
func (self *StashCommands) Rename(index int, message string) error {
|
func (self *StashCommands) Rename(index int, message string) error {
|
||||||
sha, err := self.Sha(index)
|
sha, err := self.Sha(index)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -758,18 +758,31 @@ func (self *FilesController) createStashMenu() error {
|
|||||||
{
|
{
|
||||||
Label: self.c.Tr.LcStashAllChanges,
|
Label: self.c.Tr.LcStashAllChanges,
|
||||||
OnPress: func() error {
|
OnPress: func() error {
|
||||||
return self.handleStashSave(self.git.Stash.Save, self.c.Tr.Actions.StashAllChanges, self.c.Tr.NoFilesToStash)
|
if !self.helpers.WorkingTree.IsWorkingTreeDirty() {
|
||||||
|
return self.c.ErrorMsg(self.c.Tr.NoFilesToStash)
|
||||||
|
}
|
||||||
|
return self.handleStashSave(self.git.Stash.Save, self.c.Tr.Actions.StashAllChanges)
|
||||||
},
|
},
|
||||||
Key: 'a',
|
Key: 'a',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Label: self.c.Tr.LcStashAllChangesKeepIndex,
|
Label: self.c.Tr.LcStashAllChangesKeepIndex,
|
||||||
OnPress: func() error {
|
OnPress: func() error {
|
||||||
|
if !self.helpers.WorkingTree.IsWorkingTreeDirty() {
|
||||||
|
return self.c.ErrorMsg(self.c.Tr.NoFilesToStash)
|
||||||
|
}
|
||||||
// if there are no staged files it behaves the same as Stash.Save
|
// if there are no staged files it behaves the same as Stash.Save
|
||||||
return self.handleStashSave(self.git.Stash.StashAndKeepIndex, self.c.Tr.Actions.StashAllChangesKeepIndex, self.c.Tr.NoFilesToStash)
|
return self.handleStashSave(self.git.Stash.StashAndKeepIndex, self.c.Tr.Actions.StashAllChangesKeepIndex)
|
||||||
},
|
},
|
||||||
Key: 'i',
|
Key: 'i',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Label: self.c.Tr.LcStashIncludeUntrackedChanges,
|
||||||
|
OnPress: func() error {
|
||||||
|
return self.handleStashSave(self.git.Stash.StashIncludeUntrackedChanges, self.c.Tr.Actions.StashIncludeUntrackedChanges)
|
||||||
|
},
|
||||||
|
Key: 'U',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
Label: self.c.Tr.LcStashStagedChanges,
|
Label: self.c.Tr.LcStashStagedChanges,
|
||||||
OnPress: func() error {
|
OnPress: func() error {
|
||||||
@ -777,18 +790,21 @@ func (self *FilesController) createStashMenu() error {
|
|||||||
if !self.helpers.WorkingTree.AnyStagedFiles() {
|
if !self.helpers.WorkingTree.AnyStagedFiles() {
|
||||||
return self.c.ErrorMsg(self.c.Tr.NoTrackedStagedFilesStash)
|
return self.c.ErrorMsg(self.c.Tr.NoTrackedStagedFilesStash)
|
||||||
}
|
}
|
||||||
return self.handleStashSave(self.git.Stash.SaveStagedChanges, self.c.Tr.Actions.StashStagedChanges, self.c.Tr.NoTrackedStagedFilesStash)
|
return self.handleStashSave(self.git.Stash.SaveStagedChanges, self.c.Tr.Actions.StashStagedChanges)
|
||||||
},
|
},
|
||||||
Key: 's',
|
Key: 's',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Label: self.c.Tr.LcStashUnstagedChanges,
|
Label: self.c.Tr.LcStashUnstagedChanges,
|
||||||
OnPress: func() error {
|
OnPress: func() error {
|
||||||
|
if !self.helpers.WorkingTree.IsWorkingTreeDirty() {
|
||||||
|
return self.c.ErrorMsg(self.c.Tr.NoFilesToStash)
|
||||||
|
}
|
||||||
if self.helpers.WorkingTree.AnyStagedFiles() {
|
if self.helpers.WorkingTree.AnyStagedFiles() {
|
||||||
return self.handleStashSave(self.git.Stash.StashUnstagedChanges, self.c.Tr.Actions.StashUnstagedChanges, self.c.Tr.NoFilesToStash)
|
return self.handleStashSave(self.git.Stash.StashUnstagedChanges, self.c.Tr.Actions.StashUnstagedChanges)
|
||||||
}
|
}
|
||||||
// ordinary stash
|
// ordinary stash
|
||||||
return self.handleStashSave(self.git.Stash.Save, self.c.Tr.Actions.StashUnstagedChanges, self.c.Tr.NoFilesToStash)
|
return self.handleStashSave(self.git.Stash.Save, self.c.Tr.Actions.StashUnstagedChanges)
|
||||||
},
|
},
|
||||||
Key: 'u',
|
Key: 'u',
|
||||||
},
|
},
|
||||||
@ -797,7 +813,7 @@ func (self *FilesController) createStashMenu() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (self *FilesController) stash() error {
|
func (self *FilesController) stash() error {
|
||||||
return self.handleStashSave(self.git.Stash.Save, self.c.Tr.Actions.StashAllChanges, self.c.Tr.NoTrackedStagedFilesStash)
|
return self.handleStashSave(self.git.Stash.Save, self.c.Tr.Actions.StashAllChanges)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *FilesController) createResetToUpstreamMenu() error {
|
func (self *FilesController) createResetToUpstreamMenu() error {
|
||||||
@ -825,11 +841,7 @@ func (self *FilesController) toggleTreeView() error {
|
|||||||
return self.c.PostRefreshUpdate(self.context())
|
return self.c.PostRefreshUpdate(self.context())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *FilesController) handleStashSave(stashFunc func(message string) error, action string, errorMsg string) error {
|
func (self *FilesController) handleStashSave(stashFunc func(message string) error, action string) error {
|
||||||
if !self.helpers.WorkingTree.IsWorkingTreeDirty() {
|
|
||||||
return self.c.ErrorMsg(errorMsg)
|
|
||||||
}
|
|
||||||
|
|
||||||
return self.c.Prompt(types.PromptOpts{
|
return self.c.Prompt(types.PromptOpts{
|
||||||
Title: self.c.Tr.StashChanges,
|
Title: self.c.Tr.StashChanges,
|
||||||
HandleConfirm: func(stashComment string) error {
|
HandleConfirm: func(stashComment string) error {
|
||||||
|
@ -295,6 +295,7 @@ type TranslationSet struct {
|
|||||||
LcStashStagedChanges string
|
LcStashStagedChanges string
|
||||||
LcStashAllChangesKeepIndex string
|
LcStashAllChangesKeepIndex string
|
||||||
LcStashUnstagedChanges string
|
LcStashUnstagedChanges string
|
||||||
|
LcStashIncludeUntrackedChanges string
|
||||||
LcStashOptions string
|
LcStashOptions string
|
||||||
NotARepository string
|
NotARepository string
|
||||||
LcJump string
|
LcJump string
|
||||||
@ -588,6 +589,7 @@ type Actions struct {
|
|||||||
StashAllChangesKeepIndex string
|
StashAllChangesKeepIndex string
|
||||||
StashStagedChanges string
|
StashStagedChanges string
|
||||||
StashUnstagedChanges string
|
StashUnstagedChanges string
|
||||||
|
StashIncludeUntrackedChanges string
|
||||||
GitFlowFinish string
|
GitFlowFinish string
|
||||||
GitFlowStart string
|
GitFlowStart string
|
||||||
CopyToClipboard string
|
CopyToClipboard string
|
||||||
@ -940,6 +942,7 @@ func EnglishTranslationSet() TranslationSet {
|
|||||||
LcStashStagedChanges: "stash staged changes",
|
LcStashStagedChanges: "stash staged changes",
|
||||||
LcStashAllChangesKeepIndex: "stash all changes and keep index",
|
LcStashAllChangesKeepIndex: "stash all changes and keep index",
|
||||||
LcStashUnstagedChanges: "stash unstaged changes",
|
LcStashUnstagedChanges: "stash unstaged changes",
|
||||||
|
LcStashIncludeUntrackedChanges: "stash all changes including untracked files",
|
||||||
LcStashOptions: "Stash options",
|
LcStashOptions: "Stash options",
|
||||||
NotARepository: "Error: must be run inside a git repository",
|
NotARepository: "Error: must be run inside a git repository",
|
||||||
LcJump: "jump to panel",
|
LcJump: "jump to panel",
|
||||||
@ -1216,6 +1219,7 @@ func EnglishTranslationSet() TranslationSet {
|
|||||||
StashAllChangesKeepIndex: "Stash all changes and keep index",
|
StashAllChangesKeepIndex: "Stash all changes and keep index",
|
||||||
StashStagedChanges: "Stash staged changes",
|
StashStagedChanges: "Stash staged changes",
|
||||||
StashUnstagedChanges: "Stash unstaged changes",
|
StashUnstagedChanges: "Stash unstaged changes",
|
||||||
|
StashIncludeUntrackedChanges: "Stash all changes including untracked files",
|
||||||
GitFlowFinish: "Git flow finish",
|
GitFlowFinish: "Git flow finish",
|
||||||
GitFlowStart: "Git Flow start",
|
GitFlowStart: "Git Flow start",
|
||||||
CopyToClipboard: "Copy to clipboard",
|
CopyToClipboard: "Copy to clipboard",
|
||||||
|
@ -84,6 +84,17 @@ func (self *Assert) CommitCount(expectedCount int) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *Assert) StashCount(expectedCount int) {
|
||||||
|
self.assertWithRetries(func() (bool, string) {
|
||||||
|
actualCount := len(self.gui.Model().StashEntries)
|
||||||
|
|
||||||
|
return actualCount == expectedCount, fmt.Sprintf(
|
||||||
|
"Expected %d stash entries, but got %d",
|
||||||
|
expectedCount, actualCount,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func (self *Assert) AtLeastOneCommit() {
|
func (self *Assert) AtLeastOneCommit() {
|
||||||
self.assertWithRetries(func() (bool, string) {
|
self.assertWithRetries(func() (bool, string) {
|
||||||
actualCount := len(self.gui.Model().Commits)
|
actualCount := len(self.gui.Model().Commits)
|
||||||
|
34
pkg/integration/tests/stash/stash.go
Normal file
34
pkg/integration/tests/stash/stash.go
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
package stash
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/jesseduffield/lazygit/pkg/config"
|
||||||
|
. "github.com/jesseduffield/lazygit/pkg/integration/components"
|
||||||
|
)
|
||||||
|
|
||||||
|
var Stash = NewIntegrationTest(NewIntegrationTestArgs{
|
||||||
|
Description: "Stashing files",
|
||||||
|
ExtraCmdArgs: "",
|
||||||
|
Skip: false,
|
||||||
|
SetupConfig: func(config *config.AppConfig) {},
|
||||||
|
SetupRepo: func(shell *Shell) {
|
||||||
|
shell.EmptyCommit("initial commit")
|
||||||
|
shell.CreateFile("file", "content")
|
||||||
|
shell.GitAddAll()
|
||||||
|
},
|
||||||
|
Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) {
|
||||||
|
assert.StashCount(0)
|
||||||
|
assert.WorkingTreeFileCount(1)
|
||||||
|
|
||||||
|
input.PressKeys(keys.Files.ViewStashOptions)
|
||||||
|
assert.InMenu()
|
||||||
|
|
||||||
|
input.PressKeys("a")
|
||||||
|
assert.InPrompt()
|
||||||
|
assert.MatchCurrentViewTitle(Equals("Stash changes"))
|
||||||
|
|
||||||
|
input.Type("my stashed file")
|
||||||
|
input.Confirm()
|
||||||
|
assert.StashCount(1)
|
||||||
|
assert.WorkingTreeFileCount(0)
|
||||||
|
},
|
||||||
|
})
|
@ -0,0 +1,35 @@
|
|||||||
|
package stash
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/jesseduffield/lazygit/pkg/config"
|
||||||
|
. "github.com/jesseduffield/lazygit/pkg/integration/components"
|
||||||
|
)
|
||||||
|
|
||||||
|
var StashIncludingUntrackedFiles = NewIntegrationTest(NewIntegrationTestArgs{
|
||||||
|
Description: "Stashing all files including untracked ones",
|
||||||
|
ExtraCmdArgs: "",
|
||||||
|
Skip: false,
|
||||||
|
SetupConfig: func(config *config.AppConfig) {},
|
||||||
|
SetupRepo: func(shell *Shell) {
|
||||||
|
shell.EmptyCommit("initial commit")
|
||||||
|
shell.CreateFile("file_1", "content")
|
||||||
|
shell.CreateFile("file_2", "content")
|
||||||
|
shell.GitAdd("file_1")
|
||||||
|
},
|
||||||
|
Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) {
|
||||||
|
assert.StashCount(0)
|
||||||
|
assert.WorkingTreeFileCount(2)
|
||||||
|
|
||||||
|
input.PressKeys(keys.Files.ViewStashOptions)
|
||||||
|
assert.InMenu()
|
||||||
|
|
||||||
|
input.PressKeys("U")
|
||||||
|
assert.InPrompt()
|
||||||
|
assert.MatchCurrentViewTitle(Equals("Stash changes"))
|
||||||
|
|
||||||
|
input.Type("my stashed file")
|
||||||
|
input.Confirm()
|
||||||
|
assert.StashCount(1)
|
||||||
|
assert.WorkingTreeFileCount(0)
|
||||||
|
},
|
||||||
|
})
|
@ -24,24 +24,26 @@ import (
|
|||||||
// be sure to add it to this list.
|
// be sure to add it to this list.
|
||||||
|
|
||||||
var tests = []*components.IntegrationTest{
|
var tests = []*components.IntegrationTest{
|
||||||
commit.Commit,
|
bisect.Basic,
|
||||||
commit.NewBranch,
|
bisect.FromOtherBranch,
|
||||||
branch.Suggestions,
|
|
||||||
branch.Delete,
|
branch.Delete,
|
||||||
branch.Rebase,
|
branch.Rebase,
|
||||||
branch.RebaseAndDrop,
|
branch.RebaseAndDrop,
|
||||||
interactive_rebase.One,
|
branch.Suggestions,
|
||||||
interactive_rebase.AmendMerge,
|
|
||||||
custom_commands.Basic,
|
|
||||||
custom_commands.MultiplePrompts,
|
|
||||||
custom_commands.MenuFromCommand,
|
|
||||||
bisect.Basic,
|
|
||||||
bisect.FromOtherBranch,
|
|
||||||
cherry_pick.CherryPick,
|
cherry_pick.CherryPick,
|
||||||
cherry_pick.CherryPickConflicts,
|
cherry_pick.CherryPickConflicts,
|
||||||
|
commit.Commit,
|
||||||
|
commit.NewBranch,
|
||||||
|
custom_commands.Basic,
|
||||||
custom_commands.FormPrompts,
|
custom_commands.FormPrompts,
|
||||||
stash.Rename,
|
custom_commands.MenuFromCommand,
|
||||||
|
custom_commands.MultiplePrompts,
|
||||||
file.DirWithUntrackedFile,
|
file.DirWithUntrackedFile,
|
||||||
|
interactive_rebase.AmendMerge,
|
||||||
|
interactive_rebase.One,
|
||||||
|
stash.Rename,
|
||||||
|
stash.Stash,
|
||||||
|
stash.StashIncludingUntrackedFiles,
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetTests() []*components.IntegrationTest {
|
func GetTests() []*components.IntegrationTest {
|
||||||
|
@ -0,0 +1 @@
|
|||||||
|
initial commit
|
@ -0,0 +1 @@
|
|||||||
|
ref: refs/heads/master
|
@ -0,0 +1 @@
|
|||||||
|
e6ed7d5c2198fa4791de9c66e8000da607eaf9a3
|
@ -0,0 +1,12 @@
|
|||||||
|
[core]
|
||||||
|
repositoryformatversion = 0
|
||||||
|
filemode = true
|
||||||
|
bare = false
|
||||||
|
logallrefupdates = true
|
||||||
|
ignorecase = true
|
||||||
|
precomposeunicode = true
|
||||||
|
[user]
|
||||||
|
email = CI@example.com
|
||||||
|
name = CI
|
||||||
|
[commit]
|
||||||
|
gpgSign = false
|
@ -0,0 +1 @@
|
|||||||
|
Unnamed repository; edit this file 'description' to name the repository.
|
BIN
test/integration_new/stash/stash/expected/repo/.git_keep/index
Normal file
BIN
test/integration_new/stash/stash/expected/repo/.git_keep/index
Normal file
Binary file not shown.
@ -0,0 +1,6 @@
|
|||||||
|
# git ls-files --others --exclude-from=.git/info/exclude
|
||||||
|
# Lines that start with '#' are comments.
|
||||||
|
# For a project mostly in C, the following would be a good set of
|
||||||
|
# exclude patterns (uncomment them if you want to use them):
|
||||||
|
# *.[oa]
|
||||||
|
# *~
|
@ -0,0 +1,2 @@
|
|||||||
|
0000000000000000000000000000000000000000 e6ed7d5c2198fa4791de9c66e8000da607eaf9a3 CI <CI@example.com> 1668288675 -0330 commit (initial): initial commit
|
||||||
|
e6ed7d5c2198fa4791de9c66e8000da607eaf9a3 e6ed7d5c2198fa4791de9c66e8000da607eaf9a3 CI <CI@example.com> 1668288676 -0330 reset: moving to HEAD
|
@ -0,0 +1 @@
|
|||||||
|
0000000000000000000000000000000000000000 e6ed7d5c2198fa4791de9c66e8000da607eaf9a3 CI <CI@example.com> 1668288675 -0330 commit (initial): initial commit
|
@ -0,0 +1 @@
|
|||||||
|
0000000000000000000000000000000000000000 c86eeda485a49ca608cb2617bb027be66cd92bc3 CI <CI@example.com> 1668288676 -0330 On master: my stashed file
|
Binary file not shown.
Binary file not shown.
@ -0,0 +1 @@
|
|||||||
|
x�ŽAjÃ0E³Ö)æ cÉI¥”@V>ÆX3"Ë®9~¥ûl?ÿ=^ÞZ«¬¥SßUAÒ Hƒ³drN¬/)àœrö£ Îa,sôX̃w];(©ñÙ)Ã�kÊDQ˜0(—ÄÎð³ß·n|ߦ«¾¸=½äýÀ@mŒÎèšc=¢º~x7u}Á¶Bã߃úú¯‚ºÖ^y�?¡yN»FY
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1 @@
|
|||||||
|
e6ed7d5c2198fa4791de9c66e8000da607eaf9a3
|
@ -0,0 +1 @@
|
|||||||
|
c86eeda485a49ca608cb2617bb027be66cd92bc3
|
@ -0,0 +1 @@
|
|||||||
|
initial commit
|
@ -0,0 +1 @@
|
|||||||
|
ref: refs/heads/master
|
@ -0,0 +1 @@
|
|||||||
|
364ac39500dfec09956626a513736d7602b4d64a
|
@ -0,0 +1,12 @@
|
|||||||
|
[core]
|
||||||
|
repositoryformatversion = 0
|
||||||
|
filemode = true
|
||||||
|
bare = false
|
||||||
|
logallrefupdates = true
|
||||||
|
ignorecase = true
|
||||||
|
precomposeunicode = true
|
||||||
|
[user]
|
||||||
|
email = CI@example.com
|
||||||
|
name = CI
|
||||||
|
[commit]
|
||||||
|
gpgSign = false
|
@ -0,0 +1 @@
|
|||||||
|
Unnamed repository; edit this file 'description' to name the repository.
|
Binary file not shown.
@ -0,0 +1,6 @@
|
|||||||
|
# git ls-files --others --exclude-from=.git/info/exclude
|
||||||
|
# Lines that start with '#' are comments.
|
||||||
|
# For a project mostly in C, the following would be a good set of
|
||||||
|
# exclude patterns (uncomment them if you want to use them):
|
||||||
|
# *.[oa]
|
||||||
|
# *~
|
@ -0,0 +1,2 @@
|
|||||||
|
0000000000000000000000000000000000000000 364ac39500dfec09956626a513736d7602b4d64a CI <CI@example.com> 1668288767 -0330 commit (initial): initial commit
|
||||||
|
364ac39500dfec09956626a513736d7602b4d64a 364ac39500dfec09956626a513736d7602b4d64a CI <CI@example.com> 1668288768 -0330 reset: moving to HEAD
|
@ -0,0 +1 @@
|
|||||||
|
0000000000000000000000000000000000000000 364ac39500dfec09956626a513736d7602b4d64a CI <CI@example.com> 1668288767 -0330 commit (initial): initial commit
|
@ -0,0 +1 @@
|
|||||||
|
0000000000000000000000000000000000000000 03892119fb6b807d1c13c23f6baacdc4a170e694 CI <CI@example.com> 1668288768 -0330 On master: my stashed file
|
@ -0,0 +1 @@
|
|||||||
|
xŤĎ=jA†áÔ{Šą@‚ć_2!\ąĘF# <^ăÝ@rűLă>íÇó__Ǹě.ľěU'˘Ĺűž�%KK>W&˛ÂěŞöFË˝=ô6Ă’ZʔĴQ.%”–}¬±H-8É4OŹâSíť$uK ľ†Č4C&4Ž5TC~z0lćYEI™Q4‡ěkK\s0ÖâŇľ÷óúpÇ“{?ž>ő§ŤűUßú:>ś/b-č^!FXć:OďúOľ|ÝÜhŰô7~ݶ·í¬âěrŐ?“Ý].
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1 @@
|
|||||||
|
364ac39500dfec09956626a513736d7602b4d64a
|
@ -0,0 +1 @@
|
|||||||
|
03892119fb6b807d1c13c23f6baacdc4a170e694
|
Loading…
x
Reference in New Issue
Block a user