summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Duffield <jessedduffield@gmail.com>2022-01-17 17:55:44 +1100
committerJesse Duffield <jessedduffield@gmail.com>2022-01-17 19:14:59 +1100
commitee622d044eb6a2964dc2410e7b001234014b8039 (patch)
tree6a603c510528a2cc85fc79f78500f71777e19134
parent99035959a110bd1b7f5e030d02ddf71384aad812 (diff)
add integration test for staging view
-rw-r--r--test/integration/staging/expected/.git_keep/COMMIT_EDITMSG1
-rw-r--r--test/integration/staging/expected/.git_keep/FETCH_HEAD0
-rw-r--r--test/integration/staging/expected/.git_keep/HEAD1
-rw-r--r--test/integration/staging/expected/.git_keep/config10
-rw-r--r--test/integration/staging/expected/.git_keep/description1
-rw-r--r--test/integration/staging/expected/.git_keep/indexbin0 -> 281 bytes
-rw-r--r--test/integration/staging/expected/.git_keep/info/exclude7
-rw-r--r--test/integration/staging/expected/.git_keep/logs/HEAD2
-rw-r--r--test/integration/staging/expected/.git_keep/logs/refs/heads/master2
-rw-r--r--test/integration/staging/expected/.git_keep/objects/05/9586b468b89bf98e3b62126f455ab15bea4a5fbin0 -> 108 bytes
-rw-r--r--test/integration/staging/expected/.git_keep/objects/12/c4186053ecd4056526743060a8fe87429b7306bin0 -> 2331 bytes
-rw-r--r--test/integration/staging/expected/.git_keep/objects/3e/95c983db9349a26b20fccbdaa933e805ff817ebin0 -> 367 bytes
-rw-r--r--test/integration/staging/expected/.git_keep/objects/40/ce5b93f72e04cb876afaaf91398c2821260b95bin0 -> 394 bytes
-rw-r--r--test/integration/staging/expected/.git_keep/objects/42/53d2597aec2a480a8e9054250e6b4aa5b76d9e2
-rw-r--r--test/integration/staging/expected/.git_keep/objects/63/5b45efaba0c2415658bc121de201ec43a479204
-rw-r--r--test/integration/staging/expected/.git_keep/objects/68/06c569c7c063ec7ed3d16da3faa32a1622bb4b2
-rw-r--r--test/integration/staging/expected/.git_keep/objects/79/8369253f104fe8cdc91db6f7d3525be532218ebin0 -> 369 bytes
-rw-r--r--test/integration/staging/expected/.git_keep/objects/a0/425534134de68284a0a7250b83b0e6303f0ed7bin0 -> 2327 bytes
-rw-r--r--test/integration/staging/expected/.git_keep/objects/a4/7182dc057408b3c6b1749cb46db0e0c5fd626bbin0 -> 2328 bytes
-rw-r--r--test/integration/staging/expected/.git_keep/objects/a4/8a7caa799e7859b8f21d373e3f01b06002d42fbin0 -> 476 bytes
-rw-r--r--test/integration/staging/expected/.git_keep/objects/b6/77e3e5777e122a22ebb001532c5017b199b0c02
-rw-r--r--test/integration/staging/expected/.git_keep/objects/dc/02541428fdc15b30bd2174fcbcd43d388eab82bin0 -> 2331 bytes
-rw-r--r--test/integration/staging/expected/.git_keep/objects/e8/aaa2f356eb341c693e239467fd200d0117b4871
-rw-r--r--test/integration/staging/expected/.git_keep/objects/fb/e09a11933b44ea60b46bd0f3d44142cb6189a4bin0 -> 108 bytes
-rw-r--r--test/integration/staging/expected/.git_keep/refs/heads/master1
-rw-r--r--test/integration/staging/expected/one.txt15
-rw-r--r--test/integration/staging/expected/three.txt301
-rw-r--r--test/integration/staging/expected/two.txt33
-rw-r--r--test/integration/staging/files/one.txt15
-rw-r--r--test/integration/staging/files/one_new.txt15
-rw-r--r--test/integration/staging/files/three.txt300
-rw-r--r--test/integration/staging/files/three_new.txt298
-rw-r--r--test/integration/staging/files/two.txt33
-rw-r--r--test/integration/staging/files/two_new.txt33
-rw-r--r--test/integration/staging/recording.json1
-rw-r--r--test/integration/staging/setup.sh18
-rw-r--r--test/integration/staging/test.json4
37 files changed, 1102 insertions, 0 deletions
diff --git a/test/integration/staging/expected/.git_keep/COMMIT_EDITMSG b/test/integration/staging/expected/.git_keep/COMMIT_EDITMSG
new file mode 100644
index 000000000..9daeafb98
--- /dev/null
+++ b/test/integration/staging/expected/.git_keep/COMMIT_EDITMSG
@@ -0,0 +1 @@
+test
diff --git a/test/integration/staging/expected/.git_keep/FETCH_HEAD b/test/integration/staging/expected/.git_keep/FETCH_HEAD
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/test/integration/staging/expected/.git_keep/FETCH_HEAD
diff --git a/test/integration/staging/expected/.git_keep/HEAD b/test/integration/staging/expected/.git_keep/HEAD
new file mode 100644
index 000000000..cb089cd89
--- /dev/null
+++ b/test/integration/staging/expected/.git_keep/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/master
diff --git a/test/integration/staging/expected/.git_keep/config b/test/integration/staging/expected/.git_keep/config
new file mode 100644
index 000000000..8ae104545
--- /dev/null
+++ b/test/integration/staging/expected/.git_keep/config
@@ -0,0 +1,10 @@
+[core]
+ repositoryformatversion = 0
+ filemode = true
+ bare = false
+ logallrefupdates = true
+ ignorecase = true
+ precomposeunicode = true
+[user]
+ email = CI@example.com
+ name = CI
diff --git a/test/integration/staging/expected/.git_keep/description b/test/integration/staging/expected/.git_keep/description
new file mode 100644
index 000000000..498b267a8
--- /dev/null
+++ b/test/integration/staging/expected/.git_keep/description
@@ -0,0 +1 @@
+Unnamed repository; edit this file 'description' to name the repository.
diff --git a/test/integration/staging/expected/.git_keep/index b/test/integration/staging/expected/.git_keep/index
new file mode 100644
index 000000000..cdf1e9ab6
--- /dev/null
+++ b/test/integration/staging/expected/.git_keep/index
Binary files differ
diff --git a/test/integration/staging/expected/.git_keep/info/exclude b/test/integration/staging/expected/.git_keep/info/exclude
new file mode 100644
index 000000000..8e9f2071f
--- /dev/null
+++ b/test/integration/staging/expected/.git_keep/info/exclude
@@ -0,0 +1,7 @@
+# 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]
+# *~
+.DS_Store
diff --git a/test/integration/staging/expected/.git_keep/logs/HEAD b/test/integration/staging/expected/.git_keep/logs/HEAD
new file mode 100644
index 000000000..8ad145985
--- /dev/null
+++ b/test/integration/staging/expected/.git_keep/logs/HEAD
@@ -0,0 +1,2 @@
+0000000000000000000000000000000000000000 6806c569c7c063ec7ed3d16da3faa32a1622bb4b CI <CI@example.com> 1642402468 +1100 commit (initial): file1
+6806c569c7c063ec7ed3d16da3faa32a1622bb4b 4253d2597aec2a480a8e9054250e6b4aa5b76d9e CI <CI@example.com> 1642402495 +1100 commit: test
diff --git a/test/integration/staging/expected/.git_keep/logs/refs/heads/master b/test/integration/staging/expected/.git_keep/logs/refs/heads/master
new file mode 100644
index 000000000..8ad145985
--- /dev/null
+++ b/test/integration/staging/expected/.git_keep/logs/refs/heads/master
@@ -0,0 +1,2 @@
+0000000000000000000000000000000000000000 6806c569c7c063ec7ed3d16da3faa32a1622bb4b CI <CI@example.com> 1642402468 +1100 commit (initial): file1
+6806c569c7c063ec7ed3d16da3faa32a1622bb4b 4253d2597aec2a480a8e9054250e6b4aa5b76d9e CI <CI@example.com> 1642402495 +1100 commit: test
diff --git a/test/integration/staging/expected/.git_keep/objects/05/9586b468b89bf98e3b62126f455ab15bea4a5f b/test/integration/staging/expected/.git_keep/objects/05/9586b468b89bf98e3b62126f455ab15bea4a5f
new file mode 100644
index 000000000..08eb1a0d1
--- /dev/null
+++ b/test/integration/staging/expected/.git_keep/objects/05/9586b468b89bf98e3b62126f455ab15bea4a5f
Binary files differ
diff --git a/test/integration/staging/expected/.git_keep/objects/12/c4186053ecd4056526743060a8fe87429b7306 b/test/integration/staging/expected/.git_keep/objects/12/c4186053ecd4056526743060a8fe87429b7306
new file mode 100644
index 000000000..65f9a5559
--- /dev/null
+++ b/test/integration/staging/expected/.git_keep/objects/12/c4186053ecd4056526743060a8fe87429b7306
Binary files differ
diff --git a/test/integration/staging/expected/.git_keep/objects/3e/95c983db9349a26b20fccbdaa933e805ff817e b/test/integration/staging/expected/.git_keep/objects/3e/95c983db9349a26b20fccbdaa933e805ff817e
new file mode 100644
index 000000000..2da57d308
--- /dev/null
+++ b/test/integration/staging/expected/.git_keep/objects/3e/95c983db9349a26b20fccbdaa933e805ff817e
Binary files differ
diff --git a/test/integration/staging/expected/.git_keep/objects/40/ce5b93f72e04cb876afaaf91398c2821260b95 b/test/integration/staging/expected/.git_keep/objects/40/ce5b93f72e04cb876afaaf91398c2821260b95
new file mode 100644
index 000000000..8c6fa3ec6
--- /dev/null
+++ b/test/integration/staging/expected/.git_keep/objects/40/ce5b93f72e04cb876afaaf91398c2821260b95
Binary files differ
diff --git a/test/integration/staging/expected/.git_keep/objects/42/53d2597aec2a480a8e9054250e6b4aa5b76d9e b/test/integration/staging/expected/.git_keep/objects/42/53d2597aec2a480a8e9054250e6b4aa5b76d9e
new file mode 100644
index 000000000..ed016e977
--- /dev/null
+++ b/test/integration/staging/expected/.git_keep/objects/42/53d2597aec2a480a8e9054250e6b4aa5b76d9e
@@ -0,0 +1,2 @@
+xA
+0@Q9Ed4"BW=L:AR#x|{em-d8]:̘H"%IYjN<xP#c5ꖒP-.aZ8T{(?v87r۞z)kZ1=8gzLun~!9o \ No newline at end of file
diff --git a/test/integration/staging/expected/.git_keep/objects/63/5b45efaba0c2415658bc121de201ec43a47920 b/test/integration/staging/expected/.git_keep/objects/63/5b45efaba0c2415658bc121de201ec43a47920
new file mode 100644
index 000000000..860950f65
--- /dev/null
+++ b/test/integration/staging/expected/.git_keep/objects/63/5b45efaba0c2415658bc121de201ec43a47920
@@ -0,0 +1,4 @@
+xMn0 ;)NtN:dYhK8Yt%y<I()
+E"?x㗇O"GFT:Մ+Y.^km2FËX&Zh" s9hM!acT? ;e%:dĬ-lm< j҆4 Otj%H\B ɝ5^%sD
+~ǩdNpl^e4_VB@]Mm4˽s ;fDi6@jAl7jVZr
+Wiztxpf3I=RGy5rmFv3(vťunpKmIS 2ÑX~s-;Y2pVNF"Kk08 \ No newline at end of file
diff --git a/test/integration/staging/expected/.git_keep/objects/68/06c569c7c063ec7ed3d16da3faa32a1622bb4b b/test/integration/staging/expected/.git_keep/objects/68/06c569c7c063ec7ed3d16da3faa32a1622bb4b
new file mode 100644
index 000000000..ad0ced197
--- /dev/null
+++ b/test/integration/staging/expected/.git_keep/objects/68/06c569c7c063ec7ed3d16da3faa32a1622bb4b
@@ -0,0 +1,2 @@
+xA
+0Fa9I~B"BW=$`!R"x|{^mÌj6N*BȀi䌘Wa(SR8W?h^>/Oj{v+=H"<#Ntavg='n+ \ No newline at end of file
diff --git a/test/integration/staging/expected/.git_keep/objects/79/8369253f104fe8cdc91db6f7d3525be532218e b/test/integration/staging/expected/.git_keep/objects/79/8369253f104fe8cdc91db6f7d3525be532218e
new file mode 100644
index 000000000..f38ecd0b6
--- /dev/null
+++ b/test/integration/staging/expected/.git_keep/objects/79/8369253f104fe8cdc91db6f7d3525be532218e
Binary files differ
diff --git a/test/integration/staging/expected/.git_keep/objects/a0/425534134de68284a0a7250b83b0e6303f0ed7 b/test/integration/staging/expected/.git_keep/objects/a0/425534134de68284a0a7250b83b0e6303f0ed7
new file mode 100644
index 000000000..258d99746
--- /dev/null
+++ b/test/integration/staging/expected/.git_keep/objects/a0/425534134de68284a0a7250b83b0e6303f0ed7
Binary files differ
diff --git a/test/integration/staging/expected/.git_keep/objects/a4/7182dc057408b3c6b1749cb46db0e0c5fd626b b/test/integration/staging/expected/.git_keep/objects/a4/7182dc057408b3c6b1749cb46db0e0c5fd626b
new file mode 100644
index 000000000..49bb3dd6b
--- /dev/null
+++ b/test/integration/staging/expected/.git_keep/objects/a4/7182dc057408b3c6b1749cb46db0e0c5fd626b
Binary files differ
diff --git a/test/integration/staging/expected/.git_keep/objects/a4/8a7caa799e7859b8f21d373e3f01b06002d42f b/test/integration/staging/expected/.git_keep/objects/a4/8a7caa799e7859b8f21d373e3f01b06002d42f
new file mode 100644
index 000000000..428e84de6
--- /dev/null
+++ b/test/integration/staging/expected/.git_keep/objects/a4/8a7caa799e7859b8f21d373e3f01b06002d42f
Binary files differ
diff --git a/test/integration/staging/expected/.git_keep/objects/b6/77e3e5777e122a22ebb001532c5017b199b0c0 b/test/integration/staging/expected/.git_keep/objects/b6/77e3e5777e122a22ebb001532c5017b199b0c0
new file mode 100644
index 000000000..a50f73636
--- /dev/null
+++ b/test/integration/staging/expected/.git_keep/objects/b6/77e3e5777e122a22ebb001532c5017b199b0c0
@@ -0,0 +1,2 @@
+xMn0 ;)NN@L:m 'Dp["O')4EC3<|8J4F&\WBXh07|^r0BQ88XCA=Iu>#>7Y|\OEotD=FƓ&mHDVR+q%)\KǛ#;dHaOB6
+Q» 8h*%KM}Q2"HGkϟ[`:DBUuJO=+4<3Zpo~lFU<WJy߯FMdqn&E۞8|m/)x_ 87עJU (?"#o -΢@ \ No newline at end of file
diff --git a/test/integration/staging/expected/.git_keep/objects/dc/02541428fdc15b30bd2174fcbcd43d388eab82 b/test/integration/staging/expected/.git_keep/objects/dc/02541428fdc15b30bd2174fcbcd43d388eab82
new file mode 100644
index 000000000..232769986
--- /dev/null
+++ b/test/integration/staging/expected/.git_keep/objects/dc/02541428fdc15b30bd2174fcbcd43d388eab82
Binary files differ
diff --git a/test/integration/staging/expected/.git_keep/objects/e8/aaa2f356eb341c693e239467fd200d0117b487 b/test/integration/staging/expected/.git_keep/objects/e8/aaa2f356eb341c693e239467fd200d0117b487
new file mode 100644
index 000000000..f444e5a1e
--- /dev/null
+++ b/test/integration/staging/expected/.git_keep/objects/e8/aaa2f356eb341c693e239467fd200d0117b487
@@ -0,0 +1 @@
+x==0 S/4ީ-*@vllі0gr0'ɓY )/.8I2Mpp_D;⇘F<= oaq6bV =1IV#:w+6#&8{/ _kv(WmJ]z)} ]dαk™Yx*81<ȩp ~TC;k>^%G g ffPˆKΰ%x1\hhgD Ljۈdϟ[`:H YkKWEKtQqmaCRn~?QnR kmtqνs+|"x_!fvؓVůe'ڟwA/Z4!oZZ- b \ No newline at end of file
diff --git a/test/integration/staging/expected/.git_keep/objects/fb/e09a11933b44ea60b46bd0f3d44142cb6189a4 b/test/integration/staging/expected/.git_keep/objects/fb/e09a11933b44ea60b46bd0f3d44142cb6189a4
new file mode 100644
index 000000000..3d85419a6
--- /dev/null
+++ b/test/integration/staging/expected/.git_keep/objects/fb/e09a11933b44ea60b46bd0f3d44142cb6189a4
Binary files differ
diff --git a/test/integration/staging/expected/.git_keep/refs/heads/master b/test/integration/staging/expected/.git_keep/refs/heads/master
new file mode 100644
index 000000000..c94180bef
--- /dev/null
+++ b/test/integration/staging/expected/.git_keep/refs/heads/master
@@ -0,0 +1 @@
+4253d2597aec2a480a8e9054250e6b4aa5b76d9e
diff --git a/test/integration/staging/expected/one.txt b/test/integration/staging/expected/one.txt
new file mode 100644
index 000000000..3a54c9212
--- /dev/null
+++ b/test/integration/staging/expected/one.txt
@@ -0,0 +1,15 @@
+Out there, we've walked quite friendly up to Death, --
+Sat down and eaten with him, cool and bland, --
+Pardoned his spilling mess-tins in our hand.
+We've sniffed the green thick smell of his breath, --
+Our eyes wept, but our courage did not writhe.
+He's spat at us with bullets and he's coughed
+Shrapnel. We sang when he sang aloft,
+We whistled while he shaved us with his scythe.
+
+Oh, Death was never enemy of ours!
+We laughed at him, we leagued with him, old chum.
+No soldier's paid to kick against His powers.
+We laughed, — knowing that greater men would come,
+And greater wars: when each proud fighter brags
+He wars on Death, for lives; not men, for flags
diff --git a/test/integration/staging/expected/three.txt b/test/integration/staging/expected/three.txt
new file mode 100644
index 000000000..2a6e8cb28
--- /dev/null
+++ b/test/integration/staging/expected/three.txt
@@ -0,0 +1,301 @@
+package gui
+
+import (
+ "fmt"
+ "regexp"
+ "strings"
+
+ "github.com/jesseduffield/lazygit/pkg/commands/git_commands"
+ "github.com/jesseduffield/lazygit/pkg/commands/loaders"
+ "github.com/jesseduffield/lazygit/pkg/commands/models"
+ "github.com/jesseduffield/lazygit/pkg/config"
+ "github.com/jesseduffield/lazygit/pkg/gui/filetree"
+ "github.com/jesseduffield/lazygit/pkg/utils"
+)
+
+// list panel functions
+
+func (gui *Gui) getSelectednodeNode() *nodetree.nodeNode {
+ selectedLine := gui.State.Panels.nodes.SelectedLineIdx
+ if selectedLine == -1 {
+ return nil
+ }
+
+ return gui.State.FileManager.GetItemAtIndex(selectedLine)
+ return gui.State.nodeManager.GetItemAtIndex(selectedLine)
+}
+
+func (gui *Gui) getSelectednode() *models.node {
+ node := gui.getSelectednodeNode()
+ if node == nil {
+ return nil
+ }
+ return node.node
+}
+
+func (gui *Gui) getSelectedPath() string {
+ node := gui.getSelectednodeNode()
+ if node == nil {
+ return ""
+ }
+
+ return node.GetPath()
+}
+
+func (gui *Gui) filesRenderToMain() error {
+ node := gui.getSelectedFileNode()
+func (gui *Gui) nodesRenderToMain() error {
+ node := gui.getSelectednodeNode()
+
+ if node == nil {
+ return gui.refreshMainViews(refreshMainOpts{
+ main: &viewUpdateOpts{
+ title: "",
+ task: NewRenderStringTask(gui.Tr.NoChangednodes),
+ },
+ })
+ }
+
+ if node.node != nil && node.File.HasInlineMergeConflicts {
+ return gui.renderConflictsFromFilesPanel()
+ }
+
+ cmdObj := gui.Git.WorkingTree.WorktreeFileDiffCmdObj(node, false, !node.GetHasUnstagedChanges() && node.GetHasStagedChanges(), gui.State.IgnoreWhitespaceInDiffView)
+
+ refreshOpts := refreshMainOpts{main: &viewUpdateOpts{
+ title: gui.Tr.UnstagedChanges,
+ task: NewRunPtyTask(cmdObj.GetCmd()),
+ }}
+
+ if node.GetHasUnstagedChanges() {
+ if node.GetHasStagedChanges() {
+ cmdObj := gui.Git.WorkingTree.WorktreeFileDiffCmdObj(node, false, true, gui.State.IgnoreWhitespaceInDiffView)
+
+ refreshOpts.secondary = &viewUpdateOpts{
+ title: gui.Tr.StagedChanges,
+ task: NewRunPtyTask(cmdObj.GetCmd()),
+ }
+ }
+ } else {
+ refreshOpts.main.title = gui.Tr.StagedChanges
+ }
+
+ return gui.refreshMainViews(refreshOpts)
+}
+
+func (gui *Gui) refreshFilesAndSubmodules() error {
+ gui.Mutexes.RefreshingFilesMutex.Lock()
+ gui.State.IsRefreshingFiles = true
+ defer func() {
+ gui.State.IsRefreshingFiles = false
+ gui.Mutexes.RefreshingFilesMutex.Unlock()
+ }()
+
+ selectedPath := gui.getSelectedPath()
+
+ if err := gui.refreshStateSubmoduleConfigs(); err != nil {
+ return err
+ }
+ if err := gui.refreshStateFiles(); err != nil {
+ return err
+ }
+
+ gui.OnUIThread(func() error {
+ if err := gui.postRefreshUpdate(gui.State.Contexts.Submodules); err != nil {
+ gui.Log.Error(err)
+ }
+
+ if ContextKey(gui.Views.Files.Context) == FILES_CONTEXT_KEY {
+ // doing this a little custom (as opposed to using gui.postRefreshUpdate) because we handle selecting the file explicitly below
+ if err := gui.State.Contexts.Files.HandleRender(); err != nil {
+ return err
+ }
+ }
+
+ if gui.currentContext().GetKey() == FILES_CONTEXT_KEY || (gui.g.CurrentView() == gui.Views.Main && ContextKey(gui.g.CurrentView().Context) == MAIN_MERGING_CONTEXT_KEY) {
+ newSelectedPath := gui.getSelectedPath()
+ alreadySelected := selectedPath != "" && newSelectedPath == selectedPath
+ if !alreadySelected {
+ gui.takeOverMergeConflictScrolling()
+ }
+
+ gui.Views.Files.FocusPoint(0, gui.State.Panels.Files.SelectedLineIdx)
+ return gui.filesRenderToMain()
+ }
+
+ return nil
+ })
+
+ return nil
+}
+
+// specific functions
+
+func (gui *Gui) stagedFiles() []*models.File {
+ files := gui.State.FileManager.GetAllFiles()
+ result := make([]*models.File, 0)
+ for _, file := range files {
+ if file.HasStagedChanges {
+ result = append(result, file)
+ }
+ }
+ return result
+}
+
+func (gui *Gui) trackedFiles() []*models.File {
+ files := gui.State.FileManager.GetAllFiles()
+ result := make([]*models.File, 0, len(files))
+ for _, file := range files {
+ if file.Tracked {
+ result = append(result, file)
+ }
+ }
+ return result
+}
+
+func (gui *Gui) stageSelectedFile() error {
+ file := gui.getSelectedFile()
+ if file == nil {
+ return nil
+ }
+
+ return gui.Git.WorkingTree.StageFile(file.Name)
+}
+
+func (gui *Gui) handleEnterFile() error {
+ return gui.enterFile(OnFocusOpts{ClickedViewName: "", ClickedViewLineIdx: -1})
+}
+
+func (gui *Gui) enterFile(opts OnFocusOpts) error {
+ node := gui.getSelectedFileNode()
+ if node == nil {
+ return nil
+ }
+
+ if node.File == nil {
+ return gui.handleToggleDirCollapsed()
+ }
+
+ file := node.File
+
+ submoduleConfigs := gui.State.Submodules
+ if file.IsSubmodule(submoduleConfigs) {
+ submoduleConfig := file.SubmoduleConfig(submoduleConfigs)
+ return gui.enterSubmodule(submoduleConfig)
+ }
+
+ if file.HasInlineMergeConflicts {
+ return gui.switchToMerge()
+ }
+ if file.HasMergeConflicts {
+ return gui.createErrorPanel(gui.Tr.FileStagingRequirements)
+ }
+
+ return gui.pushContext(gui.State.Contexts.Staging, opts)
+}
+
+func (gui *Gui) handleFilePress() error {
+ node := gui.getSelectedFileNode()
+ if node == nil {
+ return nil
+ }
+
+ if node.IsLeaf() {
+ file := node.File
+
+ if file.HasInlineMergeConflicts {
+ return gui.switchToMerge()
+ }
+
+ if node.HasUnstagedChanges {
+ gui.logAction(gui.Tr.Actions.Stagenode)
+ if err := gui.Git.WorkingTree.Stagenode(node.Name); err != nil {
+ return gui.surfaceError(err)
+ }
+ } else {
+ gui.logAction(gui.Tr.Actions.Unstagenode)
+ if err := gui.Git.WorkingTree.UnStagenode(node.Names(), node.Tracked); err != nil {
+ return gui.surfaceError(err)
+ }
+ }
+ } else {
+ if node.GetHasInlineMergeConflicts() {
+ return gui.createErrorPanel(gui.Tr.ErrStageDirWithInlineMergeConflicts)
+ }
+
+ if node.GetHasUnstagedChanges() {
+ gui.logAction(gui.Tr.Actions.Stagenode)
+ if err := gui.Git.WorkingTree.Stagenode(node.Path); err != nil {
+ return gui.surfaceError(err)
+ }
+ } else {
+ // pretty sure it doesn't matter that we're always passing true here
+ gui.logAction(gui.Tr.Actions.Unstagenode)
+ if err := gui.Git.WorkingTree.UnStagenode([]string{node.Path}, true); err != nil {
+ return gui.surfaceError(err)
+ }
+ }
+ }
+
+ if err := gui.blah(refreshOptions{scope: []RefreshableView{nodeS}}); err != nil {
+ return err
+ }
+
+ return gui.State.Contexts.nodes.HandleFocus()
+}
+
+func (gui *Gui) allnodesStaged() bool {
+ for _, node := range gui.State.nodeManager.GetAllnodes() {
+ if node.HasUnstagedChanges {
+ return false
+ }
+ }
+ return true
+}
+
+func (gui *Gui) onFocusnode() error {
+ gui.takeOverMergeConflictScrolling()
+ return nil
+}
+
+func (gui *Gui) handleStageAll() error {
+ var err error
+ if gui.allnodesStaged() {
+ gui.logAction(gui.Tr.Actions.UnstageAllnodes)
+ err = gui.Git.WorkingTree.UnstageAll()
+ } else {
+ gui.logAction(gui.Tr.Actions.StageAllnodes)
+ err = gui.Git.WorkingTree.StageAll()
+ }
+ if err != nil {
+ _ = gui.surfaceError(err)
+ }
+
+ if err := gui.blah(refreshOptions{scope: []RefreshableView{nodeS}}); err != nil {
+ return err
+ }
+
+ return gui.State.Contexts.nodes.HandleFocus()
+}
+
+func (gui *Gui) handleIgnorenode() error {
+ node := gui.getSelectednodeNode()
+ if node == nil {
+ return nil
+ }
+
+ if node.GetPath() == ".gitignore" {
+ return gui.createErrorPanel("Cannot ignore .gitignore")
+ }
+
+ unstagenodes := func() error {
+ return node.ForEachnode(func(node *models.node) error {
+ if node.HasStagedChanges {
+ if err := gui.Git.WorkingTree.UnStagenode(node.Names(), node.Tracked); err != nil {
+ return err
+ }
+ }
+
+ return nil
+ })
+ }
diff --git a/test/integration/staging/expected/two.txt b/test/integration/staging/expected/two.txt
new file mode 100644
index 000000000..b4ebbd4f1
--- /dev/null
+++ b/test/integration/staging/expected/two.txt
@@ -0,0 +1,33 @@
+type createMenuOptions struct {
+ showCancel bool
+}
+
+func (gui *Gui) createMenu(title string, items []*menuItem, createMenuOptions createMenuOptions) error {
+ if createMenuOptions.showCancel {
+ // this is mutative but I'm okay with that for now
+ items = app(items, &menuItem{
+ d: []string{gui.Tr.LcCancel},
+ onPress: func() error {
+ return nil
+ },
+ })
+ }
+
+ gui.State.MenuItems = items
+
+ stringArrays := make([][]string, len(items))
+ for i, items := range items {
+ if items.opensMenu && item.displayStrings != nil {
+ return errors.New("Message for the developer of this app: you've set opensMenu with displaystrings on the menu panel. Bad developer!. Apologies, user")
+ }
+
+ if item.displayStrings == nil {
+ styledStr := item.displayString
+ if item.opensMenu {
+ styledStr = opensMenuStyle(styledStr)
+ }
+ stringArrays[i] = []string{styledStr}
+ } else {
+ stringArrays[i] = item.displayStrings
+ }
+ }
diff --git a/test/integration/staging/files/one.txt b/test/integration/staging/files/one.txt
new file mode 100644
index 000000000..e8aaa2f35
--- /dev/null
+++ b/test/integration/staging/files/one.txt
@@ -0,0 +1,15 @@
+Out there, we've walked quite friendly up to Death, --
+Sat down and eaten with him, cool and bland, --
+Pardoned his spilling mess-tins in our hand.
+We've sniffed the green thick odour of his breath, --
+Our eyes wept, but our courage didn't writhe.
+He's spat at us with bullets and he's coughed
+Shrapnel. We chorused when he sang aloft,
+We whistled while he shaved us with his scythe.
+
+Oh, Death was never enemy of ours!
+We laughed at him, we leagued with him, old chum.
+No soldier's paid to kick against His powers.
+We laughed, — knowing that better men would come,
+And greater wars: when each proud fighter brags
+He wars on Death, for lives; not men, for flags
diff --git a/test/integration/staging/files/one_new.txt b/test/integration/staging/files/one_new.txt
new file mode 100644
index 000000000..3a54c9212
--- /dev/null
+++ b/test/integration/staging/files/one_new.txt
@@ -0,0 +1,15 @@
+Out there, we've walked quite friendly up to Death, --
+Sat down and eaten with him, cool and bland, --
+Pardoned his spilling mess-tins in our hand.
+We've sniffed the green thick smell of his breath, --
+Our eyes wept, but our courage did not writhe.
+He's spat at us with bullets and he's coughed
+Shrapnel. We sang when he sang aloft,
+We whistled while he shaved us with his scythe.
+
+Oh, Death was never enemy of ours!
+We laughed at him, we leagued with him, old chum.
+No soldier's paid to kick against His powers.
+We laughed, — knowing that greater men would come,
+And greater wars: when each proud fighter brags
+He wars on Death, for lives; not men, for flags
diff --git a/test/integration/staging/files/three.txt b/test/integration/staging/files/three.txt
new file mode 100644
index 000000000..a04255341
--- /dev/null
+++ b/test/integration/staging/files/three.txt
@@ -0,0 +1,300 @@
+package gui
+
+import (
+ "fmt"
+ "regexp"
+ "strings"
+
+ "github.com/jesseduffield/lazygit/pkg/commands/git_commands"
+ "github.com/jesseduffield/lazygit/pkg/commands/loaders"
+ "github.com/jesseduffield/lazygit/pkg/commands/models"
+ "github.com/jesseduffield/lazygit/pkg/co