Support using the selected commit's message in a fixup

I've optimised for muscle memory backwards compatibility here:
  - Outside interactive rebase: press 'f' then instead of a confirmation
panel, a menu appears where you can choose to keep the selected commit's
message
  - Inside interactive rebase: press 'f' then press 'c' to see the menu
for keeping the message, where if you press 'c' again it will retain the
current message. so 'fcc' is the chord to press.

We're also now showing the -C flag (which is what enables the behaviour)
against the todo.

I've picked the 'c' keybinding because 'C' was taken and it corresponds
to the flag. Previously that showed a warning about a change in
keybinding for cherry picking but it's been ages since we've made that
change so I'm happy to retire it.
This commit is contained in:
Jesse Duffield 2026-01-25 08:59:39 +11:00 committed by Stefan Haller
parent 6f6545e44f
commit f317a97ac1
20 changed files with 236 additions and 14 deletions

View file

@ -713,6 +713,7 @@ keybinding:
renameCommitWithEditor: R renameCommitWithEditor: R
viewResetOptions: g viewResetOptions: g
markCommitAsFixup: f markCommitAsFixup: f
setFixupMessage: c
createFixupCommit: F createFixupCommit: F
squashAboveCommits: S squashAboveCommits: S
moveDownCommit: <c-j> moveDownCommit: <c-j>

View file

@ -89,6 +89,7 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
| `` b `` | View bisect options | | | `` b `` | View bisect options | |
| `` s `` | Squash | Squash the selected commit into the commit below it. The selected commit's message will be appended to the commit below it. | | `` s `` | Squash | Squash the selected commit into the commit below it. The selected commit's message will be appended to the commit below it. |
| `` f `` | Fixup | Meld the selected commit into the commit below it. Similar to squash, but the selected commit's message will be discarded. | | `` f `` | Fixup | Meld the selected commit into the commit below it. Similar to squash, but the selected commit's message will be discarded. |
| `` c `` | Set fixup message | Set the message option for the fixup commit. The -C option means to use this commit's message instead of the target commit's message. |
| `` r `` | Reword | Reword the selected commit's message. | | `` r `` | Reword | Reword the selected commit's message. |
| `` R `` | Reword with editor | | | `` R `` | Reword with editor | |
| `` d `` | Drop | Drop the selected commit. This will remove the commit from the branch via a rebase. If the commit makes changes that later commits depend on, you may need to resolve merge conflicts. | | `` d `` | Drop | Drop the selected commit. This will remove the commit from the branch via a rebase. If the commit makes changes that later commits depend on, you may need to resolve merge conflicts. |

View file

@ -69,6 +69,7 @@ _凡例`c-b` はctrl+b、`a-b` はalt+b、`B` はshift+bを意味
| `` b `` | bisectオプションを表示 | | | `` b `` | bisectオプションを表示 | |
| `` s `` | スカッシュ | 選択したコミットをその下のコミットにスカッシュします。スカッシュとは複数のコミットを1つにまとめる操作です。選択したコミットのメッセージが下のコミットに追加されます。 | | `` s `` | スカッシュ | 選択したコミットをその下のコミットにスカッシュします。スカッシュとは複数のコミットを1つにまとめる操作です。選択したコミットのメッセージが下のコミットに追加されます。 |
| `` f `` | フィックスアップ | 選択したコミットをその下のコミットにマージします。フィックスアップはスカッシュと似ていますが、選択したコミットのメッセージは破棄され、下のコミットのメッセージのみが保持されます。 | | `` f `` | フィックスアップ | 選択したコミットをその下のコミットにマージします。フィックスアップはスカッシュと似ていますが、選択したコミットのメッセージは破棄され、下のコミットのメッセージのみが保持されます。 |
| `` c `` | Set fixup message | Set the message option for the fixup commit. The -C option means to use this commit's message instead of the target commit's message. |
| `` r `` | メッセージ変更 | 選択したコミットのメッセージを変更します。 | | `` r `` | メッセージ変更 | 選択したコミットのメッセージを変更します。 |
| `` R `` | エディタでメッセージ変更 | | | `` R `` | エディタでメッセージ変更 | |
| `` d `` | 削除 | 選択したコミットを削除します。これはリベースを通じてブランチからコミットを削除します。コミットが後続のコミットが依存する変更を行っている場合、マージコンフリクトを解決する必要があるかもしれません。 | | `` d `` | 削除 | 選択したコミットを削除します。これはリベースを通じてブランチからコミットを削除します。コミットが後続のコミットが依存する変更を行っている場合、マージコンフリクトを解決する必要があるかもしれません。 |

