Fix checking out a file from a range selection of commits (#4423)

- **PR Description**

When selecting a range of commits by selecting the top one and then
pressing shift-down to create a range, and then pressing enter and
checking out one of the files by pressing `c`, you would get the file
checked out with its state at the bottom end of the range, which is not
what you want; it is expected to check out the file at the state that
the diff shows it changes to. (And if the file was only created in the
middle of that range, trying to check it out would result in an error.)
Fix this by paying attention to a "from-to" range selection, and
checking out the file at the "to" state.

Related to #4420.
This commit is contained in:
Stefan Haller 2025-03-25 09:58:34 +01:00 committed by GitHub
commit 200e490398
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 115 additions and 1 deletions

View file

@ -292,7 +292,8 @@ func (self *CommitFilesController) openCopyMenu() error {
func (self *CommitFilesController) checkout(node *filetree.CommitFileNode) error {
self.c.LogAction(self.c.Tr.Actions.CheckoutFile)
if err := self.c.Git().WorkingTree.CheckoutFile(self.context().GetRef().RefName(), node.GetPath()); err != nil {
_, to := self.context().GetFromAndToForDiff()
if err := self.c.Git().WorkingTree.CheckoutFile(to, node.GetPath()); err != nil {
return err
}

View file

@ -0,0 +1,55 @@
package commit
import (
"github.com/jesseduffield/lazygit/pkg/config"
. "github.com/jesseduffield/lazygit/pkg/integration/components"
)
var CheckoutFileFromCommit = NewIntegrationTest(NewIntegrationTestArgs{
Description: "Checkout a file from a commit",
ExtraCmdArgs: []string{},
Skip: false,
SetupConfig: func(config *config.AppConfig) {},
SetupRepo: func(shell *Shell) {
shell.CreateFileAndAdd("file.txt", "one\n")
shell.Commit("one")
shell.CreateFileAndAdd("file.txt", "two\n")
shell.Commit("two")
shell.CreateFileAndAdd("file.txt", "three\n")
shell.Commit("three")
shell.CreateFileAndAdd("file.txt", "four\n")
shell.Commit("four")
},
Run: func(t *TestDriver, keys config.KeybindingConfig) {
t.Views().Commits().
Focus().
Lines(
Contains("four").IsSelected(),
Contains("three"),
Contains("two"),
Contains("one"),
).
NavigateToLine(Contains("three")).
Tap(func() {
t.Views().Main().ContainsLines(
Contains("-two"),
Contains("+three"),
)
}).
PressEnter()
t.Views().CommitFiles().
IsFocused().
Lines(
Equals("M file.txt"),
).
Press(keys.CommitFiles.CheckoutCommitFile)
t.Views().Files().
Lines(
Equals("M file.txt"),
)
t.FileSystem().FileContent("file.txt", Equals("three\n"))
},
})

View file

@ -0,0 +1,56 @@
package commit
import (
"github.com/jesseduffield/lazygit/pkg/config"
. "github.com/jesseduffield/lazygit/pkg/integration/components"
)
var CheckoutFileFromRangeSelectionOfCommits = NewIntegrationTest(NewIntegrationTestArgs{
Description: "Checkout a file from a range selection of commits",
ExtraCmdArgs: []string{},
Skip: false,
SetupConfig: func(config *config.AppConfig) {},
SetupRepo: func(shell *Shell) {
shell.CreateFileAndAdd("file.txt", "one\n")
shell.Commit("one")
shell.CreateFileAndAdd("file.txt", "two\n")
shell.Commit("two")
shell.CreateFileAndAdd("file.txt", "three\n")
shell.Commit("three")
shell.CreateFileAndAdd("file.txt", "four\n")
shell.Commit("four")
},
Run: func(t *TestDriver, keys config.KeybindingConfig) {
t.Views().Commits().
Focus().
Lines(
Contains("four").IsSelected(),
Contains("three"),
Contains("two"),
Contains("one"),
).
NavigateToLine(Contains("three")).
Press(keys.Universal.RangeSelectDown).
Tap(func() {
t.Views().Main().ContainsLines(
Contains("-one"),
Contains("+three"),
)
}).
PressEnter()
t.Views().CommitFiles().
IsFocused().
Lines(
Equals("M file.txt"),
).
Press(keys.CommitFiles.CheckoutCommitFile)
t.Views().Files().
Lines(
Equals("M file.txt"),
)
t.FileSystem().FileContent("file.txt", Equals("three\n"))
},
})

View file

@ -89,6 +89,8 @@ var tests = []*components.IntegrationTest{
commit.AmendWhenThereAreConflictsAndContinue,
commit.AutoWrapMessage,
commit.Checkout,
commit.CheckoutFileFromCommit,
commit.CheckoutFileFromRangeSelectionOfCommits,
commit.Commit,
commit.CommitMultiline,
commit.CommitSkipHooks,