diff --git a/pkg/commands/git.go b/pkg/commands/git.go index 243457c4f..ddb19f98a 100644 --- a/pkg/commands/git.go +++ b/pkg/commands/git.go @@ -1061,7 +1061,7 @@ func (c *GitCommand) GetFilesInRef(parent string, isStash bool, patchManager *pa for _, file := range strings.Split(strings.TrimRight(files, "\n"), "\n") { status := patch.UNSELECTED - if patchManager != nil && patchManager.CommitSha == parent { + if patchManager != nil && patchManager.Parent == parent { status = patchManager.GetFileStatus(file) } diff --git a/pkg/commands/patch/patch_manager.go b/pkg/commands/patch/patch_manager.go index d248381f6..8da6fb3a2 100644 --- a/pkg/commands/patch/patch_manager.go +++ b/pkg/commands/patch/patch_manager.go @@ -12,7 +12,7 @@ const ( UNSELECTED = iota // WHOLE is for when you want to add the whole diff of a file to the patch, // including e.g. if it was deleted - WHOLE = iota + WHOLE // PART is for when you're only talking about specific lines that have been modified PART ) @@ -25,9 +25,13 @@ type fileInfo struct { type applyPatchFunc func(patch string, flags ...string) error -// PatchManager manages the building of a patch for a commit to be applied to another commit (or the working tree, or removed from the current commit) +// PatchManager manages the building of a patch for a commit to be applied to another commit (or the working tree, or removed from the current commit). We also support building patches from things like stashes, for which there is less flexibility type PatchManager struct { - CommitSha string + // Parent is the commit sha if we're dealing with files of a commit, or a stash ref for a stash + Parent string + + // CanRebase tells us whether we're allowed to modify our commits. CanRebase should be true for commits of the currently checked out branch and false for everything else + CanRebase bool fileInfoMap map[string]*fileInfo Log *logrus.Entry ApplyPatch applyPatchFunc @@ -42,8 +46,8 @@ func NewPatchManager(log *logrus.Entry, applyPatch applyPatchFunc) *PatchManager } // NewPatchManager returns a new PatchManager -func (p *PatchManager) Start(commitSha string, diffMap map[string]string) { - p.CommitSha = commitSha +func (p *PatchManager) Start(parent string, diffMap map[string]string) { + p.Parent = parent p.fileInfoMap = map[string]*fileInfo{} for filename, diff := range diffMap { p.fileInfoMap[filename] = &fileInfo{ @@ -219,12 +223,12 @@ func (p *PatchManager) ApplyPatches(reverse bool) error { // clears the patch func (p *PatchManager) Reset() { - p.CommitSha = "" + p.Parent = "" p.fileInfoMap = map[string]*fileInfo{} } -func (p *PatchManager) CommitSelected() bool { - return p.CommitSha != "" +func (p *PatchManager) Active() bool { + return p.Parent != "" } func (p *PatchManager) IsEmpty() bool { diff --git a/pkg/gui/commit_files_panel.go b/pkg/gui/commit_files_panel.go index 327c4450c..2cdf0c02f 100644 --- a/pkg/gui/commit_files_panel.go +++ b/pkg/gui/commit_files_panel.go @@ -2,7 +2,6 @@ package gui import ( "github.com/davecgh/go-spew/spew" - "github.com/go-errors/errors" "github.com/jesseduffield/gocui" "github.com/jesseduffield/lazygit/pkg/commands" ) @@ -122,7 +121,7 @@ func (gui *Gui) handleToggleFileForPatch(g *gocui.Gui, v *gocui.View) error { } toggleTheFile := func() error { - if !gui.GitCommand.PatchManager.CommitSelected() { + if !gui.GitCommand.PatchManager.Active() { if err := gui.startPatchManager(); err != nil { return err } @@ -133,7 +132,7 @@ func (gui *Gui) handleToggleFileForPatch(g *gocui.Gui, v *gocui.View) error { return gui.refreshCommitFilesView() } - if gui.GitCommand.PatchManager.CommitSelected() && gui.GitCommand.PatchManager.CommitSha != commitFile.Parent { + if gui.GitCommand.PatchManager.Active() && gui.GitCommand.PatchManager.Parent != commitFile.Parent { return gui.ask(askOpts{ returnToView: v, returnFocusOnClose: true, @@ -151,6 +150,7 @@ func (gui *Gui) handleToggleFileForPatch(g *gocui.Gui, v *gocui.View) error { func (gui *Gui) startPatchManager() error { diffMap := map[string]string{} + // TODO: only load these files as we need to for _, commitFile := range gui.State.CommitFiles { commitText, err := gui.GitCommand.ShowCommitFile(commitFile.Parent, commitFile.Name, true) if err != nil { @@ -159,12 +159,7 @@ func (gui *Gui) startPatchManager() error { diffMap[commitFile.Name] = commitText } - commit := gui.getSelectedCommit() - if commit == nil { - return errors.New("No commit selected") - } - - gui.GitCommand.PatchManager.Start(commit.Sha, diffMap) + gui.GitCommand.PatchManager.Start(gui.State.Panels.CommitFiles.refName, diffMap) return nil } @@ -184,7 +179,7 @@ func (gui *Gui) enterCommitFile(selectedLineIdx int) error { } enterTheFile := func(selectedLineIdx int) error { - if !gui.GitCommand.PatchManager.CommitSelected() { + if !gui.GitCommand.PatchManager.Active() { if err := gui.startPatchManager(); err != nil { return err } @@ -196,7 +191,7 @@ func (gui *Gui) enterCommitFile(selectedLineIdx int) error { return gui.refreshPatchBuildingPanel(selectedLineIdx) } - if gui.GitCommand.PatchManager.CommitSelected() && gui.GitCommand.PatchManager.CommitSha != commitFile.Parent { + if gui.GitCommand.PatchManager.Active() && gui.GitCommand.PatchManager.Parent != commitFile.Parent { return gui.ask(askOpts{ returnToView: gui.getCommitFilesView(), returnFocusOnClose: false, diff --git a/pkg/gui/patch_building_panel.go b/pkg/gui/patch_building_panel.go index 76589505a..c39568cdf 100644 --- a/pkg/gui/patch_building_panel.go +++ b/pkg/gui/patch_building_panel.go @@ -6,7 +6,7 @@ import ( ) func (gui *Gui) refreshPatchBuildingPanel(selectedLineIdx int) error { - if !gui.GitCommand.PatchManager.CommitSelected() { + if !gui.GitCommand.PatchManager.Active() { return gui.handleEscapePatchBuildingPanel() } @@ -88,7 +88,7 @@ func (gui *Gui) handleEscapePatchBuildingPanel() error { func (gui *Gui) refreshSecondaryPatchPanel() error { // TODO: swap out for secondaryPatchPanelUpdateOpts - if gui.GitCommand.PatchManager.CommitSelected() { + if gui.GitCommand.PatchManager.Active() { gui.splitMainPanel(true) secondaryView := gui.getSecondaryView() secondaryView.Highlight = true @@ -106,7 +106,7 @@ func (gui *Gui) refreshSecondaryPatchPanel() error { } func (gui *Gui) secondaryPatchPanelUpdateOpts() *viewUpdateOpts { - if gui.GitCommand.PatchManager.CommitSelected() { + if gui.GitCommand.PatchManager.Active() { patch := gui.GitCommand.PatchManager.RenderAggregatedPatchColored(false) return &viewUpdateOpts{ diff --git a/pkg/gui/patch_options_panel.go b/pkg/gui/patch_options_panel.go index bb9bf7918..844ecbd36 100644 --- a/pkg/gui/patch_options_panel.go +++ b/pkg/gui/patch_options_panel.go @@ -7,13 +7,13 @@ import ( ) func (gui *Gui) handleCreatePatchOptionsMenu(g *gocui.Gui, v *gocui.View) error { - if !gui.GitCommand.PatchManager.CommitSelected() { + if !gui.GitCommand.PatchManager.Active() { return gui.createErrorPanel(gui.Tr.SLocalize("NoPatchError")) } menuItems := []*menuItem{ { - displayString: fmt.Sprintf("remove patch from original commit (%s)", gui.GitCommand.PatchManager.CommitSha), + displayString: fmt.Sprintf("remove patch from original commit (%s)", gui.GitCommand.PatchManager.Parent), onPress: gui.handleDeletePatchFromCommit, }, { @@ -39,7 +39,7 @@ func (gui *Gui) handleCreatePatchOptionsMenu(g *gocui.Gui, v *gocui.View) error } selectedCommit := gui.getSelectedCommit() - if selectedCommit != nil && gui.GitCommand.PatchManager.CommitSha != selectedCommit.Sha { + if selectedCommit != nil && gui.GitCommand.PatchManager.Parent != selectedCommit.Sha { // adding this option to index 1 menuItems = append( menuItems[:1], @@ -59,7 +59,7 @@ func (gui *Gui) handleCreatePatchOptionsMenu(g *gocui.Gui, v *gocui.View) error func (gui *Gui) getPatchCommitIndex() int { for index, commit := range gui.State.Commits { - if commit.Sha == gui.GitCommand.PatchManager.CommitSha { + if commit.Sha == gui.GitCommand.PatchManager.Parent { return index } } diff --git a/pkg/i18n/english.go b/pkg/i18n/english.go index 24d55b7f2..4df273a71 100644 --- a/pkg/i18n/english.go +++ b/pkg/i18n/english.go @@ -887,7 +887,7 @@ func addEnglish(i18nObject *i18n.Bundle) error { Other: "Discard Patch", }, &i18n.Message{ ID: "DiscardPatchConfirm", - Other: "You can only build a patch from one commit at a time. Discard current patch?", + Other: "You can only build a patch from one commit/stash-entry at a time. Discard current patch?", }, &i18n.Message{ ID: "CantPatchWhileRebasingError", Other: "You cannot build a patch or run patch commands while in a merging or rebasing state",