summaryrefslogtreecommitdiffstats
path: root/pkg/commands
diff options
context:
space:
mode:
authorStefan Haller <stefan@haller-berlin.de>2023-04-05 19:01:49 +0200
committerStefan Haller <stefan@haller-berlin.de>2023-04-29 07:28:33 +0200
commitb8fbe9756e5b2ad22b39fe7d0b8e40d88b15df84 (patch)
treeaa01199f7a3c0cd3d41f179ac2e79bac88007c82 /pkg/commands
parentab25600ccbbc9b8880289c496f521710894e26cc (diff)
Implement squash, fixup, drop, and reword in terms of daemon
Diffstat (limited to 'pkg/commands')
-rw-r--r--pkg/commands/git_commands/rebase.go101
1 files changed, 47 insertions, 54 deletions
diff --git a/pkg/commands/git_commands/rebase.go b/pkg/commands/git_commands/rebase.go
index 31eaf1366..338917626 100644
--- a/pkg/commands/git_commands/rebase.go
+++ b/pkg/commands/git_commands/rebase.go
@@ -55,14 +55,14 @@ func (self *RebaseCommands) RewordCommit(commits []*models.Commit, index int, me
}
func (self *RebaseCommands) RewordCommitInEditor(commits []*models.Commit, index int) (oscommands.ICmdObj, error) {
- todo, sha, err := self.BuildSingleActionTodo(commits, index, "reword")
- if err != nil {
- return nil, err
- }
-
return self.PrepareInteractiveRebaseCommand(PrepareInteractiveRebaseCommandOpts{
- baseShaOrRoot: sha,
- todoLines: todo,
+ baseShaOrRoot: getBaseShaOrRoot(commits, index+1),
+ changeTodoActions: []ChangeTodoAction{
+ {
+ sha: commits[index].Sha,
+ newAction: todo.Reword,
+ },
+ },
}), nil
}
@@ -114,16 +114,21 @@ func (self *RebaseCommands) MoveCommitDown(commits []*models.Commit, index int)
}).Run()
}
-func (self *RebaseCommands) InteractiveRebase(commits []*models.Commit, index int, action string) error {
- todo, sha, err := self.BuildSingleActionTodo(commits, index, action)
- if err != nil {
- return err
+func (self *RebaseCommands) InteractiveRebase(commits []*models.Commit, index int, action todo.TodoCommand) error {
+ baseIndex := index + 1
+ if action == todo.Squash || action == todo.Fixup {
+ baseIndex++
}
+ baseShaOrRoot := getBaseShaOrRoot(commits, baseIndex)
+
return self.PrepareInteractiveRebaseCommand(PrepareInteractiveRebaseCommandOpts{
- baseShaOrRoot: sha,
- todoLines: todo,
+ baseShaOrRoot: baseShaOrRoot,
overrideEditor: true,
+ changeTodoActions: []ChangeTodoAction{{
+ sha: commits[index].Sha,
+ newAction: action,
+ }},
}).Run()
}
@@ -136,11 +141,17 @@ func (self *RebaseCommands) EditRebase(branchRef string) error {
}).Run()
}
+type ChangeTodoAction struct {
+ sha string
+ newAction todo.TodoCommand
+}
+
type PrepareInteractiveRebaseCommandOpts struct {
- baseShaOrRoot string
- todoLines []TodoLine
- overrideEditor bool
- prepend bool
+ baseShaOrRoot string
+ todoLines []TodoLine
+ overrideEditor bool
+ prepend bool
+ changeTodoActions []ChangeTodoAction
}
// PrepareInteractiveRebaseCommand returns the cmd for an interactive rebase
@@ -159,6 +170,14 @@ func (self *RebaseCommands) PrepareInteractiveRebaseCommand(opts PrepareInteract
debug = "TRUE"
}
+ changeTodoValue := strings.Join(slices.Map(opts.changeTodoActions, func(c ChangeTodoAction) string {
+ return fmt.Sprintf("%s:%s", c.sha, c.newAction)
+ }), "\n")
+
+ if todo != "" && changeTodoValue != "" {
+ panic("It's not allowed to pass both todoLines and changeActionOpts")
+ }
+
rebaseMergesArg := " --rebase-merges"
if self.version.IsOlderThan(2, 22, 0) {
rebaseMergesArg = ""
@@ -170,16 +189,19 @@ func (self *RebaseCommands) PrepareInteractiveRebaseCommand(opts PrepareInteract
cmdObj := self.cmd.New(cmdStr)
gitSequenceEditor := ex
- if todo == "" {
- gitSequenceEditor = "true"
- } else {
+ if todo != "" {
self.os.LogCommand(fmt.Sprintf("Creating TODO file for interactive rebase: \n\n%s", todo), false)
+ } else if changeTodoValue != "" {
+ self.os.LogCommand(fmt.Sprintf("Changing TODO action: %s", changeTodoValue), false)
+ } else {
+ gitSequenceEditor = "true"
}
cmdObj.AddEnvVars(
daemon.DaemonKindEnvKey+"="+string(daemon.InteractiveRebase),
daemon.RebaseTODOEnvKey+"="+todo,
daemon.PrependLinesEnvKey+"="+prependLines,
+ daemon.ChangeTodoActionEnvKey+"="+changeTodoValue,
"DEBUG="+debug,
"LANG=en_US.UTF-8", // Force using EN as language
"LC_ALL=en_US.UTF-8", // Force using EN as language
@@ -193,33 +215,6 @@ func (self *RebaseCommands) PrepareInteractiveRebaseCommand(opts PrepareInteract
return cmdObj
}
-// produces TodoLines where every commit is picked (or dropped for merge commits) except for the commit at the given index, which
-// will have the given action applied to it.
-func (self *RebaseCommands) BuildSingleActionTodo(commits []*models.Commit, actionIndex int, action string) ([]TodoLine, string, error) {
- baseIndex := actionIndex + 1
-
- if action == "squash" || action == "fixup" {
- baseIndex++
- }
-
- todoLines := self.BuildTodoLines(commits[0:baseIndex], func(commit *models.Commit, i int) string {
- if i == actionIndex {
- return action
- } else if commit.IsMerge() {
- // your typical interactive rebase will actually drop merge commits by default. Damn git CLI, you scary!
- // doing this means we don't need to worry about rebasing over merges which always causes problems.
- // you typically shouldn't be doing rebases that pass over merge commits anyway.
- return "drop"
- } else {
- return "pick"
- }
- })
-
- baseShaOrRoot := getBaseShaOrRoot(commits, baseIndex)
-
- return todoLines, baseShaOrRoot, nil
-}
-
// AmendTo amends the given commit with whatever files are staged
func (self *RebaseCommands) AmendTo(commit *models.Commit) error {
if err := self.commit.CreateFixupCommit(commit.Sha); err != nil {
@@ -278,15 +273,13 @@ func (self *RebaseCommands) BeginInteractiveRebaseForCommit(commits []*models.Co
return errors.New(self.Tr.DisabledForGPG)
}
- todo, sha, err := self.BuildSingleActionTodo(commits, commitIndex, "edit")
- if err != nil {
- return err
- }
-
return self.PrepareInteractiveRebaseCommand(PrepareInteractiveRebaseCommandOpts{
- baseShaOrRoot: sha,
- todoLines: todo,
+ baseShaOrRoot: getBaseShaOrRoot(commits, commitIndex+1),
overrideEditor: true,
+ changeTodoActions: []ChangeTodoAction{{
+ sha: commits[commitIndex].Sha,
+ newAction: todo.Edit,
+ }},
}).Run()
}