Skip to content

Commit

Permalink
Fix range select -> stage failure when deleted file is already staged (
Browse files Browse the repository at this point in the history
…#3631)

- **PR Description**

Fix range select -> stage failure when deleted file is already staged.

Fixes #3603

- **Please check if the PR fulfills these requirements**

* [ ] Cheatsheets are up-to-date (run `go generate ./...`)
* [x] Code has been formatted (see
[here](https://github.com/jesseduffield/lazygit/blob/master/CONTRIBUTING.md#code-formatting))
* [x] Tests have been added/updated (see
[here](https://github.com/jesseduffield/lazygit/blob/master/pkg/integration/README.md)
for the integration test guide)
* [ ] Text is internationalised (see
[here](https://github.com/jesseduffield/lazygit/blob/master/CONTRIBUTING.md#internationalisation))
* [ ] Docs have been updated if necessary
* [x] You've read through your own file changes for silly mistakes etc

<!--
Be sure to name your PR with an imperative e.g. 'Add worktrees view'
see https://github.com/jesseduffield/lazygit/releases/tag/v0.40.0 for
examples
-->
  • Loading branch information
jesseduffield authored Aug 24, 2024
2 parents 5fb9865 + 387bdb1 commit ca9e006
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 5 deletions.
18 changes: 13 additions & 5 deletions pkg/gui/controllers/files_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -401,16 +401,18 @@ func (self *FilesController) pressWithLock(selectedNodes []*filetree.FileNode) e

selectedNodes = normalisedSelectedNodes(selectedNodes)

// If any node has unstaged changes, we'll stage all the selected nodes. Otherwise,
// we unstage all the selected nodes.
if someNodesHaveUnstagedChanges(selectedNodes) {
// If any node has unstaged changes, we'll stage all the selected unstaged nodes (staging already staged deleted files/folders would fail).
// Otherwise, we unstage all the selected nodes.
unstagedSelectedNodes := filterNodesHaveUnstagedChanges(selectedNodes)

if len(unstagedSelectedNodes) > 0 {
self.c.LogAction(self.c.Tr.Actions.StageFile)

if err := self.optimisticChange(selectedNodes, self.optimisticStage); err != nil {
if err := self.optimisticChange(unstagedSelectedNodes, self.optimisticStage); err != nil {
return err
}

if err := self.c.Git().WorkingTree.StageFiles(toPaths(selectedNodes)); err != nil {
if err := self.c.Git().WorkingTree.StageFiles(toPaths(unstagedSelectedNodes)); err != nil {
return err
}
} else {
Expand Down Expand Up @@ -1031,6 +1033,12 @@ func someNodesHaveStagedChanges(nodes []*filetree.FileNode) bool {
return lo.SomeBy(nodes, (*filetree.FileNode).GetHasStagedChanges)
}

func filterNodesHaveUnstagedChanges(nodes []*filetree.FileNode) []*filetree.FileNode {
return lo.Filter(nodes, func(node *filetree.FileNode, _ int) bool {
return node.GetHasUnstagedChanges()
})
}

func (self *FilesController) canRemove(selectedNodes []*filetree.FileNode) *types.DisabledReason {
submodules := self.c.Model().Submodules
submoduleCount := lo.CountBy(selectedNodes, func(node *filetree.FileNode) bool {
Expand Down
50 changes: 50 additions & 0 deletions pkg/integration/tests/file/stage_deleted_range_select.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package file

import (
"github.com/jesseduffield/lazygit/pkg/config"
. "github.com/jesseduffield/lazygit/pkg/integration/components"
)

var StageDeletedRangeSelect = NewIntegrationTest(NewIntegrationTestArgs{
Description: "Stage a range of deleted files using range select",
ExtraCmdArgs: []string{},
Skip: false,
SetupConfig: func(config *config.AppConfig) {
},
SetupRepo: func(shell *Shell) {
shell.CreateFileAndAdd("file-a", "")
shell.CreateFileAndAdd("file-b", "")
shell.Commit("first commit")

shell.DeleteFile("file-a")
shell.DeleteFile("file-b")
},
Run: func(t *TestDriver, keys config.KeybindingConfig) {
t.Views().Files().
IsFocused().
Lines(
Contains(" D").Contains("file-a").IsSelected(),
Contains(" D").Contains("file-b"),
).
// Stage a single deleted file
PressPrimaryAction().
Lines(
Contains("D ").Contains("file-a").IsSelected(),
Contains(" D").Contains("file-b"),
).
Press(keys.Universal.ToggleRangeSelect).
NavigateToLine(Contains("file-b")).
// Stage both files while a deleted file is already staged
PressPrimaryAction().
Lines(
Contains("D ").Contains("file-a").IsSelected(),
Contains("D ").Contains("file-b").IsSelected(),
).
// Unstage; back to everything being unstaged
PressPrimaryAction().
Lines(
Contains(" D").Contains("file-a").IsSelected(),
Contains(" D").Contains("file-b").IsSelected(),
)
},
})
1 change: 1 addition & 0 deletions pkg/integration/tests/test_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ var tests = []*components.IntegrationTest{
file.RememberCommitMessageAfterFail,
file.RenameSimilarityThresholdChange,
file.StageChildrenRangeSelect,
file.StageDeletedRangeSelect,
file.StageRangeSelect,
filter_and_search.FilterCommitFiles,
filter_and_search.FilterFiles,
Expand Down

0 comments on commit ca9e006

Please sign in to comment.