View file

@ -298,6 +298,7 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
| `` b `` | Bisect 옵션 보기 | | | `` b `` | Bisect 옵션 보기 | |
| `` s `` | 스쿼시 | Squash the selected commit into the commit below it. The selected commit's message will be appended to the commit below it. | | `` s `` | 스쿼시 | Squash the selected commit into the commit below it. The selected commit's message will be appended to the commit below it. |
| `` f `` | Fixup | Meld the selected commit into the commit below it. Similar to squash, but the selected commit's message will be discarded. | | `` f `` | Fixup | Meld the selected commit into the commit below it. Similar to squash, but the selected commit's message will be discarded. |
| `` c `` | Set fixup message | Set the message option for the fixup commit. The -C option means to use this commit's message instead of the target commit's message. |
| `` r `` | 커밋메시지 변경 | Reword the selected commit's message. | | `` r `` | 커밋메시지 변경 | Reword the selected commit's message. |
| `` R `` | 에디터에서 커밋메시지 수정 | | | `` R `` | 에디터에서 커밋메시지 수정 | |
| `` d `` | 커밋 삭제 | Drop the selected commit. This will remove the commit from the branch via a rebase. If the commit makes changes that later commits depend on, you may need to resolve merge conflicts. | | `` d `` | 커밋 삭제 | Drop the selected commit. This will remove the commit from the branch via a rebase. If the commit makes changes that later commits depend on, you may need to resolve merge conflicts. |

View file

@ -160,6 +160,7 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
| `` b `` | View bisect options | | | `` b `` | View bisect options | |
| `` s `` | Squash | Squash the selected commit into the commit below it. The selected commit's message will be appended to the commit below it. | | `` s `` | Squash | Squash the selected commit into the commit below it. The selected commit's message will be appended to the commit below it. |
| `` f `` | Fixup | Meld the selected commit into the commit below it. Similar to squash, but the selected commit's message will be discarded. | | `` f `` | Fixup | Meld the selected commit into the commit below it. Similar to squash, but the selected commit's message will be discarded. |
| `` c `` | Set fixup message | Set the message option for the fixup commit. The -C option means to use this commit's message instead of the target commit's message. |
| `` r `` | Hernoem commit | Reword the selected commit's message. | | `` r `` | Hernoem commit | Reword the selected commit's message. |
| `` R `` | Hernoem commit met editor | | | `` R `` | Hernoem commit met editor | |
| `` d `` | Verwijder commit | Drop the selected commit. This will remove the commit from the branch via a rebase. If the commit makes changes that later commits depend on, you may need to resolve merge conflicts. | | `` d `` | Verwijder commit | Drop the selected commit. This will remove the commit from the branch via a rebase. If the commit makes changes that later commits depend on, you may need to resolve merge conflicts. |

View file

