This commit is contained in:
Stefan Haller 2025-05-10 15:10:17 +06:00 committed by GitHub
commit ee6160da8a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 63 additions and 33 deletions

View file

@ -201,6 +201,7 @@ func (self *ChangeTodoActionsInstruction) run(common *common.Common) error {
return utils.TodoChange{ return utils.TodoChange{
Hash: c.Hash, Hash: c.Hash,
NewAction: c.NewAction, NewAction: c.NewAction,
NewFlag: c.NewFlag,
} }
}) })

View file

@ -37,6 +37,7 @@ func TodoLinesToString(todoLines []TodoLine) string {
type ChangeTodoAction struct { type ChangeTodoAction struct {
Hash string Hash string
NewAction todo.TodoCommand NewAction todo.TodoCommand
NewFlag string
} }
func handleInteractiveRebase(common *common.Common, f func(path string) error) error { func handleInteractiveRebase(common *common.Common, f func(path string) error) error {

View file

@ -320,6 +320,7 @@ func (self *CommitLoader) getHydratedTodoCommits(hashPool *utils.StringPool, tod
hydratedCommits = append(hydratedCommits, rebasingCommit) hydratedCommits = append(hydratedCommits, rebasingCommit)
} else if commit := findFullCommit(rebasingCommit.Hash()); commit != nil { } else if commit := findFullCommit(rebasingCommit.Hash()); commit != nil {
commit.Action = rebasingCommit.Action commit.Action = rebasingCommit.Action
commit.FixupFlag = rebasingCommit.FixupFlag
commit.Status = rebasingCommit.Status commit.Status = rebasingCommit.Status
hydratedCommits = append(hydratedCommits, commit) hydratedCommits = append(hydratedCommits, commit)
} }
@ -366,10 +367,11 @@ func (self *CommitLoader) getRebasingCommits(hashPool *utils.StringPool, addConf
continue continue
} }
commits = utils.Prepend(commits, models.NewCommit(hashPool, models.NewCommitOpts{ commits = utils.Prepend(commits, models.NewCommit(hashPool, models.NewCommitOpts{
Hash: t.Commit, Hash: t.Commit,
Name: t.Msg, Name: t.Msg,
Status: models.StatusRebasing, Status: models.StatusRebasing,
Action: t.Command, Action: t.Command,
FixupFlag: t.Command == todo.Fixup && t.Flag == "-C",
})) }))
} }

View file

