Add test for missing commits when range-copying after a paste

After a successful paste, the "X commits copied" indicator hides and
DidPaste is set, but the buffer is not cleared. If the user then
range-selects multiple commits and presses shift+C, every Add() call
rebuilds the set via SelectedHashSet(), which returns empty while
DidPaste is true; each iteration of the copy loop therefore overwrites
the previous one and only the last commit in the range survives.
This commit is contained in:
Stefan Haller 2026-05-09 08:07:48 +02:00
parent 1cab15eba8
commit f264d43a1a
2 changed files with 120 additions and 0 deletions

View file

@ -0,0 +1,119 @@
package cherry_pick
import (
"github.com/jesseduffield/lazygit/pkg/config"
. "github.com/jesseduffield/lazygit/pkg/integration/components"
)
var CherryPickRangeAfterPaste = NewIntegrationTest(NewIntegrationTestArgs{
Description: "Regression test: range-copy multiple commits after a previous paste",
ExtraCmdArgs: []string{},
Skip: false,
SetupConfig: func(config *config.AppConfig) {
config.GetUserConfig().Git.LocalBranchSortOrder = "recency"
},
SetupRepo: func(shell *Shell) {
shell.
EmptyCommit("base").
NewBranch("target").
NewBranch("source").
EmptyCommit("one").
EmptyCommit("two").
EmptyCommit("three").
EmptyCommit("four").
EmptyCommit("five").
Checkout("target")
},
Run: func(t *TestDriver, keys config.KeybindingConfig) {
t.Views().Branches().
Focus().
Lines(
Contains("target").IsSelected(),
Contains("source"),
Contains("master"),
).
SelectNextItem().
PressEnter()
t.Views().SubCommits().
IsFocused().
Lines(
Contains("five").IsSelected(),
Contains("four"),
Contains("three"),
Contains("two"),
Contains("one"),
Contains("base"),
).
Press(keys.Commits.CherryPickCopy)
t.Views().Commits().
Focus().
Lines(
Contains("base").IsSelected(),
).
Press(keys.Commits.PasteCommits).
Tap(func() {
t.ExpectPopup().Alert().
Title(Equals("Cherry-pick")).
Content(Equals("Are you sure you want to cherry-pick the 1 copied commit(s) onto this branch?")).
Confirm()
}).
Lines(
Contains("five"),
Contains("base").IsSelected(),
).
Tap(func() {
// After paste, CherryPicking.DidPaste is true, so it looks to the user as if no
// commits are copied:
t.Views().Information().Content(DoesNotContain("commits copied"))
})
t.Views().Branches().
Focus().
NavigateToLine(Contains("source")).
PressEnter()
t.Views().SubCommits().
IsFocused().
NavigateToLine(Contains("four")).
Press(keys.Universal.RangeSelectDown).
Press(keys.Universal.RangeSelectDown).
Press(keys.Commits.CherryPickCopy).
Tap(func() {
/* EXPECTED:
t.Views().Information().Content(Contains("3 commits copied"))
ACTUAL: */
t.Views().Information().Content(Contains("1 commit copied"))
})
t.Views().Commits().
Focus().
NavigateToLine(Contains("base")).
Press(keys.Commits.PasteCommits).
Tap(func() {
t.ExpectPopup().Alert().
Title(Equals("Cherry-pick")).
/* EXPECTED:
Content(Equals("Are you sure you want to cherry-pick the 3 copied commit(s) onto this branch?")).
ACTUAL: */
Content(Equals("Are you sure you want to cherry-pick the 1 copied commit(s) onto this branch?")).
Confirm()
})
/* EXPECTED:
t.Views().Commits().Lines(
Contains("four"),
Contains("three"),
Contains("two"),
Contains("five"),
Contains("base").IsSelected(),
)
ACTUAL: */
t.Views().Commits().Lines(
Contains("two"),
Contains("five"),
Contains("base").IsSelected(),
)
},
})

View file

@ -97,6 +97,7 @@ var tests = []*components.IntegrationTest{
cherry_pick.CherryPickDuringRebase,
cherry_pick.CherryPickMerge,
cherry_pick.CherryPickRange,
cherry_pick.CherryPickRangeAfterPaste,
commit.AddCoAuthor,
commit.AddCoAuthorRange,
commit.AddCoAuthorWhileCommitting,