mirror of
https://github.com/jesseduffield/lazygit.git
synced 2024-11-24 08:52:21 +02:00
Add command to squash all fixups in the current branch
To do that, change the "Apply fixup commits" command to show a menu with the two choices "in current branch" and "above the selected commit"; we make "in current branch" the default, as it's the more useful one most of the time, even though it is a breaking change for those who are used to "shift-S enter" meaning "squash above selected".
This commit is contained in:
parent
24e79a057c
commit
b133318b40
@ -89,7 +89,7 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
|
||||
If you would instead like to start an interactive rebase from the selected commit, press `e`. |
|
||||
| `` p `` | Pick | Mark the selected commit to be picked (when mid-rebase). This means that the commit will be retained upon continuing the rebase. |
|
||||
| `` F `` | Create fixup commit | Create 'fixup!' commit for the selected commit. Later on, you can press `S` on this same commit to apply all above fixup commits. |
|
||||
| `` S `` | Apply fixup commits | Squash all 'fixup!' commits above selected commit (autosquash). |
|
||||
| `` S `` | Apply fixup commits | Squash all 'fixup!' commits, either above the selected commit, or all in current branch (autosquash). |
|
||||
| `` <c-j> `` | Move commit down one | |
|
||||
| `` <c-k> `` | Move commit up one | |
|
||||
| `` V `` | Paste (cherry-pick) | |
|
||||
|
@ -106,7 +106,7 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
|
||||
If you would instead like to start an interactive rebase from the selected commit, press `e`. |
|
||||
| `` p `` | Pick | Mark the selected commit to be picked (when mid-rebase). This means that the commit will be retained upon continuing the rebase. |
|
||||
| `` F `` | Create fixup commit | このコミットに対するfixupコミットを作成 |
|
||||
| `` S `` | Apply fixup commits | Squash all 'fixup!' commits above selected commit (autosquash). |
|
||||
| `` S `` | Apply fixup commits | Squash all 'fixup!' commits, either above the selected commit, or all in current branch (autosquash). |
|
||||
| `` <c-j> `` | コミットを1つ下に移動 | |
|
||||
| `` <c-k> `` | コミットを1つ上に移動 | |
|
||||
| `` V `` | コミットを貼り付け (cherry-pick) | |
|
||||
|
@ -167,13 +167,13 @@ func (self *LocalCommitsController) GetKeybindings(opts types.KeybindingsOpts) [
|
||||
},
|
||||
{
|
||||
Key: opts.GetKey(opts.Config.Commits.SquashAboveCommits),
|
||||
Handler: self.withItem(self.squashAllAboveFixupCommits),
|
||||
Handler: self.squashFixupCommits,
|
||||
GetDisabledReason: self.require(
|
||||
self.notMidRebase(self.c.Tr.AlreadyRebasing),
|
||||
self.singleItemSelected(),
|
||||
),
|
||||
Description: self.c.Tr.SquashAboveCommits,
|
||||
Tooltip: self.c.Tr.SquashAboveCommitsTooltip,
|
||||
OpensMenu: true,
|
||||
},
|
||||
{
|
||||
Key: opts.GetKey(opts.Config.Commits.MoveDownCommit),
|
||||
@ -816,25 +816,62 @@ func (self *LocalCommitsController) createFixupCommit(commit *models.Commit) err
|
||||
})
|
||||
}
|
||||
|
||||
func (self *LocalCommitsController) squashAllAboveFixupCommits(commit *models.Commit) error {
|
||||
prompt := utils.ResolvePlaceholderString(
|
||||
self.c.Tr.SureSquashAboveCommits,
|
||||
map[string]string{"commit": commit.Sha},
|
||||
)
|
||||
|
||||
return self.c.Confirm(types.ConfirmOpts{
|
||||
Title: self.c.Tr.SquashAboveCommits,
|
||||
Prompt: prompt,
|
||||
HandleConfirm: func() error {
|
||||
return self.c.WithWaitingStatus(self.c.Tr.SquashingStatus, func(gocui.Task) error {
|
||||
self.c.LogAction(self.c.Tr.Actions.SquashAllAboveFixupCommits)
|
||||
err := self.c.Git().Rebase.SquashAllAboveFixupCommits(commit)
|
||||
return self.c.Helpers().MergeAndRebase.CheckMergeOrRebase(err)
|
||||
})
|
||||
func (self *LocalCommitsController) squashFixupCommits() error {
|
||||
return self.c.Menu(types.CreateMenuOptions{
|
||||
Title: self.c.Tr.SquashAboveCommits,
|
||||
Items: []*types.MenuItem{
|
||||
{
|
||||
Label: self.c.Tr.SquashCommitsInCurrentBranch,
|
||||
OnPress: self.squashAllFixupsInCurrentBranch,
|
||||
DisabledReason: self.canFindCommitForSquashFixupsInCurrentBranch(),
|
||||
Key: 'b',
|
||||
Tooltip: self.c.Tr.SquashCommitsInCurrentBranchTooltip,
|
||||
},
|
||||
{
|
||||
Label: self.c.Tr.SquashCommitsAboveSelectedCommit,
|
||||
OnPress: self.withItem(self.squashAllFixupsAboveSelectedCommit),
|
||||
DisabledReason: self.singleItemSelected()(),
|
||||
Key: 'a',
|
||||
Tooltip: self.c.Tr.SquashCommitsAboveSelectedTooltip,
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func (self *LocalCommitsController) squashAllFixupsAboveSelectedCommit(commit *models.Commit) error {
|
||||
return self.c.WithWaitingStatus(self.c.Tr.SquashingStatus, func(gocui.Task) error {
|
||||
self.c.LogAction(self.c.Tr.Actions.SquashAllAboveFixupCommits)
|
||||
err := self.c.Git().Rebase.SquashAllAboveFixupCommits(commit)
|
||||
return self.c.Helpers().MergeAndRebase.CheckMergeOrRebase(err)
|
||||
})
|
||||
}
|
||||
|
||||
func (self *LocalCommitsController) squashAllFixupsInCurrentBranch() error {
|
||||
commit, err := self.findCommitForSquashFixupsInCurrentBranch()
|
||||
if err != nil {
|
||||
return self.c.Error(err)
|
||||
}
|
||||
|
||||
return self.c.WithWaitingStatus(self.c.Tr.SquashingStatus, func(gocui.Task) error {
|
||||
self.c.LogAction(self.c.Tr.Actions.SquashAllAboveFixupCommits)
|
||||
err := self.c.Git().Rebase.SquashAllAboveFixupCommits(commit)
|
||||
return self.c.Helpers().MergeAndRebase.CheckMergeOrRebase(err)
|
||||
})
|
||||
}
|
||||
|
||||
func (self *LocalCommitsController) findCommitForSquashFixupsInCurrentBranch() (*models.Commit, error) {
|
||||
commits := self.c.Model().Commits
|
||||
_, index, ok := lo.FindIndexOf(commits, func(c *models.Commit) bool {
|
||||
return c.IsMerge() || c.Status == models.StatusMerged
|
||||
})
|
||||
|
||||
if !ok || index == 0 {
|
||||
return nil, errors.New(self.c.Tr.CannotSquashCommitsInCurrentBranch)
|
||||
}
|
||||
|
||||
return commits[index-1], nil
|
||||
}
|
||||
|
||||
func (self *LocalCommitsController) createTag(commit *models.Commit) error {
|
||||
return self.c.Helpers().Tags.OpenCreateTagPrompt(commit.Sha, func() {})
|
||||
}
|
||||
@ -1019,6 +1056,14 @@ func (self *LocalCommitsController) canFindCommitForQuickStart() *types.Disabled
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *LocalCommitsController) canFindCommitForSquashFixupsInCurrentBranch() *types.DisabledReason {
|
||||
if _, err := self.findCommitForSquashFixupsInCurrentBranch(); err != nil {
|
||||
return &types.DisabledReason{Text: err.Error()}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *LocalCommitsController) canSquashOrFixup(_selectedCommits []*models.Commit, startIdx int, endIdx int) *types.DisabledReason {
|
||||
if endIdx >= len(self.c.Model().Commits)-1 {
|
||||
return &types.DisabledReason{Text: self.c.Tr.CannotSquashOrFixupFirstCommit}
|
||||
|
@ -254,7 +254,6 @@ func chineseTranslationSet() TranslationSet {
|
||||
ViewResetOptions: `查看重置选项`,
|
||||
CreateFixupCommit: `为此提交创建修正`,
|
||||
SquashAboveCommitsTooltip: `压缩在所选提交之上的所有“fixup!”提交(自动压缩)`,
|
||||
SureSquashAboveCommits: `您确定要压缩在 {{.commit}} 之上的所有“fixup!”提交吗?`,
|
||||
CreateFixupCommitTooltip: `创建修正提交`,
|
||||
SureCreateFixupCommit: `您确定要对 {{.commit}} 创建修正提交吗?`,
|
||||
ExecuteCustomCommand: "执行自定义命令",
|
||||
|
@ -217,7 +217,6 @@ func dutchTranslationSet() TranslationSet {
|
||||
HardReset: "Harde reset",
|
||||
CreateFixupCommit: `Creëer fixup commit voor deze commit`,
|
||||
SquashAboveCommitsTooltip: `Squash bovenstaande commits`,
|
||||
SureSquashAboveCommits: `Weet je zeker dat je alles wil squash/fixup! voor de bovenstaand commits {{.commit}}?`,
|
||||
CreateFixupCommitTooltip: `Creëer fixup commit`,
|
||||
SureCreateFixupCommit: `Weet je zeker dat je een fixup wil maken! commit voor commit {{.commit}}?`,
|
||||
ExecuteCustomCommand: "Voer aangepaste commando uit",
|
||||
|
@ -386,8 +386,12 @@ type TranslationSet struct {
|
||||
CreateFixupCommitDescription string
|
||||
CreateFixupCommitTooltip string
|
||||
SquashAboveCommitsTooltip string
|
||||
SquashCommitsAboveSelectedTooltip string
|
||||
SquashCommitsInCurrentBranchTooltip string
|
||||
SquashAboveCommits string
|
||||
SureSquashAboveCommits string
|
||||
SquashCommitsInCurrentBranch string
|
||||
SquashCommitsAboveSelectedCommit string
|
||||
CannotSquashCommitsInCurrentBranch string
|
||||
SureCreateFixupCommit string
|
||||
ExecuteCustomCommand string
|
||||
ExecuteCustomCommandTooltip string
|
||||
@ -1322,8 +1326,12 @@ func EnglishTranslationSet() TranslationSet {
|
||||
CreateFixupCommitDescription: `Create fixup commit`,
|
||||
CreateFixupCommitTooltip: "Create 'fixup!' commit for the selected commit. Later on, you can press `{{.squashAbove}}` on this same commit to apply all above fixup commits.",
|
||||
SquashAboveCommits: "Apply fixup commits",
|
||||
SquashAboveCommitsTooltip: `Squash all 'fixup!' commits above selected commit (autosquash).`,
|
||||
SureSquashAboveCommits: `Are you sure you want to squash all fixup! commits above {{.commit}}?`,
|
||||
SquashAboveCommitsTooltip: `Squash all 'fixup!' commits, either above the selected commit, or all in current branch (autosquash).`,
|
||||
SquashCommitsAboveSelectedTooltip: `Squash all 'fixup!' commits above the selected commit (autosquash).`,
|
||||
SquashCommitsInCurrentBranchTooltip: `Squash all 'fixup!' commits in the current branch (autosquash).`,
|
||||
SquashCommitsInCurrentBranch: "In current branch",
|
||||
SquashCommitsAboveSelectedCommit: "Above the selected commit",
|
||||
CannotSquashCommitsInCurrentBranch: "Cannot squash commits in current branch: the HEAD commit is a merge commit or is present on the main branch.",
|
||||
CreateFixupCommit: `Create fixup commit`,
|
||||
SureCreateFixupCommit: `Are you sure you want to create a fixup! commit for commit {{.commit}}?`,
|
||||
ExecuteCustomCommand: "Execute custom command",
|
||||
|
@ -263,7 +263,6 @@ func japaneseTranslationSet() TranslationSet {
|
||||
CreateFixupCommitTooltip: `このコミットに対するfixupコミットを作成`,
|
||||
// LcSquashAboveCommits: `squash all 'fixup!' commits above selected commit (autosquash)`,
|
||||
// SquashAboveCommits: `Squash all 'fixup!' commits above selected commit (autosquash)`,
|
||||
SureSquashAboveCommits: `{{.commit}}に対するすべての fixup! コミットをsquashします。よろしいですか?`,
|
||||
CreateFixupCommit: `Fixupコミットを作成`,
|
||||
SureCreateFixupCommit: `{{.commit}} に対する fixup! コミットを作成します。よろしいですか?`,
|
||||
ExecuteCustomCommand: "カスタムコマンドを実行",
|
||||
|
@ -258,7 +258,6 @@ func koreanTranslationSet() TranslationSet {
|
||||
ViewResetOptions: `View reset options`,
|
||||
CreateFixupCommitTooltip: `Create fixup commit for this commit`,
|
||||
SquashAboveCommitsTooltip: `Squash all 'fixup!' commits above selected commit (autosquash)`,
|
||||
SureSquashAboveCommits: `Are you sure you want to squash all fixup! commits above {{.commit}}?`,
|
||||
CreateFixupCommit: `Create fixup commit`,
|
||||
SureCreateFixupCommit: `Are you sure you want to create a fixup! commit for commit {{.commit}}?`,
|
||||
ExecuteCustomCommand: "Execute custom command",
|
||||
|
@ -180,7 +180,6 @@ func polishTranslationSet() TranslationSet {
|
||||
ViewResetOptions: "Wyświetl opcje resetu",
|
||||
CreateFixupCommitTooltip: "Utwórz commit naprawczy dla tego commita",
|
||||
SquashAboveCommitsTooltip: `Spłaszcz wszystkie commity naprawcze powyżej zaznaczonych commitów (autosquash)`,
|
||||
SureSquashAboveCommits: `Na pewno chcesz spłaszczyć wszystkie commity naprawcze powyżej {{.commit}}?`,
|
||||
CreateFixupCommit: `Utwóż commit naprawczy`,
|
||||
SureCreateFixupCommit: `Na pewno utworzyć commit naprawczy dla commita {{.commit}}?`,
|
||||
ExecuteCustomCommand: "Wykonaj własną komendę",
|
||||
|
@ -314,7 +314,6 @@ func RussianTranslationSet() TranslationSet {
|
||||
ViewResetOptions: `Просмотреть параметры сброса`,
|
||||
CreateFixupCommitTooltip: `Создать fixup коммит для этого коммита`,
|
||||
SquashAboveCommitsTooltip: `Объединить все 'fixup!' коммиты выше в выбранный коммит (автосохранение)`,
|
||||
SureSquashAboveCommits: `Вы уверены, что хотите объединить все fixup! коммиты выше {{.commit}}?`,
|
||||
CreateFixupCommit: `Создать fixup коммит`,
|
||||
SureCreateFixupCommit: `Вы уверены, что хотите создать fixup! коммит для коммита {{.commit}}?`,
|
||||
ExecuteCustomCommand: "Выполнить пользовательскую команду",
|
||||
|
@ -341,7 +341,6 @@ func traditionalChineseTranslationSet() TranslationSet {
|
||||
ViewResetOptions: "檢視重設選項",
|
||||
CreateFixupCommitTooltip: "為此提交建立修復提交",
|
||||
SquashAboveCommitsTooltip: "壓縮上方所有的“fixup!”提交 (自動壓縮)",
|
||||
SureSquashAboveCommits: "你確定要壓縮{{.commit}}上方所有的fixup!提交嗎?",
|
||||
CreateFixupCommit: "建立修復提交",
|
||||
SureCreateFixupCommit: "你確定要為提交{{.commit}}建立fixup!提交嗎?",
|
||||
ExecuteCustomCommand: "執行自訂命令",
|
||||
|
@ -33,9 +33,9 @@ var SquashFixupsAboveFirstCommit = NewIntegrationTest(NewIntegrationTestArgs{
|
||||
NavigateToLine(Contains("commit 01").DoesNotContain("fixup!")).
|
||||
Press(keys.Commits.SquashAboveCommits).
|
||||
Tap(func() {
|
||||
t.ExpectPopup().Confirmation().
|
||||
t.ExpectPopup().Menu().
|
||||
Title(Equals("Apply fixup commits")).
|
||||
Content(Contains("Are you sure you want to squash all fixup! commits above")).
|
||||
Select(Contains("Above the selected commit")).
|
||||
Confirm()
|
||||
}).
|
||||
Lines(
|
||||
|
@ -0,0 +1,55 @@
|
||||
package interactive_rebase
|
||||
|
||||
import (
|
||||
"github.com/jesseduffield/lazygit/pkg/config"
|
||||
. "github.com/jesseduffield/lazygit/pkg/integration/components"
|
||||
)
|
||||
|
||||
var SquashFixupsInCurrentBranch = NewIntegrationTest(NewIntegrationTestArgs{
|
||||
Description: "Squashes all fixups in the current branch.",
|
||||
ExtraCmdArgs: []string{},
|
||||
Skip: false,
|
||||
SetupConfig: func(config *config.AppConfig) {},
|
||||
SetupRepo: func(shell *Shell) {
|
||||
shell.
|
||||
CreateFileAndAdd("file1", "file1").
|
||||
Commit("master commit").
|
||||
NewBranch("branch").
|
||||
// Test the pathological case that the first commit of a branch is a
|
||||
// fixup for the last master commit below it. We _don't_ want this to
|
||||
// be squashed.
|
||||
UpdateFileAndAdd("file1", "changed file1").
|
||||
Commit("fixup! master commit").
|
||||
CreateNCommits(2).
|
||||
CreateFileAndAdd("fixup-file", "fixup content").
|
||||
Commit("fixup! commit 01")
|
||||
},
|
||||
Run: func(t *TestDriver, keys config.KeybindingConfig) {
|
||||
t.Views().Commits().
|
||||
Focus().
|
||||
Lines(
|
||||
Contains("fixup! commit 01"),
|
||||
Contains("commit 02"),
|
||||
Contains("commit 01"),
|
||||
Contains("fixup! master commit"),
|
||||
Contains("master commit"),
|
||||
).
|
||||
Press(keys.Commits.SquashAboveCommits).
|
||||
Tap(func() {
|
||||
t.ExpectPopup().Menu().
|
||||
Title(Equals("Apply fixup commits")).
|
||||
Select(Contains("In current branch")).
|
||||
Confirm()
|
||||
}).
|
||||
Lines(
|
||||
Contains("commit 02"),
|
||||
Contains("commit 01"),
|
||||
Contains("fixup! master commit"),
|
||||
Contains("master commit"),
|
||||
).
|
||||
NavigateToLine(Contains("commit 01"))
|
||||
|
||||
t.Views().Main().
|
||||
Content(Contains("fixup content"))
|
||||
},
|
||||
})
|
@ -183,6 +183,7 @@ var tests = []*components.IntegrationTest{
|
||||
interactive_rebase.SquashDownFirstCommit,
|
||||
interactive_rebase.SquashDownSecondCommit,
|
||||
interactive_rebase.SquashFixupsAboveFirstCommit,
|
||||
interactive_rebase.SquashFixupsInCurrentBranch,
|
||||
interactive_rebase.SwapInRebaseWithConflict,
|
||||
interactive_rebase.SwapInRebaseWithConflictAndEdit,
|
||||
interactive_rebase.SwapWithConflict,
|
||||
|
Loading…
Reference in New Issue
Block a user