From 7ed8ee160d7f1d38f5159dca315e56899de8c0b9 Mon Sep 17 00:00:00 2001 From: Gary Yendell Date: Mon, 27 Apr 2020 17:31:22 +0100 Subject: [PATCH] Add option to split patch into a new commit Add GetHeadCommitMessage to read the subject of the HEAD commit Create PullPatchIntoNewCommit based heavily on PullPatchIntoIndex to split the current patch from its commit and apply it in a separate commit immediately after. WIP to Squash - Fill format string with format string WIP --- pkg/commands/git.go | 7 ++++++ pkg/commands/patch_rebases.go | 45 +++++++++++++++++++++++++++++++++- pkg/gui/patch_options_panel.go | 20 +++++++++++++++ 3 files changed, 71 insertions(+), 1 deletion(-) diff --git a/pkg/commands/git.go b/pkg/commands/git.go index 31318fc92..94234cab3 100644 --- a/pkg/commands/git.go +++ b/pkg/commands/git.go @@ -441,6 +441,13 @@ func (c *GitCommand) Commit(message string, flags string) (*exec.Cmd, error) { return nil, c.OSCommand.RunCommand(command) } +// Get the subject of the HEAD commit +func (c *GitCommand) GetHeadCommitMessage() (string, error) { + cmdStr := "git log -1 --pretty=%s" + message, err := c.OSCommand.RunCommandWithOutput(cmdStr) + return strings.TrimSpace(message), err +} + // AmendHead amends HEAD with whatever is staged in your working tree func (c *GitCommand) AmendHead() (*exec.Cmd, error) { command := "git commit --amend --no-edit --allow-empty" diff --git a/pkg/commands/patch_rebases.go b/pkg/commands/patch_rebases.go index eeeb0876c..bb1ca5b98 100644 --- a/pkg/commands/patch_rebases.go +++ b/pkg/commands/patch_rebases.go @@ -1,6 +1,9 @@ package commands -import "github.com/go-errors/errors" +import ( + "fmt" + "github.com/go-errors/errors" +) // DeletePatchesFromCommit applies a patch in reverse for a commit func (c *GitCommand) DeletePatchesFromCommit(commits []*Commit, commitIndex int, p *PatchManager) error { @@ -183,3 +186,43 @@ func (c *GitCommand) PullPatchIntoIndex(commits []*Commit, commitIdx int, p *Pat return c.GenericMerge("rebase", "continue") } + +func (c *GitCommand) PullPatchIntoNewCommit(commits []*Commit, commitIdx int, p *PatchManager) error { + if err := c.BeginInteractiveRebaseForCommit(commits, commitIdx); err != nil { + return err + } + + if err := p.ApplyPatches(true); err != nil { + if err := c.GenericMerge("rebase", "abort"); err != nil { + return err + } + return err + } + + // amend the commit + if _, err := c.AmendHead(); err != nil { + return err + } + + // add patches to index + if err := p.ApplyPatches(false); err != nil { + if err := c.GenericMerge("rebase", "abort"); err != nil { + return err + } + return err + } + + head_message, _ := c.GetHeadCommitMessage() + new_message := fmt.Sprintf("Split from \"%s\"", head_message) + _, err := c.Commit(new_message, "") + if err != nil { + return err + } + + if c.onSuccessfulContinue != nil { + return errors.New("You are midway through another rebase operation. Please abort to start again") + } + + c.PatchManager.Reset() + return c.GenericMerge("rebase", "continue") +} diff --git a/pkg/gui/patch_options_panel.go b/pkg/gui/patch_options_panel.go index b69d12d92..4ec3cd228 100644 --- a/pkg/gui/patch_options_panel.go +++ b/pkg/gui/patch_options_panel.go @@ -20,6 +20,10 @@ func (gui *Gui) handleCreatePatchOptionsMenu(g *gocui.Gui, v *gocui.View) error displayString: "pull patch out into index", onPress: gui.handlePullPatchIntoWorkingTree, }, + { + displayString: "pull patch into new commit", + onPress: gui.handlePullPatchIntoNewCommit, + }, { displayString: "apply patch", onPress: func() error { return gui.handleApplyPatch(false) }, @@ -137,6 +141,22 @@ func (gui *Gui) handlePullPatchIntoWorkingTree() error { } } +func (gui *Gui) handlePullPatchIntoNewCommit() error { + if ok, err := gui.validateNormalWorkingTreeState(); !ok { + return err + } + + if err := gui.returnFocusFromLineByLinePanelIfNecessary(); err != nil { + return err + } + + return gui.WithWaitingStatus(gui.Tr.SLocalize("RebasingStatus"), func() error { + commitIndex := gui.getPatchCommitIndex() + err := gui.GitCommand.PullPatchIntoNewCommit(gui.State.Commits, commitIndex, gui.GitCommand.PatchManager) + return gui.handleGenericMergeCommandResult(err) + }) +} + func (gui *Gui) handleApplyPatch(reverse bool) error { if err := gui.returnFocusFromLineByLinePanelIfNecessary(); err != nil { return err