summaryrefslogtreecommitdiffstats
path: root/pkg/gui
diff options
context:
space:
mode:
authorJesse Duffield Duffield <jesseduffieldduffield@Jesses-MacBook-Pro-3.local>2019-02-24 13:51:52 +1100
committerJesse Duffield Duffield <jesseduffieldduffield@Jesses-MacBook-Pro-3.local>2019-02-24 13:51:52 +1100
commita8858cbd12bd2ef5766f2436a7d43e4ff1c4ca9f (patch)
tree19febb0f502e2ff050ddde80de166e8354218ced /pkg/gui
parent1a19b1412d3da03992403cf62fddf06031de2927 (diff)
support cherry picking commits
Diffstat (limited to 'pkg/gui')
-rw-r--r--pkg/gui/commits_panel.go68
-rw-r--r--pkg/gui/gui.go12
-rw-r--r--pkg/gui/keybindings.go19
3 files changed, 93 insertions, 6 deletions
diff --git a/pkg/gui/commits_panel.go b/pkg/gui/commits_panel.go
index 383f9b6ba..37b7538f7 100644
--- a/pkg/gui/commits_panel.go
+++ b/pkg/gui/commits_panel.go
@@ -2,6 +2,8 @@ package gui
import (
"fmt"
+ "strconv"
+ "strings"
"github.com/go-errors/errors"
@@ -40,7 +42,7 @@ func (gui *Gui) handleCommitSelect(g *gocui.Gui, v *gocui.View) error {
func (gui *Gui) refreshCommits(g *gocui.Gui) error {
g.Update(func(*gocui.Gui) error {
- builder, err := git.NewCommitListBuilder(gui.Log, gui.GitCommand, gui.OSCommand, gui.Tr)
+ builder, err := git.NewCommitListBuilder(gui.Log, gui.GitCommand, gui.OSCommand, gui.Tr, gui.State.CherryPickedShas)
if err != nil {
return err
}
@@ -347,3 +349,67 @@ func (gui *Gui) handleCommitRevert(g *gocui.Gui, v *gocui.View) error {
gui.State.Panels.Commits.SelectedLine++
return gui.refreshCommits(gui.g)
}
+
+func (gui *Gui) handleCopyCommit(g *gocui.Gui, v *gocui.View) error {
+ // get currently selected commit, add the sha to state.
+ sha := gui.State.Commits[gui.State.Panels.Commits.SelectedLine].Sha
+
+ // we will un-copy it if it's already copied
+ for index, cherryPickedSha := range gui.State.CherryPickedShas {
+ if sha == cherryPickedSha {
+ gui.State.CherryPickedShas = append(gui.State.CherryPickedShas[0:index], gui.State.CherryPickedShas[index+1:]...)
+ gui.Log.Info("removed copied sha. New shas:\n" + strings.Join(gui.State.CherryPickedShas, "\n"))
+ return gui.refreshCommits(gui.g)
+ }
+ }
+
+ gui.addCommitToCherryPickedShas(gui.State.Panels.Commits.SelectedLine)
+ return gui.refreshCommits(gui.g)
+}
+
+func (gui *Gui) addCommitToCherryPickedShas(index int) {
+ defer func() { gui.Log.Info("new copied shas:\n" + strings.Join(gui.State.CherryPickedShas, "\n")) }()
+
+ // not super happy with modifying the state of the Commits array here
+ // but the alternative would be very tricky
+ gui.State.Commits[index].Copied = true
+
+ newShas := []string{}
+ for _, commit := range gui.State.Commits {
+ if commit.Copied {
+ newShas = append(newShas, commit.Sha)
+ }
+ }
+
+ gui.State.CherryPickedShas = newShas
+}
+
+func (gui *Gui) handleCopyCommitRange(g *gocui.Gui, v *gocui.View) error {
+ // whenever I add a commit, I need to make sure I retain its order
+
+ // find the last commit that is copied that's above our position
+ // if there are none, startIndex = 0
+ startIndex := 0
+ for index, commit := range gui.State.Commits[0:gui.State.Panels.Commits.SelectedLine] {
+ if commit.Copied {
+ startIndex = index
+ }
+ }
+
+ gui.Log.Info("commit copy start index: " + strconv.Itoa(startIndex))
+
+ for index := startIndex; index <= gui.State.Panels.Commits.SelectedLine; index++ {
+ gui.addCommitToCherryPickedShas(index)
+ }
+
+ return gui.refreshCommits(gui.g)
+}
+
+// HandlePasteCommits begins a cherry-pick rebase with the commits the user has copied
+func (gui *Gui) HandlePasteCommits(g *gocui.Gui, v *gocui.View) error {
+ return gui.createConfirmationPanel(g, v, gui.Tr.SLocalize("CherryPick"), gui.Tr.SLocalize("SureCherryPick"), func(g *gocui.Gui, v *gocui.View) error {
+ err := gui.GitCommand.CherryPickShas(gui.State.CherryPickedShas)
+ return gui.handleGenericMergeCommandResult(err)
+ }, nil)
+
+}
diff --git a/pkg/gui/gui.go b/pkg/gui/gui.go
index 11daec652..2103856fd 100644
--- a/pkg/gui/gui.go
+++ b/pkg/gui/gui.go
@@ -133,17 +133,19 @@ type guiState struct {
Panels *panelStates
WorkingTreeState string // one of "merging", "rebasing", "normal"
Contexts map[string]string
+ CherryPickedShas []string
}
// NewGui builds a new gui handler
func NewGui(log *logrus.Entry, gitCommand *commands.GitCommand, oSCommand *commands.OSCommand, tr *i18n.Localizer, config config.AppConfigurer, updater *updates.Updater) (*Gui, error) {
initialState := guiState{
- Files: make([]*commands.File, 0),
- PreviousView: "files",
- Commits: make([]*commands.Commit, 0),
- StashEntries: make([]*commands.StashEntry, 0),
- Platform: *oSCommand.Platform,
+ Files: make([]*commands.File, 0),
+ PreviousView: "files",
+ Commits: make([]*commands.Commit, 0),
+ CherryPickedShas: []string{},
+ StashEntries: make([]*commands.StashEntry, 0),
+ Platform: *oSCommand.Platform,
Panels: &panelStates{
Files: &filePanelState{SelectedLine: -1},
Branches: &branchPanelState{SelectedLine: 0},
diff --git a/pkg/gui/keybindings.go b/pkg/gui/keybindings.go
index ab70616ea..3992513ef 100644
--- a/pkg/gui/keybindings.go
+++ b/pkg/gui/keybindings.go
@@ -359,12 +359,31 @@ func (gui *Gui) GetInitialKeybindings() []*Binding {
Handler: gui.handleCommitRevert,
Description: gui.Tr.SLocalize("revertCommit"),
}, {
+ ViewName: "commits",
+ Key: 'c',
+ Modifier: gocui.ModNone,
+ Handler: gui.handleCopyCommit,
+ Description: gui.Tr.SLocalize("cherryPickCopy"),
+ }, {
+ ViewName: "commits",
+ Key: 'C',
+ Modifier: gocui.ModNone,
+ Handler: gui.handleCopyCommitRange,
+ Description: gui.Tr.SLocalize("cherryPickCopyRange"),
+ }, {
+ ViewName: "commits",
+ Key: 'v',
+ Modifier: gocui.ModNone,
+ Handler: gui.HandlePasteCommits,
+ Description: gui.Tr.SLocalize("pasteCommits"),
+ }, {
ViewName: "stash",
Key: gocui.KeySpace,
Modifier: gocui.ModNone,
Handler: gui.handleStashApply,
Description: gui.Tr.SLocalize("apply"),
}, {
+
ViewName: "stash",
Key: 'g',
Modifier: gocui.ModNone,