diff --git a/pkg/gui/controllers/helpers/fixup_helper.go b/pkg/gui/controllers/helpers/fixup_helper.go index 2198d11cb..35c8233b8 100644 --- a/pkg/gui/controllers/helpers/fixup_helper.go +++ b/pkg/gui/controllers/helpers/fixup_helper.go @@ -39,7 +39,7 @@ func (self *FixupHelper) HandleFindBaseCommitForFixupPress() error { return self.c.ErrorMsg(self.c.Tr.NoChangedFiles) } - deletedLineInfos := self.parseDiff(diff) + deletedLineInfos, hasHunksWithOnlyAddedLines := self.parseDiff(diff) if len(deletedLineInfos) == 0 { return self.c.ErrorMsg(self.c.Tr.NoDeletedLinesInDiff) } @@ -79,15 +79,29 @@ func (self *FixupHelper) HandleFindBaseCommitForFixupPress() error { return self.c.ErrorMsg(self.c.Tr.BaseCommitIsAlreadyOnMainBranch) } - if !useIndex { - if err := self.c.Git().WorkingTree.StageAll(); err != nil { - return err + doIt := func() error { + if !hasStagedChanges { + if err := self.c.Git().WorkingTree.StageAll(); err != nil { + return err + } + _ = self.c.Refresh(types.RefreshOptions{Mode: types.SYNC, Scope: []types.RefreshableView{types.FILES}}) } - _ = self.c.Refresh(types.RefreshOptions{Mode: types.SYNC, Scope: []types.RefreshableView{types.FILES}}) + + self.c.Contexts().LocalCommits.SetSelectedLineIdx(index) + return self.c.PushContext(self.c.Contexts().LocalCommits) } - self.c.Contexts().LocalCommits.SetSelectedLineIdx(index) - return self.c.PushContext(self.c.Contexts().LocalCommits) + if hasHunksWithOnlyAddedLines { + return self.c.Confirm(types.ConfirmOpts{ + Title: self.c.Tr.FindBaseCommitForFixup, + Prompt: self.c.Tr.HunksWithOnlyAddedLinesWarning, + HandleConfirm: func() error { + return doIt() + }, + }) + } + + return doIt() } func (self *FixupHelper) getDiff() (string, bool, error) { @@ -106,18 +120,23 @@ func (self *FixupHelper) getDiff() (string, bool, error) { return diff, hasStagedChanges, err } -func (self *FixupHelper) parseDiff(diff string) []*deletedLineInfo { +func (self *FixupHelper) parseDiff(diff string) ([]*deletedLineInfo, bool) { lines := strings.Split(strings.TrimSuffix(diff, "\n"), "\n") deletedLineInfos := []*deletedLineInfo{} + hasHunksWithOnlyAddedLines := false hunkHeaderRegexp := regexp.MustCompile(`@@ -(\d+)(?:,\d+)? \+\d+(?:,\d+)? @@`) var filename string var currentLineInfo *deletedLineInfo finishHunk := func() { - if currentLineInfo != nil && currentLineInfo.numLines > 0 { - deletedLineInfos = append(deletedLineInfos, currentLineInfo) + if currentLineInfo != nil { + if currentLineInfo.numLines > 0 { + deletedLineInfos = append(deletedLineInfos, currentLineInfo) + } else { + hasHunksWithOnlyAddedLines = true + } } } for _, line := range lines { @@ -139,7 +158,7 @@ func (self *FixupHelper) parseDiff(diff string) []*deletedLineInfo { } finishHunk() - return deletedLineInfos + return deletedLineInfos, hasHunksWithOnlyAddedLines } // returns the list of commit hashes that introduced the lines which have now been deleted diff --git a/pkg/i18n/english.go b/pkg/i18n/english.go index e2559f3d2..b645291e7 100644 --- a/pkg/i18n/english.go +++ b/pkg/i18n/english.go @@ -47,6 +47,7 @@ type TranslationSet struct { MultipleBaseCommitsFoundUnstaged string BaseCommitIsAlreadyOnMainBranch string BaseCommitIsNotInCurrentView string + HunksWithOnlyAddedLinesWarning string StatusTitle string GlobalTitle string Menu string @@ -874,6 +875,7 @@ func EnglishTranslationSet() TranslationSet { MultipleBaseCommitsFoundUnstaged: "Multiple base commits found. (Try staging some of the changes)", BaseCommitIsAlreadyOnMainBranch: "The base commit for this change is already on the main branch", BaseCommitIsNotInCurrentView: "Base commit is not in current view", + HunksWithOnlyAddedLinesWarning: "There are ranges of only added lines in the diff; be careful to check that these belong in the found base commit.\n\nProceed?", StatusTitle: "Status", Menu: "Menu", Execute: "Execute", diff --git a/pkg/integration/tests/commit/find_base_commit_for_fixup_warning_for_added_lines.go b/pkg/integration/tests/commit/find_base_commit_for_fixup_warning_for_added_lines.go new file mode 100644 index 000000000..315b757db --- /dev/null +++ b/pkg/integration/tests/commit/find_base_commit_for_fixup_warning_for_added_lines.go @@ -0,0 +1,48 @@ +package commit + +import ( + "github.com/jesseduffield/lazygit/pkg/config" + . "github.com/jesseduffield/lazygit/pkg/integration/components" +) + +var FindBaseCommitForFixupWarningForAddedLines = NewIntegrationTest(NewIntegrationTestArgs{ + Description: "Finds the base commit to create a fixup for, and warns that there are hunks with only added lines", + ExtraCmdArgs: []string{}, + Skip: false, + SetupConfig: func(config *config.AppConfig) {}, + SetupRepo: func(shell *Shell) { + shell.NewBranch("mybranch"). + EmptyCommit("1st commit"). + CreateFileAndAdd("file1", "file1 content\n"). + Commit("2nd commit"). + CreateFileAndAdd("file2", "file2 content\n"). + Commit("3rd commit"). + UpdateFile("file1", "file1 changed content"). + UpdateFile("file2", "file2 content\nadded content") + }, + Run: func(t *TestDriver, keys config.KeybindingConfig) { + t.Views().Commits(). + Lines( + Contains("3rd commit").IsSelected(), + Contains("2nd commit"), + Contains("1st commit"), + ) + + t.Views().Files(). + Focus(). + Press(keys.Files.FindBaseCommitForFixup) + + t.ExpectPopup().Confirmation(). + Title(Equals("Find base commit for fixup")). + Content(Contains("There are ranges of only added lines in the diff; be careful to check that these belong in the found base commit.")). + Confirm() + + t.Views().Commits(). + IsFocused(). + Lines( + Contains("3rd commit"), + Contains("2nd commit").IsSelected(), + Contains("1st commit"), + ) + }, +}) diff --git a/pkg/integration/tests/test_list.go b/pkg/integration/tests/test_list.go index c018d84e7..1b6ab75e9 100644 --- a/pkg/integration/tests/test_list.go +++ b/pkg/integration/tests/test_list.go @@ -71,6 +71,7 @@ var tests = []*components.IntegrationTest{ commit.CreateTag, commit.DiscardOldFileChange, commit.FindBaseCommitForFixup, + commit.FindBaseCommitForFixupWarningForAddedLines, commit.Highlight, commit.History, commit.HistoryComplex,