Skip to content

Support fixup with keeping the message of the selected commit #4526

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions pkg/app/daemon/daemon.go
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ func (self *ChangeTodoActionsInstruction) run(common *common.Common) error {
return utils.TodoChange{
Hash: c.Hash,
NewAction: c.NewAction,
NewFlag: c.NewFlag,
}
})

Expand Down
1 change: 1 addition & 0 deletions pkg/app/daemon/rebase.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ func TodoLinesToString(todoLines []TodoLine) string {
type ChangeTodoAction struct {
Hash string
NewAction todo.TodoCommand
NewFlag string
}

func handleInteractiveRebase(common *common.Common, f func(path string) error) error {
Expand Down
10 changes: 6 additions & 4 deletions pkg/commands/git_commands/commit_loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,7 @@ func (self *CommitLoader) getHydratedTodoCommits(hashPool *utils.StringPool, tod
hydratedCommits = append(hydratedCommits, rebasingCommit)
} else if commit := findFullCommit(rebasingCommit.Hash()); commit != nil {
commit.Action = rebasingCommit.Action
commit.FixupFlag = rebasingCommit.FixupFlag
commit.Status = rebasingCommit.Status
hydratedCommits = append(hydratedCommits, commit)
}
Expand Down Expand Up @@ -366,10 +367,11 @@ func (self *CommitLoader) getRebasingCommits(hashPool *utils.StringPool, addConf
continue
}
commits = utils.Prepend(commits, models.NewCommit(hashPool, models.NewCommitOpts{
Hash: t.Commit,
Name: t.Msg,
Status: models.StatusRebasing,
Action: t.Command,
Hash: t.Commit,
Name: t.Msg,
Status: models.StatusRebasing,
Action: t.Command,
FixupFlag: t.Command == todo.Fixup && t.Flag == "-C",
}))
}

Expand Down
6 changes: 4 additions & 2 deletions pkg/commands/git_commands/rebase.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ func (self *RebaseCommands) MoveCommitsUp(commits []*models.Commit, startIdx int
}).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
if action == todo.Squash || action == todo.Fixup {
baseIndex++
Expand All @@ -149,6 +149,7 @@ func (self *RebaseCommands) InteractiveRebase(commits []*models.Commit, startIdx
return daemon.ChangeTodoAction{
Hash: commit.Hash(),
NewAction: action,
NewFlag: flag,
}, !commit.IsMerge()
})

Expand Down Expand Up @@ -331,11 +332,12 @@ func todoFromCommit(commit *models.Commit) utils.Todo {
}

// 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 {
return utils.TodoChange{
Hash: commit.Hash(),
NewAction: action,
NewFlag: flag,
}
})

Expand Down
3 changes: 3 additions & 0 deletions pkg/commands/models/commit.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ type Commit struct {

Status CommitStatus
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
}