@ -62,6 +62,7 @@ _Legenda: `<c-b>` oznacza ctrl+b, `<a-b>` oznacza alt+b, `B` oznacza shift+b_
| `` b `` | Zobacz opcje bisect | | | `` b `` | Zobacz opcje bisect | |
| `` s `` | Scal | Scal wybrany commit z commitami poniżej. Wiadomość wybranego commita zostanie dołączona do commita poniżej. | | `` s `` | Scal | Scal wybrany commit z commitami poniżej. Wiadomość wybranego commita zostanie dołączona do commita poniżej. |
| `` f `` | Poprawka | Włącz wybrany commit do commita poniżej. Podobnie do fixup, ale wiadomość wybranego commita zostanie odrzucona. | | `` f `` | Poprawka | Włącz wybrany commit do commita poniżej. Podobnie do fixup, ale wiadomość wybranego commita zostanie odrzucona. |
| `` c `` | Set fixup message | Set the message option for the fixup commit. The -C option means to use this commit's message instead of the target commit's message. |
| `` r `` | Przeformułuj | Przeformułuj wiadomość wybranego commita. | | `` r `` | Przeformułuj | Przeformułuj wiadomość wybranego commita. |
| `` R `` | Przeformułuj za pomocą edytora | | | `` R `` | Przeformułuj za pomocą edytora | |
| `` d `` | Usuń | Usuń wybrany commit. To usunie commit z gałęzi za pomocą rebazowania. Jeśli commit wprowadza zmiany, od których zależą późniejsze commity, być może będziesz musiał rozwiązać konflikty scalania. | | `` d `` | Usuń | Usuń wybrany commit. To usunie commit z gałęzi za pomocą rebazowania. Jeśli commit wprowadza zmiany, od których zależą późniejsze commity, być może będziesz musiał rozwiązać konflikty scalania. |

View file

@ -164,6 +164,7 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
| `` b `` | View bisect options | | | `` b `` | View bisect options | |
| `` s `` | Squash | Squash o commit selecionado no commit abaixo dele. A mensagem do commit selecionado será anexada ao commit abaixo dele. | | `` s `` | Squash | Squash o commit selecionado no commit abaixo dele. A mensagem do commit selecionado será anexada ao commit abaixo dele. |
| `` f `` | Fixup | Faça o commit selecionado no commit abaixo dele. Semelhante para o squash, mas a mensagem do commit selecionado será descartada. | | `` f `` | Fixup | Faça o commit selecionado no commit abaixo dele. Semelhante para o squash, mas a mensagem do commit selecionado será descartada. |
| `` c `` | Set fixup message | Set the message option for the fixup commit. The -C option means to use this commit's message instead of the target commit's message. |
| `` r `` | Reword | Repetir a mensagem de submissão selecionada. | | `` r `` | Reword | Repetir a mensagem de submissão selecionada. |
| `` R `` | Republicar com o editor | | | `` R `` | Republicar com o editor | |
| `` d `` | Descartar | Solte o commit selecionado. Isso irá remover o commit do branch através de uma rebase. Se o commit faz com que as alterações em commits posteriores dependem, você pode precisar resolver conflitos de merge. | | `` d `` | Descartar | Solte o commit selecionado. Isso irá remover o commit do branch através de uma rebase. Se o commit faz com que as alterações em commits posteriores dependem, você pode precisar resolver conflitos de merge. |

View file

@ -170,6 +170,7 @@ _Связки клавиш_
| `` b `` | Просмотреть параметры бинарного поиска | | | `` b `` | Просмотреть параметры бинарного поиска | |
| `` s `` | Объединить коммиты (Squash) | Squash the selected commit into the commit below it. The selected commit's message will be appended to the commit below it. | | `` s `` | Объединить коммиты (Squash) | Squash the selected commit into the commit below it. The selected commit's message will be appended to the commit below it. |
| `` f `` | Объединить несколько коммитов в один отбросив сообщение коммита (Fixup) | Meld the selected commit into the commit below it. Similar to squash, but the selected commit's message will be discarded. | | `` f `` | Объединить несколько коммитов в один отбросив сообщение коммита (Fixup) | Meld the selected commit into the commit below it. Similar to squash, but the selected commit's message will be discarded. |
| `` c `` | Set fixup message | Set the message option for the fixup commit. The -C option means to use this commit's message instead of the target commit's message. |
| `` r `` | Перефразировать коммит | Reword the selected commit's message. | | `` r `` | Перефразировать коммит | Reword the selected commit's message. |
| `` R `` | Переписать коммит с помощью редактора | | | `` R `` | Переписать коммит с помощью редактора | |
| `` d `` | Удалить коммит | Drop the selected commit. This will remove the commit from the branch via a rebase. If the commit makes changes that later commits depend on, you may need to resolve merge conflicts. | | `` d `` | Удалить коммит | Drop the selected commit. This will remove the commit from the branch via a rebase. If the commit makes changes that later commits depend on, you may need to resolve merge conflicts. |

