diff --git a/pkg/commands/git_commands/rebase.go b/pkg/commands/git_commands/rebase.go index 0c79e92b7..50ab4de7a 100644 --- a/pkg/commands/git_commands/rebase.go +++ b/pkg/commands/git_commands/rebase.go @@ -198,12 +198,12 @@ func (self *RebaseCommands) BuildSingleActionTodo(commits []*models.Commit, acti } // AmendTo amends the given commit with whatever files are staged -func (self *RebaseCommands) AmendTo(sha string) error { - if err := self.commit.CreateFixupCommit(sha); err != nil { +func (self *RebaseCommands) AmendTo(commit *models.Commit) error { + if err := self.commit.CreateFixupCommit(commit.Sha); err != nil { return err } - return self.SquashAllAboveFixupCommits(sha) + return self.SquashAllAboveFixupCommits(commit) } // EditRebaseTodo sets the action at a given index in the git-rebase-todo file @@ -258,12 +258,17 @@ func (self *RebaseCommands) MoveTodoDown(index int) error { } // SquashAllAboveFixupCommits squashes all fixup! commits above the given one -func (self *RebaseCommands) SquashAllAboveFixupCommits(sha string) error { +func (self *RebaseCommands) SquashAllAboveFixupCommits(commit *models.Commit) error { + shaOrRoot := commit.Sha + "^" + if commit.IsFirstCommit() { + shaOrRoot = "--root" + } + return self.runSkipEditorCommand( self.cmd.New( fmt.Sprintf( - "git rebase --interactive --rebase-merges --autostash --autosquash %s^", - sha, + "git rebase --interactive --rebase-merges --autostash --autosquash %s", + shaOrRoot, ), ), ) diff --git a/pkg/gui/controllers/local_commits_controller.go b/pkg/gui/controllers/local_commits_controller.go index 42920bf81..0cee212d1 100644 --- a/pkg/gui/controllers/local_commits_controller.go +++ b/pkg/gui/controllers/local_commits_controller.go @@ -428,7 +428,7 @@ func (self *LocalCommitsController) amendTo(commit *models.Commit) error { HandleConfirm: func() error { return self.c.WithWaitingStatus(self.c.Tr.AmendingStatus, func() error { self.c.LogAction(self.c.Tr.Actions.AmendCommit) - err := self.git.Rebase.AmendTo(commit.Sha) + err := self.git.Rebase.AmendTo(commit) return self.helpers.MergeAndRebase.CheckMergeOrRebase(err) }) }, @@ -571,7 +571,7 @@ func (self *LocalCommitsController) squashAllAboveFixupCommits(commit *models.Co HandleConfirm: func() error { return self.c.WithWaitingStatus(self.c.Tr.SquashingStatus, func() error { self.c.LogAction(self.c.Tr.Actions.SquashAllAboveFixupCommits) - err := self.git.Rebase.SquashAllAboveFixupCommits(commit.Sha) + err := self.git.Rebase.SquashAllAboveFixupCommits(commit) return self.helpers.MergeAndRebase.CheckMergeOrRebase(err) }) }, diff --git a/pkg/integration/tests/interactive_rebase/amend_first_commit.go b/pkg/integration/tests/interactive_rebase/amend_first_commit.go new file mode 100644 index 000000000..d03a880b9 --- /dev/null +++ b/pkg/integration/tests/interactive_rebase/amend_first_commit.go @@ -0,0 +1,41 @@ +package interactive_rebase + +import ( + "github.com/jesseduffield/lazygit/pkg/config" + . "github.com/jesseduffield/lazygit/pkg/integration/components" +) + +var AmendFirstCommit = NewIntegrationTest(NewIntegrationTestArgs{ + Description: "Amends a staged file to the first (initial) commit.", + ExtraCmdArgs: "", + Skip: false, + SetupConfig: func(config *config.AppConfig) {}, + SetupRepo: func(shell *Shell) { + shell. + CreateNCommits(2). + CreateFileAndAdd("fixup-file", "fixup content") + }, + Run: func(t *TestDriver, keys config.KeybindingConfig) { + t.Views().Commits(). + Focus(). + Lines( + Contains("commit 02"), + Contains("commit 01"), + ). + NavigateToListItem(Contains("commit 01")). + Press(keys.Commits.AmendToCommit). + Tap(func() { + t.ExpectPopup().Confirmation(). + Title(Equals("Amend Commit")). + Content(Contains("Are you sure you want to amend this commit with your staged files?")). + Confirm() + }). + Lines( + Contains("commit 02"), + Contains("commit 01").IsSelected(), + ) + + t.Views().Main(). + Content(Contains("fixup content")) + }, +}) diff --git a/pkg/integration/tests/interactive_rebase/squash_fixups_above_first_commit.go b/pkg/integration/tests/interactive_rebase/squash_fixups_above_first_commit.go new file mode 100644 index 000000000..ece1e5fae --- /dev/null +++ b/pkg/integration/tests/interactive_rebase/squash_fixups_above_first_commit.go @@ -0,0 +1,49 @@ +package interactive_rebase + +import ( + "github.com/jesseduffield/lazygit/pkg/config" + . "github.com/jesseduffield/lazygit/pkg/integration/components" +) + +var SquashFixupsAboveFirstCommit = NewIntegrationTest(NewIntegrationTestArgs{ + Description: "Squashes all fixups above the first (initial) commit.", + ExtraCmdArgs: "", + Skip: false, + SetupConfig: func(config *config.AppConfig) {}, + SetupRepo: func(shell *Shell) { + shell. + CreateNCommits(2). + CreateFileAndAdd("fixup-file", "fixup content") + }, + Run: func(t *TestDriver, keys config.KeybindingConfig) { + t.Views().Commits(). + Focus(). + Lines( + Contains("commit 02"), + Contains("commit 01"), + ). + NavigateToListItem(Contains("commit 01")). + Press(keys.Commits.CreateFixupCommit). + Tap(func() { + t.ExpectPopup().Confirmation(). + Title(Equals("Create fixup commit")). + Content(Contains("Are you sure you want to create a fixup! commit for commit")). + Confirm() + }). + NavigateToListItem(Contains("commit 01")). + Press(keys.Commits.SquashAboveCommits). + Tap(func() { + t.ExpectPopup().Confirmation(). + Title(Equals("Squash all 'fixup!' commits above selected commit (autosquash)")). + Content(Contains("Are you sure you want to squash all fixup! commits above")). + Confirm() + }). + Lines( + Contains("commit 02"), + Contains("commit 01").IsSelected(), + ) + + t.Views().Main(). + Content(Contains("fixup content")) + }, +}) diff --git a/pkg/integration/tests/tests_gen.go b/pkg/integration/tests/tests_gen.go index 0e1b3b01c..3bef44c7e 100644 --- a/pkg/integration/tests/tests_gen.go +++ b/pkg/integration/tests/tests_gen.go @@ -65,6 +65,7 @@ var tests = []*components.IntegrationTest{ filter_by_path.CliArg, filter_by_path.SelectFile, filter_by_path.TypeFile, + interactive_rebase.AmendFirstCommit, interactive_rebase.AmendMerge, interactive_rebase.EditFirstCommit, interactive_rebase.FixupFirstCommit, @@ -73,6 +74,7 @@ var tests = []*components.IntegrationTest{ interactive_rebase.RewordFirstCommit, interactive_rebase.SquashDownFirstCommit, interactive_rebase.SquashDownSecondCommit, + interactive_rebase.SquashFixupsAboveFirstCommit, misc.ConfirmOnQuit, misc.InitialOpen, patch_building.CopyPatchToClipboard,