diff options
author | Jesse Duffield Duffield <jesseduffieldduffield@Jesses-MacBook-Pro-3.local> | 2019-02-24 13:51:52 +1100 |
---|---|---|
committer | Jesse Duffield Duffield <jesseduffieldduffield@Jesses-MacBook-Pro-3.local> | 2019-02-24 13:51:52 +1100 |
commit | a8858cbd12bd2ef5766f2436a7d43e4ff1c4ca9f (patch) | |
tree | 19febb0f502e2ff050ddde80de166e8354218ced /pkg/gui | |
parent | 1a19b1412d3da03992403cf62fddf06031de2927 (diff) |
support cherry picking commits
Diffstat (limited to 'pkg/gui')
-rw-r--r-- | pkg/gui/commits_panel.go | 68 | ||||
-rw-r--r-- | pkg/gui/gui.go | 12 | ||||
-rw-r--r-- | pkg/gui/keybindings.go | 19 |
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, |