View file

@ -126,6 +126,7 @@ _图例`<c-b>` 意味着ctrl+b, `<a-b>意味着Alt+b, `B` 意味着shift+b_
| `` b `` | 查看二分查找选项 | | | `` b `` | 查看二分查找选项 | |
| `` s `` | 压缩(Squash) | 将已选提交压缩到该提交之下。这些选定的提交的消息会附加到该提交的消息之下。 | | `` s `` | 压缩(Squash) | 将已选提交压缩到该提交之下。这些选定的提交的消息会附加到该提交的消息之下。 |
| `` f `` | 修正 fixup | 将选定的提交合并到其下面的提交中。与压缩类似,但所选提交的消息将被丢弃。 | | `` f `` | 修正 fixup | 将选定的提交合并到其下面的提交中。与压缩类似,但所选提交的消息将被丢弃。 |
| `` c `` | Set fixup message | Set the message option for the fixup commit. The -C option means to use this commit's message instead of the target commit's message. |
| `` r `` | 改写提交 | 重写所选提交的消息。 | | `` r `` | 改写提交 | 重写所选提交的消息。 |
| `` R `` | 使用编辑器重命名提交 | | | `` R `` | 使用编辑器重命名提交 | |
| `` d `` | 删除提交 | 删除选中的提交。这将通过变基从分支中删除该提交,如果该提交修改的内容依赖于后续的提交,则需要解决合并冲突。 | | `` d `` | 删除提交 | 删除选中的提交。这将通过变基从分支中删除该提交,如果该提交修改的内容依赖于后续的提交,则需要解决合并冲突。 |

View file

@ -184,6 +184,7 @@ _說明`<c-b>` 表示 CtrlB、`<a-b>` 表示 AltB`B`表示 ShiftB
| `` b `` | 查看二分選項 | | | `` b `` | 查看二分選項 | |
| `` s `` | 壓縮 (Squash) | Squash the selected commit into the commit below it. The selected commit's message will be appended to the commit below it. | | `` s `` | 壓縮 (Squash) | Squash the selected commit into the commit below it. The selected commit's message will be appended to the commit below it. |
| `` f `` | 修復 (Fixup) | Meld the selected commit into the commit below it. Similar to squash, but the selected commit's message will be discarded. | | `` f `` | 修復 (Fixup) | Meld the selected commit into the commit below it. Similar to squash, but the selected commit's message will be discarded. |
| `` c `` | Set fixup message | Set the message option for the fixup commit. The -C option means to use this commit's message instead of the target commit's message. |
| `` r `` | 改寫提交 | 改寫選中的提交訊息 | | `` r `` | 改寫提交 | 改寫選中的提交訊息 |
| `` R `` | 使用編輯器改寫提交 | | | `` R `` | 使用編輯器改寫提交 | |
| `` d `` | 刪除提交 | Drop the selected commit. This will remove the commit from the branch via a rebase. If the commit makes changes that later commits depend on, you may need to resolve merge conflicts. | | `` d `` | 刪除提交 | Drop the selected commit. This will remove the commit from the branch via a rebase. If the commit makes changes that later commits depend on, you may need to resolve merge conflicts. |

View file

@ -551,6 +551,7 @@ type KeybindingCommitsConfig struct {
RenameCommitWithEditor string `yaml:"renameCommitWithEditor"` RenameCommitWithEditor string `yaml:"renameCommitWithEditor"`
ViewResetOptions string `yaml:"viewResetOptions"` ViewResetOptions string `yaml:"viewResetOptions"`
MarkCommitAsFixup string `yaml:"markCommitAsFixup"` MarkCommitAsFixup string `yaml:"markCommitAsFixup"`
SetFixupMessage string `yaml:"setFixupMessage"`
CreateFixupCommit string `yaml:"createFixupCommit"` CreateFixupCommit string `yaml:"createFixupCommit"`
SquashAboveCommits string `yaml:"squashAboveCommits"` SquashAboveCommits string `yaml:"squashAboveCommits"`
MoveDownCommit string `yaml:"moveDownCommit"` MoveDownCommit string `yaml:"moveDownCommit"`
@ -1008,6 +1009,7 @@ func GetDefaultConfig() *UserConfig {
RenameCommitWithEditor: "R", RenameCommitWithEditor: "R",
ViewResetOptions: "g", ViewResetOptions: "g",
MarkCommitAsFixup: "f", MarkCommitAsFixup: "f",
SetFixupMessage: "c",
CreateFixupCommit: "F", CreateFixupCommit: "F",
SquashAboveCommits: "S", SquashAboveCommits: "S",
MoveDownCommit: "<c-j>", MoveDownCommit: "<c-j>",

View file

@ -82,6 +82,15 @@ func (self *LocalCommitsController) GetKeybindings(opts types.KeybindingsOpts) [
Tooltip: self.c.Tr.FixupTooltip, Tooltip: self.c.Tr.FixupTooltip,
DisplayOnScreen: true, DisplayOnScreen: true,
}, },
{
Key: opts.GetKey(opts.Config.Commits.SetFixupMessage),
Handler: self.withItem(self.setFixupMessage),
GetDisabledReason: self.require(
self.singleItemSelected(self.canSetFixupMessage),
),
Description: self.c.Tr.SetFixupMessage,
Tooltip: self.c.Tr.SetFixupMessageTooltip,
},
{ {
Key: opts.GetKey(opts.Config.Commits.RenameCommit), Key: opts.GetKey(opts.Config.Commits.RenameCommit),
Handler: self.withItem(self.reword), Handler: self.withItem(self.reword),
@ -321,20 +330,71 @@ func (self *LocalCommitsController) fixup(selectedCommits []*models.Commit, star
return self.updateTodos(todo.Fixup, selectedCommits) return self.updateTodos(todo.Fixup, selectedCommits)
} }
self.c.Confirm(types.ConfirmOpts{ return self.c.Menu(types.CreateMenuOptions{
Title: self.c.Tr.Fixup, Title: self.c.Tr.Fixup,
Prompt: self.c.Tr.SureFixupThisCommit, Items: []*types.MenuItem{
HandleConfirm: func() error { {
return self.c.WithWaitingStatus(self.c.Tr.FixingStatus, func(gocui.Task) error { Label: self.c.Tr.Fixup,
self.c.LogAction(self.c.Tr.Actions.FixupCommit) Key: 'f',
return self.interactiveRebase(todo.Fixup, startIdx, endIdx) OnPress: func() error {
}) return self.c.WithWaitingStatus(self.c.Tr.FixingStatus, func(gocui.Task) error {
self.c.LogAction(self.c.Tr.Actions.FixupCommit)
return self.interactiveRebase(todo.Fixup, startIdx, endIdx)
})
},
Tooltip: self.c.Tr.FixupTooltip,
},
{
Label: self.c.Tr.FixupKeepMessage,
Key: 'c',
OnPress: func() error {
return self.c.WithWaitingStatus(self.c.Tr.FixingStatus, func(gocui.Task) error {
self.c.LogAction(self.c.Tr.Actions.FixupCommitKeepMessage)
return self.interactiveRebaseWithFlag(todo.Fixup, startIdx, endIdx, "-C")
})
},
Tooltip: self.c.Tr.FixupKeepMessageTooltip,
},
}, },
}) })
}
func (self *LocalCommitsController) canSetFixupMessage(commit *models.Commit) *types.DisabledReason {
if !self.isRebasing() {
return &types.DisabledReason{Text: self.c.Tr.NotMidRebase}
}
if commit.Action != todo.Fixup {
return &types.DisabledReason{Text: self.c.Tr.MustSelectFixupCommit}
}
return nil return nil
} }
func (self *LocalCommitsController) setFixupMessage(commit *models.Commit) error {
return self.c.Menu(types.CreateMenuOptions{
Title: self.c.Tr.SetFixupMessage,
Items: []*types.MenuItem{
{
Label: self.c.Tr.FixupDiscardMessage,
Key: 'f',
OnPress: func() error {
return self.updateTodosWithFlag(todo.Fixup, []*models.Commit{commit}, "")
},
Tooltip: self.c.Tr.FixupDiscardMessageTooltip,
},
{
Label: self.c.Tr.FixupKeepMessage,
Key: 'c',
OnPress: func() error {
return self.updateTodosWithFlag(todo.Fixup, []*models.Commit{commit}, "-C")
},
Tooltip: self.c.Tr.FixupKeepMessageTooltip,
},
},
})
}
func (self *LocalCommitsController) reword(commit *models.Commit) error { func (self *LocalCommitsController) reword(commit *models.Commit) error {
commitIdx := self.context().GetSelectedLineIdx() commitIdx := self.context().GetSelectedLineIdx()
if self.c.Git().Config.NeedsGpgSubprocessForCommit() && !self.isHeadCommit(commitIdx) { if self.c.Git().Config.NeedsGpgSubprocessForCommit() && !self.isHeadCommit(commitIdx) {

View file

@ -164,7 +164,12 @@ type TranslationSet struct {
CannotSquashOrFixupMergeCommit string CannotSquashOrFixupMergeCommit string
Fixup string Fixup string
FixupTooltip string FixupTooltip string
SureFixupThisCommit string FixupKeepMessage string
FixupKeepMessageTooltip string
SetFixupMessage string
SetFixupMessageTooltip string
FixupDiscardMessage string
FixupDiscardMessageTooltip string
SureSquashThisCommit string SureSquashThisCommit string
Squash string Squash string
PickCommitTooltip string PickCommitTooltip string
@ -316,6 +321,8 @@ type TranslationSet struct {
ViewRevertOptions string ViewRevertOptions string
NotMergingOrRebasing string NotMergingOrRebasing string
AlreadyRebasing string AlreadyRebasing string
NotMidRebase string
MustSelectFixupCommit string
RecentRepos string RecentRepos string
MergeOptionsTitle string MergeOptionsTitle string
RebaseOptionsTitle string RebaseOptionsTitle string
@ -965,6 +972,7 @@ type Actions struct {
CheckoutFile string CheckoutFile string
SquashCommitDown string SquashCommitDown string
FixupCommit string FixupCommit string
FixupCommitKeepMessage string
RewordCommit string RewordCommit string
DropCommit string DropCommit string
EditCommit string EditCommit string
@ -1259,7 +1267,12 @@ func EnglishTranslationSet() *TranslationSet {
CannotSquashOrFixupFirstCommit: "There's no commit below to squash into", CannotSquashOrFixupFirstCommit: "There's no commit below to squash into",
CannotSquashOrFixupMergeCommit: "Cannot squash or fixup a merge commit", CannotSquashOrFixupMergeCommit: "Cannot squash or fixup a merge commit",
Fixup: "Fixup", Fixup: "Fixup",
SureFixupThisCommit: "Are you sure you want to 'fixup' the selected commit(s) into the commit below?", FixupKeepMessage: "Fixup and use this commit's message",
FixupKeepMessageTooltip: "Squash the selected commit into the commit below, using this commit's message, discarding the message of the commit below.",
SetFixupMessage: "Set fixup message",
SetFixupMessageTooltip: "Set the message option for the fixup commit. The -C option means to use this commit's message instead of the target commit's message.",
FixupDiscardMessage: "Fixup and discard this commit's message",
FixupDiscardMessageTooltip: "Squash the selected commit into the commit below, discarding this commit's message.",
SureSquashThisCommit: "Are you sure you want to squash the selected commit(s) into the commit below?", SureSquashThisCommit: "Are you sure you want to squash the selected commit(s) into the commit below?",
Squash: "Squash", Squash: "Squash",
PickCommitTooltip: "Mark the selected commit to be picked (when mid-rebase). This means that the commit will be retained upon continuing the rebase.", PickCommitTooltip: "Mark the selected commit to be picked (when mid-rebase). This means that the commit will be retained upon continuing the rebase.",
@ -1411,6 +1424,8 @@ func EnglishTranslationSet() *TranslationSet {
ViewRevertOptions: "View revert options", ViewRevertOptions: "View revert options",
NotMergingOrRebasing: "You are currently neither rebasing nor merging", NotMergingOrRebasing: "You are currently neither rebasing nor merging",
AlreadyRebasing: "Can't perform this action during a rebase", AlreadyRebasing: "Can't perform this action during a rebase",
NotMidRebase: "This action only works during an interactive rebase",
MustSelectFixupCommit: "This action only works on fixup commits",
RecentRepos: "Recent repositories", RecentRepos: "Recent repositories",
MergeOptionsTitle: "Merge options", MergeOptionsTitle: "Merge options",
RebaseOptionsTitle: "Rebase options", RebaseOptionsTitle: "Rebase options",
@ -2023,6 +2038,7 @@ func EnglishTranslationSet() *TranslationSet {
CheckoutFile: "Checkout file", CheckoutFile: "Checkout file",
SquashCommitDown: "Squash commit down", SquashCommitDown: "Squash commit down",
FixupCommit: "Fixup commit", FixupCommit: "Fixup commit",
FixupCommitKeepMessage: "Fixup commit (keep message)",
RewordCommit: "Reword commit", RewordCommit: "Reword commit",
DropCommit: "Drop commit", DropCommit: "Drop commit",
EditCommit: "Edit commit", EditCommit: "Edit commit",

View file

@ -0,0 +1,48 @@
package interactive_rebase
import (
"github.com/jesseduffield/lazygit/pkg/config"
. "github.com/jesseduffield/lazygit/pkg/integration/components"
)
var FixupKeepMessage = NewIntegrationTest(NewIntegrationTestArgs{
Description: "Fixup a commit, keeping its commit message",
ExtraCmdArgs: []string{},
Skip: false,
SetupConfig: func(config *config.AppConfig) {},
SetupRepo: func(shell *Shell) {
shell.
CreateFileAndAdd("file1.txt", "File1 Content\n").Commit("First Commit").
CreateFileAndAdd("file2.txt", "File2 Content\n").Commit("Second Commit").
CreateFileAndAdd("file3.txt", "File3 Content\n").Commit("Third Commit")
},
Run: func(t *TestDriver, keys config.KeybindingConfig) {
t.Views().Commits().
Focus().
Lines(
Contains("Third Commit"),
Contains("Second Commit"),
Contains("First Commit"),
).
NavigateToLine(Contains("Second Commit")).
Press(keys.Commits.MarkCommitAsFixup).
Tap(func() {
t.ExpectPopup().Menu().
Title(Equals("Fixup")).
Select(Contains("use this commit's message")).
Confirm()
}).
Lines(
Contains("Third Commit"),
Contains("Second Commit").IsSelected(),
)
t.Views().Main().
// The resulting commit should have the message from the fixup commit,
// not the target commit
Content(Contains("Second Commit")).
Content(DoesNotContain("First Commit")).
Content(Contains("+File1 Content")).
Content(Contains("+File2 Content"))
},
})

View file

@ -0,0 +1,78 @@
package interactive_rebase
import (
"github.com/jesseduffield/lazygit/pkg/config"
. "github.com/jesseduffield/lazygit/pkg/integration/components"
)
var FixupKeepMessageRebase = NewIntegrationTest(NewIntegrationTestArgs{
Description: "Set fixup -C flag on a fixup commit during interactive rebase",
ExtraCmdArgs: []string{},
Skip: false,
SetupConfig: func(config *config.AppConfig) {},
SetupRepo: func(shell *Shell) {
shell.
CreateFileAndAdd("file1.txt", "File1 Content\n").Commit("First Commit").
CreateFileAndAdd("file2.txt", "File2 Content\n").Commit("Second Commit").
CreateFileAndAdd("file3.txt", "File3 Content\n").Commit("Third Commit")
},
Run: func(t *TestDriver, keys config.KeybindingConfig) {
t.Views().Commits().
Focus().
Lines(
Contains("Third Commit"),
Contains("Second Commit"),
Contains("First Commit"),
).
// Start interactive rebase from the first commit
NavigateToLine(Contains("First Commit")).
Press(keys.Universal.Edit).
Lines(
Contains("--- Pending rebase todos ---"),
Contains("pick CI Third Commit"),
Contains("pick CI Second Commit"),
Contains("--- Commits ---"),
Contains("First Commit").IsSelected(),
).
// Mark second commit as fixup
NavigateToLine(Contains("Second Commit")).
Press(keys.Commits.MarkCommitAsFixup).
Lines(
Contains("--- Pending rebase todos ---"),
Contains("pick CI Third Commit"),
Contains("fixup CI Second Commit").IsSelected(),
Contains("--- Commits ---"),
Contains("First Commit"),
).
// Now set the -C flag using the SetFixupMessage keybinding
Press(keys.Commits.SetFixupMessage).
Tap(func() {
t.ExpectPopup().Menu().
Title(Equals("Set fixup message")).
Select(Contains("use this commit's message")).
Confirm()
}).
Lines(
Contains("--- Pending rebase todos ---"),
Contains("pick CI Third Commit"),
Contains("fixup -C CI Second Commit").IsSelected(),
Contains("--- Commits ---"),
Contains("First Commit"),
).
// Continue the rebase
Tap(func() {
t.Common().ContinueRebase()
}).
Lines(
Contains("Third Commit"),
Contains("Second Commit").IsSelected(),
)
t.Views().Main().
// The resulting commit should have the message from the fixup commit
Content(Contains("Second Commit")).
Content(DoesNotContain("First Commit")).
Content(Contains("+File1 Content")).
Content(Contains("+File2 Content"))
},
})

View file

@ -27,9 +27,8 @@ var FixupSecondCommit = NewIntegrationTest(NewIntegrationTestArgs{
NavigateToLine(Contains("Fixup Commit Message")). NavigateToLine(Contains("Fixup Commit Message")).
Press(keys.Commits.MarkCommitAsFixup). Press(keys.Commits.MarkCommitAsFixup).
Tap(func() { Tap(func() {
t.ExpectPopup().Confirmation(). t.ExpectPopup().Menu().
Title(Equals("Fixup")). Title(Equals("Fixup")).
Content(Equals("Are you sure you want to 'fixup' the selected commit(s) into the commit below?")).
Confirm() Confirm()
}). }).
Lines( Lines(

View file

@ -77,9 +77,8 @@ var OutsideRebaseRangeSelect = NewIntegrationTest(NewIntegrationTestArgs{
). ).
Press(keys.Commits.MarkCommitAsFixup). Press(keys.Commits.MarkCommitAsFixup).
Tap(func() { Tap(func() {
t.ExpectPopup().Confirmation(). t.ExpectPopup().Menu().
Title(Equals("Fixup")). Title(Equals("Fixup")).
Content(Contains("Are you sure you want to 'fixup' the selected commit(s) into the commit below?")).
Confirm() Confirm()
}). }).
TopLines( TopLines(

View file

@ -279,6 +279,8 @@ var tests = []*components.IntegrationTest{
interactive_rebase.EditRangeSelectOutsideRebase, interactive_rebase.EditRangeSelectOutsideRebase,
interactive_rebase.EditTheConflCommit, interactive_rebase.EditTheConflCommit,
interactive_rebase.FixupFirstCommit, interactive_rebase.FixupFirstCommit,
interactive_rebase.FixupKeepMessage,
interactive_rebase.FixupKeepMessageRebase,
interactive_rebase.FixupSecondCommit, interactive_rebase.FixupSecondCommit,
interactive_rebase.InteractiveRebaseOfCopiedBranch, interactive_rebase.InteractiveRebaseOfCopiedBranch,
interactive_rebase.InteractiveRebaseWithConflictForEditCommand, interactive_rebase.InteractiveRebaseWithConflictForEditCommand,

View file

@ -946,6 +946,10 @@
"type": "string", "type": "string",
"default": "f" "default": "f"
}, },
"setFixupMessage": {
"type": "string",
"default": "c"
},
"createFixupCommit": { "createFixupCommit": {
"type": "string", "type": "string",
"default": "F" "default": "F"

View file

@ -946,6 +946,10 @@
"type": "string", "type": "string",
"default": "f" "default": "f"
}, },
"setFixupMessage": {
"type": "string",
"default": "c"
},
"createFixupCommit": { "createFixupCommit": {
"type": "string", "type": "string",
"default": "F" "default": "F"