diff --git a/pkg/integration/tests/interactive_rebase/lock_error_partway_through_rebase.go b/pkg/integration/tests/interactive_rebase/lock_error_partway_through_rebase.go new file mode 100644 index 000000000..0d0b9cf92 --- /dev/null +++ b/pkg/integration/tests/interactive_rebase/lock_error_partway_through_rebase.go @@ -0,0 +1,59 @@ +package interactive_rebase + +import ( + "github.com/jesseduffield/lazygit/pkg/config" + . "github.com/jesseduffield/lazygit/pkg/integration/components" + "github.com/jesseduffield/lazygit/pkg/integration/tests/shared" +) + +var LockErrorPartwayThroughRebase = NewIntegrationTest(NewIntegrationTestArgs{ + Description: "Drops a commit while another git process takes index.lock partway through the rebase", + ExtraCmdArgs: []string{}, + Skip: false, + SetupConfig: func(config *config.AppConfig) {}, + SetupRepo: func(shell *Shell) { + shell.CreateNCommits(4) + // The rebase makes a commit when it picks commit-03; the lock then + // stops it when it tries to pick commit-04. + shared.HoldIndexLockAfterNextCommit(shell) + }, + Run: func(t *TestDriver, keys config.KeybindingConfig) { + t.Views().Commits(). + Focus(). + Lines( + Contains("commit-04").IsSelected(), + Contains("commit-03"), + Contains("commit-02"), + Contains("commit-01"), + ). + NavigateToLine(Contains("commit-02")). + Press(keys.Universal.Remove). + Tap(func() { + t.ExpectPopup().Confirmation(). + Title(Equals("Drop commit")). + Content(Contains("Are you sure you want to drop the selected commit(s)?")). + Confirm() + }). + /* EXPECTED: + IsFocused(). + Lines( + Contains("commit-04"), + Contains("commit-03"), + Contains("commit-01"), + ) + ACTUAL: */ + Tap(func() { + t.ExpectPopup().Alert(). + Title(Equals("Error")). + Content(Contains("It seems that there is already a rebase-merge directory")). + Confirm() + }). + Lines( + Contains("─── Pending rebase todos"), + Contains("pick").Contains("commit-04"), + Contains("─── Commits"), + Contains("commit-03"), + Contains("commit-01"), + ) + }, +}) diff --git a/pkg/integration/tests/shared/index_lock.go b/pkg/integration/tests/shared/index_lock.go new file mode 100644 index 000000000..29e513f6f --- /dev/null +++ b/pkg/integration/tests/shared/index_lock.go @@ -0,0 +1,32 @@ +package shared + +import ( + . "github.com/jesseduffield/lazygit/pkg/integration/components" +) + +// holdIndexLockScript is the part of a git hook that takes index.lock the +// first time the hook runs, and holds it until the git command that ran the +// hook has exited. This simulates another git process (for example an IDE +// running "git status" in the background) that takes the lock while a command +// of several steps, such as a rebase, is partway through. +const holdIndexLockScript = `if [ ! -e .git/index-lock-taken ]; then + touch .git/index-lock-taken .git/index.lock + ( + # If lazygit runs the command in a pty (as it does for a pull), we + # get SIGHUP when the command exits + trap '' HUP + while kill -0 $PPID 2>/dev/null; do sleep 0.01; done + rm -f .git/index.lock + ) >/dev/null 2>&1