Skip to content

Commit

Permalink
Support range select in rebase actions
Browse files Browse the repository at this point in the history
  • Loading branch information
jesseduffield committed Jan 23, 2024
1 parent 44e2542 commit f0de880
Show file tree
Hide file tree
Showing 26 changed files with 773 additions and 363 deletions.
74 changes: 45 additions & 29 deletions pkg/app/daemon/daemon.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ const (

DaemonKindExitImmediately
DaemonKindCherryPick
DaemonKindMoveTodoUp
DaemonKindMoveTodoDown
DaemonKindMoveTodosUp
DaemonKindMoveTodosDown
DaemonKindInsertBreak
DaemonKindChangeTodoActions
DaemonKindMoveFixupCommitDown
Expand All @@ -56,8 +56,8 @@ func getInstruction() Instruction {
DaemonKindCherryPick: deserializeInstruction[*CherryPickCommitsInstruction],
DaemonKindChangeTodoActions: deserializeInstruction[*ChangeTodoActionsInstruction],
DaemonKindMoveFixupCommitDown: deserializeInstruction[*MoveFixupCommitDownInstruction],
DaemonKindMoveTodoUp: deserializeInstruction[*MoveTodoUpInstruction],
DaemonKindMoveTodoDown: deserializeInstruction[*MoveTodoDownInstruction],
DaemonKindMoveTodosUp: deserializeInstruction[*MoveTodosUpInstruction],
DaemonKindMoveTodosDown: deserializeInstruction[*MoveTodosDownInstruction],
DaemonKindInsertBreak: deserializeInstruction[*InsertBreakInstruction],
}

Expand Down Expand Up @@ -208,13 +208,15 @@ func (self *ChangeTodoActionsInstruction) SerializedInstructions() string {

func (self *ChangeTodoActionsInstruction) run(common *common.Common) error {
return handleInteractiveRebase(common, func(path string) error {
for _, c := range self.Changes {
if err := utils.EditRebaseTodo(path, c.Sha, todo.Pick, c.NewAction, getCommentChar()); err != nil {
return err
changes := lo.Map(self.Changes, func(c ChangeTodoAction, _ int) utils.TodoChange {
return utils.TodoChange{
Sha: c.Sha,
OldAction: todo.Pick,
NewAction: c.NewAction,
}
}
})

return nil
return utils.EditRebaseTodo(path, changes, getCommentChar())
})
}

Expand Down Expand Up @@ -247,51 +249,65 @@ func (self *MoveFixupCommitDownInstruction) run(common *common.Common) error {
})
}

type MoveTodoUpInstruction struct {
Sha string
type MoveTodosUpInstruction struct {
Shas []string
}

func NewMoveTodoUpInstruction(sha string) Instruction {
return &MoveTodoUpInstruction{
Sha: sha,
func NewMoveTodosUpInstruction(shas []string) Instruction {
return &MoveTodosUpInstruction{
Shas: shas,
}
}

func (self *MoveTodoUpInstruction) Kind() DaemonKind {
return DaemonKindMoveTodoUp
func (self *MoveTodosUpInstruction) Kind() DaemonKind {
return DaemonKindMoveTodosUp
}

func (self *MoveTodoUpInstruction) SerializedInstructions() string {
func (self *MoveTodosUpInstruction) SerializedInstructions() string {
return serializeInstruction(self)
}

func (self *MoveTodoUpInstruction) run(common *common.Common) error {
func (self *MoveTodosUpInstruction) run(common *common.Common) error {
todosToMove := lo.Map(self.Shas, func(sha string, _ int) utils.Todo {
return utils.Todo{
Sha: sha,
Action: todo.Pick,
}
})

return handleInteractiveRebase(common, func(path string) error {
return utils.MoveTodoUp(path, self.Sha, todo.Pick, getCommentChar())
return utils.MoveTodosUp(path, todosToMove, getCommentChar())
})
}

type MoveTodoDownInstruction struct {
Sha string
type MoveTodosDownInstruction struct {
Shas []string
}

func NewMoveTodoDownInstruction(sha string) Instruction {
return &MoveTodoDownInstruction{
Sha: sha,
func NewMoveTodosDownInstruction(shas []string) Instruction {
return &MoveTodosDownInstruction{
Shas: shas,
}
}

func (self *MoveTodoDownInstruction) Kind() DaemonKind {
return DaemonKindMoveTodoDown
func (self *MoveTodosDownInstruction) Kind() DaemonKind {
return DaemonKindMoveTodosDown
}

func (self *MoveTodoDownInstruction) SerializedInstructions() string {
func (self *MoveTodosDownInstruction) SerializedInstructions() string {
return serializeInstruction(self)
}

func (self *MoveTodoDownInstruction) run(common *common.Common) error {
func (self *MoveTodosDownInstruction) run(common *common.Common) error {
todosToMove := lo.Map(self.Shas, func(sha string, _ int) utils.Todo {
return utils.Todo{
Sha: sha,
Action: todo.Pick,
}
})

return handleInteractiveRebase(common, func(path string) error {
return utils.MoveTodoDown(path, self.Sha, todo.Pick, getCommentChar())
return utils.MoveTodosDown(path, todosToMove, getCommentChar())
})
}

Expand Down
94 changes: 54 additions & 40 deletions pkg/commands/git_commands/rebase.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,58 +105,49 @@ func (self *RebaseCommands) GenericAmend(commits []*models.Commit, index int, f
return self.ContinueRebase()
}

func (self *RebaseCommands) MoveCommitDown(commits []*models.Commit, index int) error {
baseShaOrRoot := getBaseShaOrRoot(commits, index+2)
func (self *RebaseCommands) MoveCommitsDown(commits []*models.Commit, startIdx int, endIdx int) error {
baseShaOrRoot := getBaseShaOrRoot(commits, endIdx+2)

sha := commits[index].Sha

msg := utils.ResolvePlaceholderString(
self.Tr.Log.MoveCommitDown,
map[string]string{
"shortSha": utils.ShortSha(sha),
},
)
self.os.LogCommand(msg, false)
shas := lo.Map(commits[startIdx:endIdx+1], func(commit *models.Commit, _ int) string {
return commit.Sha
})

return self.PrepareInteractiveRebaseCommand(PrepareInteractiveRebaseCommandOpts{
baseShaOrRoot: baseShaOrRoot,
instruction: daemon.NewMoveTodoDownInstruction(sha),
instruction: daemon.NewMoveTodosDownInstruction(shas),
overrideEditor: true,
}).Run()
}

func (self *RebaseCommands) MoveCommitUp(commits []*models.Commit, index int) error {
baseShaOrRoot := getBaseShaOrRoot(commits, index+1)

sha := commits[index].Sha
func (self *RebaseCommands) MoveCommitsUp(commits []*models.Commit, startIdx int, endIdx int) error {
baseShaOrRoot := getBaseShaOrRoot(commits, endIdx+1)

msg := utils.ResolvePlaceholderString(
self.Tr.Log.MoveCommitUp,
map[string]string{
"shortSha": utils.ShortSha(sha),
},
)
self.os.LogCommand(msg, false)
shas := lo.Map(commits[startIdx:endIdx+1], func(commit *models.Commit, _ int) string {
return commit.Sha
})

return self.PrepareInteractiveRebaseCommand(PrepareInteractiveRebaseCommandOpts{
baseShaOrRoot: baseShaOrRoot,
instruction: daemon.NewMoveTodoUpInstruction(sha),
instruction: daemon.NewMoveTodosUpInstruction(shas),
overrideEditor: true,
}).Run()
}

func (self *RebaseCommands) InteractiveRebase(commits []*models.Commit, index int, action todo.TodoCommand) error {
baseIndex := index + 1
func (self *RebaseCommands) InteractiveRebase(commits []*models.Commit, startIdx int, endIdx int, action todo.TodoCommand) error {
baseIndex := endIdx + 1
if action == todo.Squash || action == todo.Fixup {
baseIndex++
}

baseShaOrRoot := getBaseShaOrRoot(commits, baseIndex)

changes := []daemon.ChangeTodoAction{{
Sha: commits[index].Sha,
NewAction: action,
}}
changes := lo.Map(commits[startIdx:endIdx+1], func(commit *models.Commit, _ int) daemon.ChangeTodoAction {
return daemon.ChangeTodoAction{
Sha: commit.Sha,
NewAction: action,
}
})

self.os.LogCommand(logTodoChanges(changes), false)

return self.PrepareInteractiveRebaseCommand(PrepareInteractiveRebaseCommandOpts{
Expand Down Expand Up @@ -200,7 +191,7 @@ func logTodoChanges(changes []daemon.ChangeTodoAction) string {
changeTodoStr := strings.Join(lo.Map(changes, func(c daemon.ChangeTodoAction, _ int) string {
return fmt.Sprintf("%s:%s", c.Sha, c.NewAction)
}), "\n")
return fmt.Sprintf("Changing TODO actions: %s", changeTodoStr)
return fmt.Sprintf("Changing TODO actions:\n%s", changeTodoStr)
}

type PrepareInteractiveRebaseCommandOpts struct {
Expand Down Expand Up @@ -281,22 +272,45 @@ func (self *RebaseCommands) AmendTo(commits []*models.Commit, commitIndex int) e
}).Run()
}

// EditRebaseTodo sets the action for a given rebase commit in the git-rebase-todo file
func (self *RebaseCommands) EditRebaseTodo(commit *models.Commit, action todo.TodoCommand) error {
// Sets the action for the given commits in the git-rebase-todo file
func (self *RebaseCommands) EditRebaseTodo(commits []*models.Commit, action todo.TodoCommand) error {
commitsWithAction := lo.Map(commits, func(commit *models.Commit, _ int) utils.TodoChange {
return utils.TodoChange{
Sha: commit.Sha,
OldAction: commit.Action,
NewAction: action,
}
})

return utils.EditRebaseTodo(
filepath.Join(self.repoPaths.WorktreeGitDirPath(), "rebase-merge/git-rebase-todo"), commit.Sha, commit.Action, action, self.config.GetCoreCommentChar())
filepath.Join(self.repoPaths.WorktreeGitDirPath(), "rebase-merge/git-rebase-todo"),
commitsWithAction,
self.config.GetCoreCommentChar(),
)
}

// MoveTodoDown moves a rebase todo item down by one position
func (self *RebaseCommands) MoveTodoDown(commit *models.Commit) error {
func (self *RebaseCommands) MoveTodosDown(commits []*models.Commit) error {
fileName := filepath.Join(self.repoPaths.WorktreeGitDirPath(), "rebase-merge/git-rebase-todo")
return utils.MoveTodoDown(fileName, commit.Sha, commit.Action, self.config.GetCoreCommentChar())
todosToMove := lo.Map(commits, func(commit *models.Commit, _ int) utils.Todo {
return utils.Todo{
Sha: commit.Sha,
Action: commit.Action,
}
})

return utils.MoveTodosDown(fileName, todosToMove, self.config.GetCoreCommentChar())
}

// MoveTodoDown moves a rebase todo item down by one position
func (self *RebaseCommands) MoveTodoUp(commit *models.Commit) error {
func (self *RebaseCommands) MoveTodosUp(commits []*models.Commit) error {
fileName := filepath.Join(self.repoPaths.WorktreeGitDirPath(), "rebase-merge/git-rebase-todo")
return utils.MoveTodoUp(fileName, commit.Sha, commit.Action, self.config.GetCoreCommentChar())
todosToMove := lo.Map(commits, func(commit *models.Commit, _ int) utils.Todo {
return utils.Todo{
Sha: commit.Sha,
Action: commit.Action,
}
})

return utils.MoveTodosUp(fileName, todosToMove, self.config.GetCoreCommentChar())
}

// SquashAllAboveFixupCommits squashes all fixup! commits above the given one
Expand Down
15 changes: 15 additions & 0 deletions pkg/gui/controllers/helpers/merge_and_rebase_helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package helpers

import (
"fmt"
"os"
"path/filepath"
"strings"

"github.com/jesseduffield/gocui"
Expand Down Expand Up @@ -80,6 +82,19 @@ func (self *MergeAndRebaseHelper) genericMergeCommand(command string) error {
}

self.c.LogAction(fmt.Sprintf("Merge/Rebase: %s", command))
if status == enums.REBASE_MODE_REBASING {
todoFile, err := os.ReadFile(
filepath.Join(self.c.Git().RepoPaths.WorktreeGitDirPath(), "rebase-merge/git-rebase-todo"),
)

if err != nil {
if !os.IsNotExist(err) {
return err
}
} else {
self.c.LogCommand(string(todoFile), false)
}
}

commandType := ""
switch status {
Expand Down
Loading

0 comments on commit f0de880

Please sign in to comment.