@ -137,7 +137,7 @@ func (self *RebaseCommands) MoveCommitsUp(commits []*models.Commit, startIdx int
}).Run() }).Run()
} }
func (self *RebaseCommands) InteractiveRebase(commits []*models.Commit, startIdx int, endIdx int, action todo.TodoCommand) error { func (self *RebaseCommands) InteractiveRebase(commits []*models.Commit, startIdx int, endIdx int, action todo.TodoCommand, flag string) error {
baseIndex := endIdx + 1 baseIndex := endIdx + 1
if action == todo.Squash || action == todo.Fixup { if action == todo.Squash || action == todo.Fixup {
baseIndex++ baseIndex++
@ -149,6 +149,7 @@ func (self *RebaseCommands) InteractiveRebase(commits []*models.Commit, startIdx
return daemon.ChangeTodoAction{ return daemon.ChangeTodoAction{
Hash: commit.Hash(), Hash: commit.Hash(),
NewAction: action, NewAction: action,
NewFlag: flag,
}, !commit.IsMerge() }, !commit.IsMerge()
}) })
@ -331,11 +332,12 @@ func todoFromCommit(commit *models.Commit) utils.Todo {
} }
// Sets the action for the given commits in the git-rebase-todo file // Sets the action for the given commits in the git-rebase-todo file
func (self *RebaseCommands) EditRebaseTodo(commits []*models.Commit, action todo.TodoCommand) error { func (self *RebaseCommands) EditRebaseTodo(commits []*models.Commit, action todo.TodoCommand, flag string) error {
commitsWithAction := lo.Map(commits, func(commit *models.Commit, _ int) utils.TodoChange { commitsWithAction := lo.Map(commits, func(commit *models.Commit, _ int) utils.TodoChange {
return utils.TodoChange{ return utils.TodoChange{
Hash: commit.Hash(), Hash: commit.Hash(),
NewAction: action, NewAction: action,
NewFlag: flag,
} }
}) })

View file

@ -56,6 +56,7 @@ type Commit struct {
Status CommitStatus Status CommitStatus
Action todo.TodoCommand Action todo.TodoCommand
FixupFlag bool // Only used for todo.Fixup action: true if the `-C` flag is set
Divergence Divergence // set to DivergenceNone unless we are showing the divergence view Divergence Divergence // set to DivergenceNone unless we are showing the divergence view
} }
@ -64,6 +65,7 @@ type NewCommitOpts struct {
Name string Name string
Status CommitStatus Status CommitStatus
Action todo.TodoCommand Action todo.TodoCommand
FixupFlag bool
Tags []string Tags []string
ExtraInfo string ExtraInfo string
AuthorName string AuthorName string
@ -79,6 +81,7 @@ func NewCommit(hashPool *utils.StringPool, opts NewCommitOpts) *Commit {
Name: opts.Name, Name: opts.Name,
Status: opts.Status, Status: opts.Status,
Action: opts.Action, Action: opts.Action,
FixupFlag: opts.FixupFlag,
Tags: opts.Tags, Tags: opts.Tags,
ExtraInfo: opts.ExtraInfo, ExtraInfo: opts.ExtraInfo,
AuthorName: opts.AuthorName, AuthorName: opts.AuthorName,

View file

@ -322,7 +322,7 @@ func secondaryPatchPanelUpdateOpts(c *ControllerCommon) *types.ViewUpdateOpts {
func (self *LocalCommitsController) squashDown(selectedCommits []*models.Commit, startIdx int, endIdx int) error { func (self *LocalCommitsController) squashDown(selectedCommits []*models.Commit, startIdx int, endIdx int) error {
if self.isRebasing() { if self.isRebasing() {
return self.updateTodos(todo.Squash, selectedCommits) return self.updateTodos(todo.Squash, "", selectedCommits)
} }
self.c.Confirm(types.ConfirmOpts{ self.c.Confirm(types.ConfirmOpts{
@ -331,7 +331,7 @@ func (self *LocalCommitsController) squashDown(selectedCommits []*models.Commit,
HandleConfirm: func() error { HandleConfirm: func() error {
return self.c.WithWaitingStatus(self.c.Tr.SquashingStatus, func(gocui.Task) error { return self.c.WithWaitingStatus(self.c.Tr.SquashingStatus, func(gocui.Task) error {
self.c.LogAction(self.c.Tr.Actions.SquashCommitDown) self.c.LogAction(self.c.Tr.Actions.SquashCommitDown)
return self.interactiveRebase(todo.Squash, startIdx, endIdx) return self.interactiveRebase(todo.Squash, "", startIdx, endIdx)
}) })
}, },
}) })
@ -340,22 +340,35 @@ func (self *LocalCommitsController) squashDown(selectedCommits []*models.Commit,
} }
func (self *LocalCommitsController) fixup(selectedCommits []*models.Commit, startIdx int, endIdx int) error { func (self *LocalCommitsController) fixup(selectedCommits []*models.Commit, startIdx int, endIdx int) error {
if self.isRebasing() { f := func(flag string) error {
return self.updateTodos(todo.Fixup, selectedCommits) if self.isRebasing() {
return self.updateTodos(todo.Fixup, flag, selectedCommits)
}
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, flag, startIdx, endIdx)
})
} }
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, Prompt: "This squashes the selected commit(s) into the commit below it. You can decide which commit message to keep:",
HandleConfirm: func() error { Items: []*types.MenuItem{
return self.c.WithWaitingStatus(self.c.Tr.FixingStatus, func(gocui.Task) error { {
self.c.LogAction(self.c.Tr.Actions.FixupCommit) Label: "Keep the message of the commit below",
return self.interactiveRebase(todo.Fixup, startIdx, endIdx) OnPress: func() error {
}) return f("")
},
},
{
Label: "Keep the message of the first selected commit",
OnPress: func() error {
return f("-C")
},
},
}, },
}) })
return nil
} }
func (self *LocalCommitsController) reword(commit *models.Commit) error { func (self *LocalCommitsController) reword(commit *models.Commit) error {
@ -485,14 +498,14 @@ func (self *LocalCommitsController) drop(selectedCommits []*models.Commit, start
self.context().SetSelectionRangeAndMode(selectedIdx, rangeStartIdx, rangeSelectMode) self.context().SetSelectionRangeAndMode(selectedIdx, rangeStartIdx, rangeSelectMode)
return self.updateTodos(todo.Drop, nonUpdateRefTodos) return self.updateTodos(todo.Drop, "", nonUpdateRefTodos)
}, },
}) })
return nil return nil
} }
return self.updateTodos(todo.Drop, selectedCommits) return self.updateTodos(todo.Drop, "", selectedCommits)
} }
isMerge := selectedCommits[0].IsMerge() isMerge := selectedCommits[0].IsMerge()
@ -506,7 +519,7 @@ func (self *LocalCommitsController) drop(selectedCommits []*models.Commit, start
if isMerge { if isMerge {
return self.dropMergeCommit(startIdx) return self.dropMergeCommit(startIdx)
} }
return self.interactiveRebase(todo.Drop, startIdx, endIdx) return self.interactiveRebase(todo.Drop, "", startIdx, endIdx)
}) })
}, },
}) })
@ -521,13 +534,13 @@ func (self *LocalCommitsController) dropMergeCommit(commitIdx int) error {
func (self *LocalCommitsController) edit(selectedCommits []*models.Commit, startIdx int, endIdx int) error { func (self *LocalCommitsController) edit(selectedCommits []*models.Commit, startIdx int, endIdx int) error {
if self.isRebasing() { if self.isRebasing() {
return self.updateTodos(todo.Edit, selectedCommits) return self.updateTodos(todo.Edit, "", selectedCommits)
} }
commits := self.c.Model().Commits commits := self.c.Model().Commits
if !commits[endIdx].IsMerge() { if !commits[endIdx].IsMerge() {
selectionRangeAndMode := self.getSelectionRangeAndMode() selectionRangeAndMode := self.getSelectionRangeAndMode()
err := self.c.Git().Rebase.InteractiveRebase(commits, startIdx, endIdx, todo.Edit) err := self.c.Git().Rebase.InteractiveRebase(commits, startIdx, endIdx, todo.Edit, "")
return self.c.Helpers().MergeAndRebase.CheckMergeOrRebaseWithRefreshOptions( return self.c.Helpers().MergeAndRebase.CheckMergeOrRebaseWithRefreshOptions(
err, err,
types.RefreshOptions{ types.RefreshOptions{
@ -568,7 +581,7 @@ func (self *LocalCommitsController) startInteractiveRebaseWithEdit(
} }
} }
if len(todos) > 0 { if len(todos) > 0 {
err := self.updateTodos(todo.Edit, todos) err := self.updateTodos(todo.Edit, "", todos)
if err != nil { if err != nil {
return err return err
} }
@ -628,7 +641,7 @@ func (self *LocalCommitsController) findCommitForQuickStartInteractiveRebase() (
func (self *LocalCommitsController) pick(selectedCommits []*models.Commit) error { func (self *LocalCommitsController) pick(selectedCommits []*models.Commit) error {
if self.isRebasing() { if self.isRebasing() {
return self.updateTodos(todo.Pick, selectedCommits) return self.updateTodos(todo.Pick, "", selectedCommits)
} }
// at this point we aren't actually rebasing so we will interpret this as an // at this point we aren't actually rebasing so we will interpret this as an
@ -636,14 +649,14 @@ func (self *LocalCommitsController) pick(selectedCommits []*models.Commit) error
return self.pullFiles() return self.pullFiles()
} }
func (self *LocalCommitsController) interactiveRebase(action todo.TodoCommand, startIdx int, endIdx int) error { func (self *LocalCommitsController) interactiveRebase(action todo.TodoCommand, flag string, startIdx int, endIdx int) error {
// When performing an action that will remove the selected commits, we need to select the // When performing an action that will remove the selected commits, we need to select the
// next commit down (which will end up at the start index after the action is performed) // next commit down (which will end up at the start index after the action is performed)
if action == todo.Drop || action == todo.Fixup || action == todo.Squash { if action == todo.Drop || action == todo.Fixup || action == todo.Squash {
self.context().SetSelection(startIdx) self.context().SetSelection(startIdx)
} }
err := self.c.Git().Rebase.InteractiveRebase(self.c.Model().Commits, startIdx, endIdx, action) err := self.c.Git().Rebase.InteractiveRebase(self.c.Model().Commits, startIdx, endIdx, action, flag)
return self.c.Helpers().MergeAndRebase.CheckMergeOrRebase(err) return self.c.Helpers().MergeAndRebase.CheckMergeOrRebase(err)
} }
@ -651,8 +664,8 @@ func (self *LocalCommitsController) interactiveRebase(action todo.TodoCommand, s
// updateTodos sees if the selected commit is in fact a rebasing // updateTodos sees if the selected commit is in fact a rebasing
// commit meaning you are trying to edit the todo file rather than actually // commit meaning you are trying to edit the todo file rather than actually
// begin a rebase. It then updates the todo file with that action // begin a rebase. It then updates the todo file with that action
func (self *LocalCommitsController) updateTodos(action todo.TodoCommand, selectedCommits []*models.Commit) error { func (self *LocalCommitsController) updateTodos(action todo.TodoCommand, flag string, selectedCommits []*models.Commit) error {
if err := self.c.Git().Rebase.EditRebaseTodo(selectedCommits, action); err != nil { if err := self.c.Git().Rebase.EditRebaseTodo(selectedCommits, action, flag); err != nil {
return err return err
} }

View file

@ -387,7 +387,15 @@ func displayCommit(
actionString := "" actionString := ""
if commit.Action != models.ActionNone { if commit.Action != models.ActionNone {
actionString = actionColorMap(commit.Action, commit.Status).Sprint(commit.Action.String()) actionName := commit.Action.String()
if commit.Action == todo.Fixup {
if commit.FixupFlag {
actionName += "←"
} else {
actionName += "↓"
}
}
actionString = actionColorMap(commit.Action, commit.Status).Sprint(actionName)
} }
tagString := "" tagString := ""

View file

@ -172,7 +172,6 @@ type TranslationSet struct {
CannotSquashOrFixupMergeCommit string CannotSquashOrFixupMergeCommit string
Fixup string Fixup string
FixupTooltip string FixupTooltip string
SureFixupThisCommit string
SureSquashThisCommit string SureSquashThisCommit string
Squash string Squash string
SquashMerge string SquashMerge string
@ -1252,7 +1251,6 @@ 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?",
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",
SquashMerge: "Squash Merge", SquashMerge: "Squash Merge",

View file

@ -19,6 +19,7 @@ type Todo struct {
type TodoChange struct { type TodoChange struct {
Hash string Hash string
NewAction todo.TodoCommand NewAction todo.TodoCommand
NewFlag string
} }
// Read a git-rebase-todo file, change the actions for the given commits, // Read a git-rebase-todo file, change the actions for the given commits,
@ -37,6 +38,7 @@ func EditRebaseTodo(filePath string, changes []TodoChange, commentChar byte) err
if equalHash(t.Commit, change.Hash) { if equalHash(t.Commit, change.Hash) {
matchCount++ matchCount++
t.Command = change.NewAction t.Command = change.NewAction
t.Flag = change.NewFlag
} }
} }
} }