Skip to content

Commit b22149d

Browse files
committed
Create fixup commit at end of its branch when there's a stack of branches
1 parent 396215a commit b22149d

File tree

4 files changed

+119
-0
lines changed

4 files changed

+119
-0
lines changed

pkg/commands/git_commands/rebase.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,19 @@ func (self *RebaseCommands) AmendTo(commits []*models.Commit, commitIndex int) e
309309
}).Run()
310310
}
311311

312+
func (self *RebaseCommands) MoveFixupCommitDown(commits []*models.Commit, targetCommitIndex int) error {
313+
fixupHash, err := self.getHashOfLastCommitMade()
314+
if err != nil {
315+
return err
316+
}
317+
318+
return self.PrepareInteractiveRebaseCommand(PrepareInteractiveRebaseCommandOpts{
319+
baseHashOrRoot: getBaseHashOrRoot(commits, targetCommitIndex+1),
320+
overrideEditor: true,
321+
instruction: daemon.NewMoveFixupCommitDownInstruction(commits[targetCommitIndex].Hash, fixupHash, false),
322+
}).Run()
323+
}
324+
312325
func todoFromCommit(commit *models.Commit) utils.Todo {
313326
if commit.Action == todo.UpdateRef {
314327
return utils.Todo{Ref: commit.Name, Action: commit.Action}

pkg/gui/controllers/local_commits_controller.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -895,6 +895,10 @@ func (self *LocalCommitsController) createFixupCommit(commit *models.Commit) err
895895
return err
896896
}
897897

898+
if err := self.moveFixupCommitToOwnerStackedBranch(commit); err != nil {
899+
return err
900+
}
901+
898902
self.context().MoveSelectedLine(1)
899903
return self.c.Refresh(types.RefreshOptions{Mode: types.SYNC})
900904
})
@@ -924,6 +928,50 @@ func (self *LocalCommitsController) createFixupCommit(commit *models.Commit) err
924928
})
925929
}
926930

931+
func (self *LocalCommitsController) moveFixupCommitToOwnerStackedBranch(targetCommit *models.Commit) error {
932+
if self.c.Git().Version.IsOlderThan(2, 38, 0) {
933+
// Git 2.38.0 introduced the `rebase.updateRefs` config option. Don't
934+
// move the commit down with older versions, as it would break the stack.
935+
return nil
936+
}
937+
938+
if self.c.Git().Status.WorkingTreeState() != enums.REBASE_MODE_NONE {
939+
// Can't move commits while rebasing
940+
return nil
941+
}
942+
943+
if targetCommit.Status == models.StatusMerged {
944+
// Target commit is already on main. It's a bit questionable that we
945+
// allow creating a fixup commit for it in the first place, but we
946+
// always did, so why restrict that now; however, it doesn't make sense
947+
// to move the created fixup commit down in that case.
948+
return nil
949+
}
950+
951+
if !self.c.Git().Config.GetRebaseUpdateRefs() {
952+
// If the user has disabled rebase.updateRefs, we don't move the fixup
953+
// because this would break the stack of branches (presumably they like
954+
// to manage it themselves manually, or something).
955+
return nil
956+
}
957+
958+
headOfOwnerBranchIdx := -1
959+
for i := self.context().GetSelectedLineIdx(); i > 0; i-- {
960+
if lo.SomeBy(self.c.Model().Branches, func(b *models.Branch) bool {
961+
return b.CommitHash == self.c.Model().Commits[i].Hash
962+
}) {
963+
headOfOwnerBranchIdx = i
964+
break
965+
}
966+
}
967+
968+
if headOfOwnerBranchIdx == -1 {
969+
return nil
970+
}
971+
972+
return self.c.Git().Rebase.MoveFixupCommitDown(self.c.Model().Commits, headOfOwnerBranchIdx)
973+
}
974+
927975
func (self *LocalCommitsController) createAmendCommit(commit *models.Commit, includeFileChanges bool) error {
928976
commitMessage, err := self.c.Git().Commit.GetCommitMessage(commit.Hash)
929977
if err != nil {
@@ -947,6 +995,10 @@ func (self *LocalCommitsController) createAmendCommit(commit *models.Commit, inc
947995
return err
948996
}
949997

998+
if err := self.moveFixupCommitToOwnerStackedBranch(commit); err != nil {
999+
return err
1000+
}
1001+
9501002
self.context().MoveSelectedLine(1)
9511003
return self.c.Refresh(types.RefreshOptions{Mode: types.SYNC})
9521004
})
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package commit
2+
3+
import (
4+
"github.com/jesseduffield/lazygit/pkg/config"
5+
. "github.com/jesseduffield/lazygit/pkg/integration/components"
6+
)
7+
8+
var CreateFixupCommitInBranchStack = NewIntegrationTest(NewIntegrationTestArgs{
9+
Description: "Create a fixup commit in a stack of branches, verify that it is created at the end of the branch it belongs to",
10+
ExtraCmdArgs: []string{},
11+
Skip: false,
12+
GitVersion: AtLeast("2.38.0"),
13+
SetupConfig: func(config *config.AppConfig) {},
14+
SetupRepo: func(shell *Shell) {
15+
shell.NewBranch("branch1")
16+
shell.EmptyCommit("branch1 commit 1")
17+
shell.EmptyCommit("branch1 commit 2")
18+
shell.EmptyCommit("branch1 commit 3")
19+
shell.NewBranch("branch2")
20+
shell.EmptyCommit("branch2 commit 1")
21+
shell.EmptyCommit("branch2 commit 2")
22+
shell.CreateFileAndAdd("fixup-file", "fixup content")
23+
24+
shell.SetConfig("rebase.updateRefs", "true")
25+
},
26+
Run: func(t *TestDriver, keys config.KeybindingConfig) {
27+
t.Views().Commits().
28+
Focus().
29+
Lines(
30+
Contains("CI ◯ branch2 commit 2"),
31+
Contains("CI ◯ branch2 commit 1"),
32+
Contains("CI ◯ * branch1 commit 3"),
33+
Contains("CI ◯ branch1 commit 2"),
34+
Contains("CI ◯ branch1 commit 1"),
35+
).
36+
NavigateToLine(Contains("branch1 commit 2")).
37+
Press(keys.Commits.CreateFixupCommit).
38+
Tap(func() {
39+
t.ExpectPopup().Menu().
40+
Title(Equals("Create fixup commit")).
41+
Select(Contains("fixup! commit")).
42+
Confirm()
43+
}).
44+
Lines(
45+
Contains("CI ◯ branch2 commit 2"),
46+
Contains("CI ◯ branch2 commit 1"),
47+
Contains("CI ◯ * fixup! branch1 commit 2"),
48+
Contains("CI ◯ branch1 commit 3"),
49+
Contains("CI ◯ branch1 commit 2"),
50+
Contains("CI ◯ branch1 commit 1"),
51+
)
52+
},
53+
})

pkg/integration/tests/test_list.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ var tests = []*components.IntegrationTest{
8787
commit.CommitWithNonMatchingBranchName,
8888
commit.CommitWithPrefix,
8989
commit.CreateAmendCommit,
90+
commit.CreateFixupCommitInBranchStack,
9091
commit.CreateTag,
9192
commit.DiscardOldFileChanges,
9293
commit.FindBaseCommitForFixup,

0 commit comments

Comments
 (0)