From f8fa6ee1a4ee9c00fa9cd32111313dffc7143605 Mon Sep 17 00:00:00 2001 From: Stefan Haller Date: Mon, 5 Oct 2026 13:44:31 +0200 Subject: [PATCH] Add a test for emptying a pane before its diff's task is created If the lower pane of the main view is asked to show a diff and is then emptied before the next layout, it ends up holding the diff. Selecting a file with staged changes and moving back to one without any in rapid succession does this. The pane is hidden then, but when it is shown again, it shows the other file's diff until its next render replaces it. Emptying a pane clears the view right away, but leaves the view's tasks alone. So the diff's task, which is only created after the layout, fills the pane again. A task that is still reading a diff into the pane isn't stopped either, so it can write into the emptied view. Co-Authored-By: Claude Opus 5.5 (1M context) --- .../main_view/keep_an_emptied_pane_empty.go | 46 +++++++++++++++++++ pkg/integration/tests/test_list.go | 1 + 2 files changed, 47 insertions(+) create mode 100644 pkg/integration/tests/main_view/keep_an_emptied_pane_empty.go diff --git a/pkg/integration/tests/main_view/keep_an_emptied_pane_empty.go b/pkg/integration/tests/main_view/keep_an_emptied_pane_empty.go new file mode 100644 index 000000000..75e4800f2 --- /dev/null +++ b/pkg/integration/tests/main_view/keep_an_emptied_pane_empty.go @@ -0,0 +1,46 @@ +package main_view + +import ( + "github.com/jesseduffield/lazygit/pkg/config" + . "github.com/jesseduffield/lazygit/pkg/integration/components" +) + +// Both selection changes are handled before the next layout. Selecting file_a asks +// for its staged changes in the lower pane, whose task is only created after the +// layout. Selecting file_b again leaves that pane with nothing to show, and empties it +// right away. The pane is hidden then, but when it is shown again, it shows what it +// holds until its next render replaces it. +var KeepAnEmptiedPaneEmpty = NewIntegrationTest(NewIntegrationTestArgs{ + Description: "Selecting a file and moving back off it in rapid succession leaves the pane that the file filled empty", + ExtraCmdArgs: []string{}, + Skip: false, + SetupConfig: func(config *config.AppConfig) {}, + SetupRepo: func(shell *Shell) { + shell.CreateFileAndAdd("file_a", "one\n") + shell.CreateFileAndAdd("file_b", "one\n") + shell.Commit("one") + + shell.UpdateFileAndAdd("file_a", "STAGED\n") + shell.UpdateFile("file_a", "UNSTAGED\n") + shell.UpdateFile("file_b", "two\n") + }, + Run: func(t *TestDriver, keys config.KeybindingConfig) { + t.Views().Files(). + IsFocused(). + NavigateToLine(Contains("file_b")) + + t.Views().Secondary(). + IsInvisible() + + t.Views().Files(). + PressRapidly(keys.Universal.PrevItem, keys.Universal.NextItem). + SelectedLine(Contains("file_b")) + + t.Views().Secondary(). + IsInvisible(). + /* EXPECTED: + Content(Equals("")) + ACTUAL: */ + Content(Contains("+STAGED")) + }, +}) diff --git a/pkg/integration/tests/test_list.go b/pkg/integration/tests/test_list.go index f836f944e..7a5c728ba 100644 --- a/pkg/integration/tests/test_list.go +++ b/pkg/integration/tests/test_list.go @@ -410,6 +410,7 @@ var tests = []*components.IntegrationTest{ main_view.JumpToAFileOfTheDiff, main_view.JumpToAFileOnlyOverADiff, main_view.KeepAWrappedLineCoveredAcrossARerender, + main_view.KeepAnEmptiedPaneEmpty, main_view.KeepBothHalvesOfAChangeSelected, main_view.KeepPositionByTheVisibleEndOfASelection, main_view.KeepPositionInBothPanesWhenChangingContextSize,