Move index-operation edge cases onto the focused diff

Patch movement still needs coverage for partial modifications, adjacent
additions, custom diff settings, and selections spanning files after the
patch-building panel goes away. Drive each through diff-line identities
while keeping the resulting commit and index assertions unchanged.

Co-Authored-By: GitHub Copilot <copilot@github.com>
This commit is contained in:
Stefan Haller
2026-10-05 11:44:42 +02:00
co-authored by GitHub Copilot
parent b75a5930a9
commit 5ab45d93d1
6 changed files with 129 additions and 156 deletions
@@ -1,15 +1,17 @@
package patch_building
package main_view
import (
"github.com/jesseduffield/lazygit/pkg/config"
. "github.com/jesseduffield/lazygit/pkg/integration/components"
)
var MoveRangeToIndex = NewIntegrationTest(NewIntegrationTestArgs{
Description: "Apply a custom patch",
var MoveMultiFileRangeToIndex = NewIntegrationTest(NewIntegrationTestArgs{
Description: "Move a multi-file range from a commit to the index",
ExtraCmdArgs: []string{},
Skip: false,
SetupConfig: func(config *config.AppConfig) {},
SetupConfig: func(config *config.AppConfig) {
config.GetUserConfig().Gui.UseHunkModeInStagingView = false
},
SetupRepo: func(shell *Shell) {
shell.CreateFileAndAdd("file1", "first line\n")
shell.Commit("first commit")
@@ -36,24 +38,22 @@ var MoveRangeToIndex = NewIntegrationTest(NewIntegrationTestArgs{
Equals(" A file2"),
Equals(" A file3"),
).
SelectNextItem().
Press(keys.Universal.FocusMainView)
t.Views().Main().
IsFocused().
SelectedLines(Contains("+second line")).
Press(keys.Universal.ToggleRangeSelect).
NavigateToLine(Contains("file2")).
NavigateToLine(Contains("+file two content")).
PressPrimaryAction()
t.Views().Information().Content(Contains("Building patch"))
t.Views().Secondary().Content(Contains("second line"))
t.Views().Secondary().Content(Contains("file two content"))
t.Views().Secondary().
Content(Contains("second line")).
Content(Contains("file two content"))
t.Common().SelectPatchOption(MatchesRegexp(`Move patch out into index$`))
t.Views().CommitFiles().
IsFocused().
Lines(
Contains("file3").IsSelected(),
).PressEscape()
t.Views().Files().
Focus().
Lines(
@@ -61,13 +61,8 @@ var MoveRangeToIndex = NewIntegrationTest(NewIntegrationTestArgs{
Equals(" M file1"),
Equals(" A file2"),
)
t.Views().Secondary().
Content(Contains("second line"))
t.Views().Files().Focus().NavigateToLine(Contains("file2"))
t.Views().Secondary().
Content(Contains("file two content"))
t.Views().Secondary().Content(Contains("second line"))
t.Views().Files().NavigateToLine(Contains("file2"))
t.Views().Secondary().Content(Contains("file two content"))
},
})
@@ -1,15 +1,17 @@
package patch_building
package main_view
import (
"github.com/jesseduffield/lazygit/pkg/config"
. "github.com/jesseduffield/lazygit/pkg/integration/components"
)
var MoveToIndexPartOfAdjacentAddedLines = NewIntegrationTest(NewIntegrationTestArgs{
Description: "Move a patch from a commit to the index, with only some lines of a range of adjacent added lines in the patch",
var MovePartOfAdjacentAddedLinesToIndex = NewIntegrationTest(NewIntegrationTestArgs{
Description: "Move only one of two adjacent added lines from a commit to the index",
ExtraCmdArgs: []string{},
Skip: false,
SetupConfig: func(config *config.AppConfig) {},
SetupConfig: func(config *config.AppConfig) {
config.GetUserConfig().Gui.UseHunkModeInStagingView = false
},
SetupRepo: func(shell *Shell) {
shell.CreateFileAndAdd("file1", "")
shell.Commit("first commit")
@@ -36,34 +38,24 @@ var MoveToIndexPartOfAdjacentAddedLines = NewIntegrationTest(NewIntegrationTestA
Lines(
Contains("file1").IsSelected(),
).
PressEnter()
Press(keys.Universal.FocusMainView)
t.Views().PatchBuilding().
t.Views().Main().
IsFocused().
SelectedLines(Contains("+1st line")).
PressPrimaryAction()
t.Views().Information().Content(Contains("Building patch"))
t.Common().SelectPatchOption(Contains("Move patch out into index"))
t.Views().CommitFiles().
t.Views().Main().
IsFocused().
Lines(
Contains("file1").IsSelected(),
).
Tap(func() {
t.Views().Main().
Content(Contains("+2nd line").
DoesNotContain("1st line"))
})
Content(Contains("+2nd line").DoesNotContain("1st line"))
t.Views().Files().
Focus().
ContainsLines(
Contains("M").Contains("file1"),
)
t.Views().Secondary().
Content(Contains("+1st line\n 2nd line"))
t.Views().Secondary().Content(Contains("+1st line\n 2nd line"))
},
})
@@ -0,0 +1,84 @@
package main_view
import (
"github.com/jesseduffield/lazygit/pkg/config"
. "github.com/jesseduffield/lazygit/pkg/integration/components"
)
var MovePartialPatchToIndex = NewIntegrationTest(NewIntegrationTestArgs{
Description: "Move part of a file's changes from a commit to the index",
ExtraCmdArgs: []string{},
Skip: false,
SetupConfig: func(config *config.AppConfig) {
config.GetUserConfig().Gui.UseHunkModeInStagingView = false
},
SetupRepo: func(shell *Shell) {
shell.CreateFileAndAdd("file1", "first line\nsecond line\nthird line\n")
shell.Commit("first commit")
shell.UpdateFileAndAdd("file1", "first line2\nsecond line\nthird line2\n")
shell.Commit("second commit")
shell.CreateFileAndAdd("file2", "file1 content")
shell.Commit("third commit")
},
Run: func(t *TestDriver, keys config.KeybindingConfig) {
t.Views().Commits().
Focus().
Lines(
Contains("third commit").IsSelected(),
Contains("second commit"),
Contains("first commit"),
).
NavigateToLine(Contains("second commit")).
PressEnter()
t.Views().CommitFiles().
IsFocused().
Lines(
Contains("file1").IsSelected(),
).
Press(keys.Universal.FocusMainView)
t.Views().Main().
IsFocused().
SelectedLines(Contains(`-first line`)).
Press(keys.Universal.ToggleRangeSelect).
Press(keys.Universal.NextItem).
SelectedLines(
Contains(`-first line`),
Contains(`+first line2`),
).
PressPrimaryAction()
t.Views().Information().Content(Contains("Building patch"))
t.Views().Secondary().ContainsLines(
Contains(`-first line`),
Contains(`+first line2`),
Contains(` second line`),
Contains(` third line`),
)
t.Common().SelectPatchOption(Contains("Move patch out into index"))
t.Views().Files().Lines(
Contains("M").Contains("file1"),
)
t.Views().Main().
IsFocused().
ContainsLines(
Contains(` first line`),
Contains(` second line`),
Contains(`-third line`),
Contains(`+third line2`),
)
t.Views().Files().Focus()
t.Views().Secondary().ContainsLines(
Contains(`-first line`),
Contains(`+first line2`),
Contains(` second line`),
Contains(` third line2`),
)
},
})
@@ -1,11 +1,11 @@
package patch_building
package main_view
import (
"github.com/jesseduffield/lazygit/pkg/config"
. "github.com/jesseduffield/lazygit/pkg/integration/components"
)
var MoveToIndexWorksEvenIfNoprefixIsSet = NewIntegrationTest(NewIntegrationTestArgs{
var MovePatchToIndexWithCustomDiffConfig = NewIntegrationTest(NewIntegrationTestArgs{
Description: "Moving a patch to the index works even if diff.noprefix or diff.external are set",
ExtraCmdArgs: []string{},
Skip: false,
@@ -14,7 +14,6 @@ var MoveToIndexWorksEvenIfNoprefixIsSet = NewIntegrationTest(NewIntegrationTestA
shell.CreateFileAndAdd("file1", "file1 content\n")
shell.Commit("first commit")
// Test that this works even if custom diff options are set
shell.SetConfig("diff.noprefix", "true")
shell.SetConfig("diff.external", "echo")
},
@@ -31,20 +30,19 @@ var MoveToIndexWorksEvenIfNoprefixIsSet = NewIntegrationTest(NewIntegrationTestA
Lines(
Contains("file1").IsSelected(),
).
Press(keys.Universal.FocusMainView)
t.Views().Main().
IsFocused().
SelectedLines(Contains("+file1 content")).
PressPrimaryAction()
t.Views().Secondary().Content(Contains("+file1 content"))
t.Common().SelectPatchOption(Contains("Move patch out into index"))
t.Views().CommitFiles().IsFocused().
Lines(
Equals("(none)"),
)
t.Views().Files().
Lines(
Contains("A").Contains("file1"),
)
t.Views().CommitFiles().Lines(Equals("(none)"))
t.Views().Files().Lines(
Contains("A").Contains("file1"),
)
},
})
@@ -1,96 +0,0 @@
package patch_building
import (
"github.com/jesseduffield/lazygit/pkg/config"
. "github.com/jesseduffield/lazygit/pkg/integration/components"
)
var MoveToIndexPartial = NewIntegrationTest(NewIntegrationTestArgs{
Description: "Move a patch from a commit to the index. This is different from the MoveToIndex test in that we're only selecting a partial patch from a file",
ExtraCmdArgs: []string{},
Skip: false,
SetupConfig: func(config *config.AppConfig) {},
SetupRepo: func(shell *Shell) {
shell.CreateFileAndAdd("file1", "first line\nsecond line\nthird line\n")
shell.Commit("first commit")
shell.UpdateFileAndAdd("file1", "first line2\nsecond line\nthird line2\n")
shell.Commit("second commit")
shell.CreateFileAndAdd("file2", "file1 content")
shell.Commit("third commit")
},
Run: func(t *TestDriver, keys config.KeybindingConfig) {
t.Views().Commits().
Focus().
Lines(
Contains("third commit").IsSelected(),
Contains("second commit"),
Contains("first commit"),
).
NavigateToLine(Contains("second commit")).
PressEnter()
t.Views().CommitFiles().
IsFocused().
Lines(
Contains("file1").IsSelected(),
).
PressEnter()
t.Views().PatchBuilding().
IsFocused().
ContainsLines(
Contains(`-first line`).IsSelected(),
Contains(`+first line2`),
Contains(` second line`),
Contains(`-third line`),
Contains(`+third line2`),
).
PressPrimaryAction().
Tap(func() {
t.Views().Information().Content(Contains("Building patch"))
t.Views().Secondary().
ContainsLines(
Contains(`-first line`),
Contains(`+first line2`),
Contains(` second line`),
Contains(` third line`),
)
t.Common().SelectPatchOption(Contains("Move patch out into index"))
t.Views().Files().
Lines(
Contains("M").Contains("file1"),
)
})
// Focus is automatically returned to the commit files panel. Arguably it shouldn't be.
t.Views().CommitFiles().
IsFocused().
Lines(
Contains("file1"),
)
t.Views().Main().
ContainsLines(
Contains(` first line`),
Contains(` second line`),
Contains(`-third line`),
Contains(`+third line2`),
)
t.Views().Files().
Focus()
t.Views().Secondary().
ContainsLines(
Contains(`-first line`),
Contains(`+first line2`),
Contains(` second line`),
Contains(` third line2`),
)
},
})
+4 -4
View File
@@ -409,8 +409,12 @@ var tests = []*components.IntegrationTest{
main_view.KeepSelectedRangeWhenChangingContextSize,
main_view.KeepSelectionAfterMovingPatchOut,
main_view.KeepSelectionVisibleWhenDiffShrinks,
main_view.MoveMultiFileRangeToIndex,
main_view.MoveOnWhenThePatchMarksRewrapTheDiff,
main_view.MovePartOfAdjacentAddedLinesToIndex,
main_view.MovePartialPatchToIndex,
main_view.MovePatchToIndex,
main_view.MovePatchToIndexWithCustomDiffConfig,
main_view.NavigateByHunkAndFile,
main_view.NoSelectionOverABinaryDiff,
main_view.NoSelectionOverACommitLog,
@@ -475,15 +479,11 @@ var tests = []*components.IntegrationTest{
patch_building.CopyRenamedFileDiff,
patch_building.DiscardLinesFromCommit,
patch_building.EditLineInPatchBuildingPanel,
patch_building.MoveRangeToIndex,
patch_building.MoveToEarlierCommit,
patch_building.MoveToEarlierCommitFromAddedFile,
patch_building.MoveToIndexFromAddedFileWithConflict,
patch_building.MoveToIndexPartOfAdjacentAddedLines,
patch_building.MoveToIndexPartial,
patch_building.MoveToIndexWithConflict,
patch_building.MoveToIndexWithModifiedFile,
patch_building.MoveToIndexWorksEvenIfNoprefixIsSet,
patch_building.MoveToLaterCommit,
patch_building.MoveToLaterCommitPartialHunk,
patch_building.MoveToNewCommit,