Expand All @@ -64,6 +65,7 @@ type NewCommitOpts struct {
Name string
Status CommitStatus
Action todo.TodoCommand
FixupFlag bool
Tags []string
ExtraInfo string
AuthorName string
Expand All @@ -79,6 +81,7 @@ func NewCommit(hashPool *utils.StringPool, opts NewCommitOpts) *Commit {
Name: opts.Name,
Status: opts.Status,
Action: opts.Action,
FixupFlag: opts.FixupFlag,
Tags: opts.Tags,
ExtraInfo: opts.ExtraInfo,
AuthorName: opts.AuthorName,
Expand Down
61 changes: 37 additions & 24 deletions pkg/gui/controllers/local_commits_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ func secondaryPatchPanelUpdateOpts(c *ControllerCommon) *types.ViewUpdateOpts {

func (self *LocalCommitsController) squashDown(selectedCommits []*models.Commit, startIdx int, endIdx int) error {
if self.isRebasing() {
return self.updateTodos(todo.Squash, selectedCommits)
return self.updateTodos(todo.Squash, "", selectedCommits)
}

self.c.Confirm(types.ConfirmOpts{
Expand All @@ -323,7 +323,7 @@ func (self *LocalCommitsController) squashDown(selectedCommits []*models.Commit,
HandleConfirm: func() error {
return self.c.WithWaitingStatus(self.c.Tr.SquashingStatus, func(gocui.Task) error {
self.c.LogAction(self.c.Tr.Actions.SquashCommitDown)
return self.interactiveRebase(todo.Squash, startIdx, endIdx)
return self.interactiveRebase(todo.Squash, "", startIdx, endIdx)
})
},
})
Expand All @@ -332,22 +332,35 @@ func (self *LocalCommitsController) squashDown(selectedCommits []*models.Commit,
}

func (self *LocalCommitsController) fixup(selectedCommits []*models.Commit, startIdx int, endIdx int) error {
if self.isRebasing() {
return self.updateTodos(todo.Fixup, selectedCommits)
f := func(flag string) error {
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,
Prompt: self.c.Tr.SureFixupThisCommit,
HandleConfirm: 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)
})
Prompt: "This squashes the selected commit(s) into the commit below it. You can decide which commit message to keep:",
Items: []*types.MenuItem{
{
Label: "Keep the message of the commit below",
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 {
Expand Down Expand Up @@ -477,14 +490,14 @@ func (self *LocalCommitsController) drop(selectedCommits []*models.Commit, start

self.context().SetSelectionRangeAndMode(selectedIdx, rangeStartIdx, rangeSelectMode)

return self.updateTodos(todo.Drop, nonUpdateRefTodos)
return self.updateTodos(todo.Drop, "", nonUpdateRefTodos)
},
})

return nil
}

return self.updateTodos(todo.Drop, selectedCommits)
return self.updateTodos(todo.Drop, "", selectedCommits)
}

isMerge := selectedCommits[0].IsMerge()
Expand All @@ -498,7 +511,7 @@ func (self *LocalCommitsController) drop(selectedCommits []*models.Commit, start
if isMerge {
return self.dropMergeCommit(startIdx)
}
return self.interactiveRebase(todo.Drop, startIdx, endIdx)
return self.interactiveRebase(todo.Drop, "", startIdx, endIdx)
})
},
})
Expand All @@ -513,13 +526,13 @@ func (self *LocalCommitsController) dropMergeCommit(commitIdx int) error {

func (self *LocalCommitsController) edit(selectedCommits []*models.Commit, startIdx int, endIdx int) error {
if self.isRebasing() {
return self.updateTodos(todo.Edit, selectedCommits)
return self.updateTodos(todo.Edit, "", selectedCommits)
}

commits := self.c.Model().Commits
if !commits[endIdx].IsMerge() {
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(
err,
types.RefreshOptions{
Expand Down Expand Up @@ -560,7 +573,7 @@ func (self *LocalCommitsController) startInteractiveRebaseWithEdit(
}
}
if len(todos) > 0 {
err := self.updateTodos(todo.Edit, todos)
err := self.updateTodos(todo.Edit, "", todos)
if err != nil {
return err
}
Expand Down Expand Up @@ -620,31 +633,31 @@ func (self *LocalCommitsController) findCommitForQuickStartInteractiveRebase() (

func (self *LocalCommitsController) pick(selectedCommits []*models.Commit) error {
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
// attempt to pull. We might revoke this later after enabling configurable keybindings
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
// 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 {
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)
}

// updateTodos sees if the selected commit is in fact a rebasing
// 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
func (self *LocalCommitsController) updateTodos(action todo.TodoCommand, selectedCommits []*models.Commit) error {
if err := self.c.Git().Rebase.EditRebaseTodo(selectedCommits, action); err != nil {
func (self *LocalCommitsController) updateTodos(action todo.TodoCommand, flag string, selectedCommits []*models.Commit) error {
if err := self.c.Git().Rebase.EditRebaseTodo(selectedCommits, action, flag); err != nil {
return err
}

Expand Down
10 changes: 9 additions & 1 deletion pkg/gui/presentation/commits.go
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,15 @@ func displayCommit(

actionString := ""
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 := ""
Expand Down
2 changes: 0 additions & 2 deletions pkg/i18n/english.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,6 @@ type TranslationSet struct {
CannotSquashOrFixupMergeCommit string
Fixup string
FixupTooltip string
SureFixupThisCommit string
SureSquashThisCommit string
Squash string
SquashMerge string
Expand Down Expand Up @@ -1255,7 +1254,6 @@ func EnglishTranslationSet() *TranslationSet {
CannotSquashOrFixupFirstCommit: "There's no commit below to squash into",
CannotSquashOrFixupMergeCommit: "Cannot squash or fixup a merge commit",
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?",
Squash: "Squash",
SquashMerge: "Squash Merge",
Expand Down
2 changes: 2 additions & 0 deletions pkg/utils/rebase_todo.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ type Todo struct {
type TodoChange struct {
Hash string
NewAction todo.TodoCommand
NewFlag string
}

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