2019-11-04 10:47:25 +02:00
|
|
|
package gui
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
|
2021-12-30 04:35:10 +02:00
|
|
|
"github.com/jesseduffield/lazygit/pkg/commands/types/enums"
|
2022-01-28 11:44:36 +02:00
|
|
|
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
2019-11-04 10:47:25 +02:00
|
|
|
)
|
|
|
|
|
2021-04-02 10:20:40 +02:00
|
|
|
func (gui *Gui) handleCreatePatchOptionsMenu() error {
|
2023-03-19 07:09:03 +02:00
|
|
|
if !gui.git.Patch.PatchBuilder.Active() {
|
2022-01-16 05:46:53 +02:00
|
|
|
return gui.c.ErrorMsg(gui.c.Tr.NoPatchError)
|
2019-11-04 10:47:25 +02:00
|
|
|
}
|
|
|
|
|
2022-01-29 10:09:20 +02:00
|
|
|
menuItems := []*types.MenuItem{
|
2020-02-14 14:32:52 +02:00
|
|
|
{
|
2022-05-08 06:23:32 +02:00
|
|
|
Label: "reset patch",
|
2022-06-13 03:01:26 +02:00
|
|
|
OnPress: gui.helpers.PatchBuilding.Reset,
|
2022-05-08 06:23:32 +02:00
|
|
|
Key: 'c',
|
2020-04-27 18:31:22 +02:00
|
|
|
},
|
2020-03-26 12:00:08 +02:00
|
|
|
{
|
2022-05-08 06:23:32 +02:00
|
|
|
Label: "apply patch",
|
|
|
|
OnPress: func() error { return gui.handleApplyPatch(false) },
|
|
|
|
Key: 'a',
|
2020-03-29 23:49:20 +02:00
|
|
|
},
|
|
|
|
{
|
2022-05-08 06:23:32 +02:00
|
|
|
Label: "apply patch in reverse",
|
|
|
|
OnPress: func() error { return gui.handleApplyPatch(true) },
|
|
|
|
Key: 'r',
|
2020-03-26 12:00:08 +02:00
|
|
|
},
|
2019-11-04 10:47:25 +02:00
|
|
|
}
|
|
|
|
|
2023-03-19 07:09:03 +02:00
|
|
|
if gui.git.Patch.PatchBuilder.CanRebase && gui.git.Status.WorkingTreeState() == enums.REBASE_MODE_NONE {
|
2022-01-29 10:09:20 +02:00
|
|
|
menuItems = append(menuItems, []*types.MenuItem{
|
2020-08-21 12:40:20 +02:00
|
|
|
{
|
2023-03-19 07:09:03 +02:00
|
|
|
Label: fmt.Sprintf("remove patch from original commit (%s)", gui.git.Patch.PatchBuilder.To),
|
2022-05-08 06:23:32 +02:00
|
|
|
OnPress: gui.handleDeletePatchFromCommit,
|
|
|
|
Key: 'd',
|
2020-08-21 12:40:20 +02:00
|
|
|
},
|
|
|
|
{
|
2022-05-08 06:23:32 +02:00
|
|
|
Label: "move patch out into index",
|
|
|
|
OnPress: gui.handleMovePatchIntoWorkingTree,
|
|
|
|
Key: 'i',
|
2020-08-21 12:40:20 +02:00
|
|
|
},
|
|
|
|
{
|
2022-05-08 06:23:32 +02:00
|
|
|
Label: "move patch into new commit",
|
|
|
|
OnPress: gui.handlePullPatchIntoNewCommit,
|
|
|
|
Key: 'n',
|
2020-08-21 12:40:20 +02:00
|
|
|
},
|
|
|
|
}...)
|
|
|
|
|
2022-02-13 08:01:53 +02:00
|
|
|
if gui.currentContext().GetKey() == gui.State.Contexts.LocalCommits.GetKey() {
|
2020-08-22 01:48:20 +02:00
|
|
|
selectedCommit := gui.getSelectedLocalCommit()
|
2023-03-19 07:09:03 +02:00
|
|
|
if selectedCommit != nil && gui.git.Patch.PatchBuilder.To != selectedCommit.Sha {
|
2020-08-21 12:54:09 +02:00
|
|
|
// adding this option to index 1
|
|
|
|
menuItems = append(
|
|
|
|
menuItems[:1],
|
|
|
|
append(
|
2022-01-29 10:09:20 +02:00
|
|
|
[]*types.MenuItem{
|
2020-08-21 12:54:09 +02:00
|
|
|
{
|
2022-05-08 06:23:32 +02:00
|
|
|
Label: fmt.Sprintf("move patch to selected commit (%s)", selectedCommit.Sha),
|
|
|
|
OnPress: gui.handleMovePatchToSelectedCommit,
|
|
|
|
Key: 'm',
|
2020-08-21 12:54:09 +02:00
|
|
|
},
|
|
|
|
}, menuItems[1:]...,
|
|
|
|
)...,
|
|
|
|
)
|
|
|
|
}
|
2020-08-21 12:51:39 +02:00
|
|
|
}
|
2019-11-04 10:47:25 +02:00
|
|
|
}
|
|
|
|
|
2023-01-29 06:33:59 +02:00
|
|
|
menuItems = append(menuItems, []*types.MenuItem{
|
|
|
|
{
|
|
|
|
Label: "copy patch to clipboard",
|
|
|
|
OnPress: func() error { return gui.copyPatchToClipboard() },
|
|
|
|
Key: 'y',
|
|
|
|
},
|
|
|
|
}...)
|
|
|
|
|
2022-01-29 10:09:20 +02:00
|
|
|
return gui.c.Menu(types.CreateMenuOptions{Title: gui.c.Tr.PatchOptionsTitle, Items: menuItems})
|
2019-11-04 10:47:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func (gui *Gui) getPatchCommitIndex() int {
|
2022-01-31 13:11:34 +02:00
|
|
|
for index, commit := range gui.State.Model.Commits {
|
2023-03-19 07:09:03 +02:00
|
|
|
if commit.Sha == gui.git.Patch.PatchBuilder.To {
|
2019-11-04 10:47:25 +02:00
|
|
|
return index
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return -1
|
|
|
|
}
|
|
|
|
|
2019-11-05 08:57:59 +02:00
|
|
|
func (gui *Gui) validateNormalWorkingTreeState() (bool, error) {
|
2022-01-16 05:46:53 +02:00
|
|
|
if gui.git.Status.WorkingTreeState() != enums.REBASE_MODE_NONE {
|
|
|
|
return false, gui.c.ErrorMsg(gui.c.Tr.CantPatchWhileRebasingError)
|
2019-11-05 08:57:59 +02:00
|
|
|
}
|
|
|
|
return true, nil
|
|
|
|
}
|
|
|
|
|
2022-06-13 03:01:26 +02:00
|
|
|
func (gui *Gui) returnFocusFromPatchExplorerIfNecessary() error {
|
|
|
|
if gui.currentContext().GetKey() == gui.State.Contexts.CustomPatchBuilder.GetKey() {
|
|
|
|
return gui.helpers.PatchBuilding.Escape()
|
2019-11-05 08:57:59 +02:00
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2019-11-04 10:47:25 +02:00
|
|
|
func (gui *Gui) handleDeletePatchFromCommit() error {
|
2019-11-05 02:53:01 +02:00
|
|
|
if ok, err := gui.validateNormalWorkingTreeState(); !ok {
|
|
|
|
return err
|
|
|
|
}
|
2019-11-04 10:47:25 +02:00
|
|
|
|
2022-06-13 03:01:26 +02:00
|
|
|
if err := gui.returnFocusFromPatchExplorerIfNecessary(); err != nil {
|
2019-11-05 08:57:59 +02:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2022-01-16 05:46:53 +02:00
|
|
|
return gui.c.WithWaitingStatus(gui.c.Tr.RebasingStatus, func() error {
|
2019-11-04 10:47:25 +02:00
|
|
|
commitIndex := gui.getPatchCommitIndex()
|
2022-01-16 05:46:53 +02:00
|
|
|
gui.c.LogAction(gui.c.Tr.Actions.RemovePatchFromCommit)
|
2022-01-31 13:11:34 +02:00
|
|
|
err := gui.git.Patch.DeletePatchesFromCommit(gui.State.Model.Commits, commitIndex)
|
2022-02-06 06:54:26 +02:00
|
|
|
return gui.helpers.MergeAndRebase.CheckMergeOrRebase(err)
|
2019-11-04 10:47:25 +02:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func (gui *Gui) handleMovePatchToSelectedCommit() error {
|
2019-11-05 02:53:01 +02:00
|
|
|
if ok, err := gui.validateNormalWorkingTreeState(); !ok {
|
|
|
|
return err
|
|
|
|
}
|
2019-11-04 10:47:25 +02:00
|
|
|
|
2022-06-13 03:01:26 +02:00
|
|
|
if err := gui.returnFocusFromPatchExplorerIfNecessary(); err != nil {
|
2019-11-05 08:57:59 +02:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2022-01-16 05:46:53 +02:00
|
|
|
return gui.c.WithWaitingStatus(gui.c.Tr.RebasingStatus, func() error {
|
2019-11-04 10:47:25 +02:00
|
|
|
commitIndex := gui.getPatchCommitIndex()
|
2022-01-16 05:46:53 +02:00
|
|
|
gui.c.LogAction(gui.c.Tr.Actions.MovePatchToSelectedCommit)
|
2022-02-13 08:01:53 +02:00
|
|
|
err := gui.git.Patch.MovePatchToSelectedCommit(gui.State.Model.Commits, commitIndex, gui.State.Contexts.LocalCommits.GetSelectedLineIdx())
|
2022-02-06 06:54:26 +02:00
|
|
|
return gui.helpers.MergeAndRebase.CheckMergeOrRebase(err)
|
2019-11-04 10:47:25 +02:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2021-04-10 08:01:46 +02:00
|
|
|
func (gui *Gui) handleMovePatchIntoWorkingTree() error {
|
2019-11-05 02:53:01 +02:00
|
|
|
if ok, err := gui.validateNormalWorkingTreeState(); !ok {
|
|
|
|
return err
|
|
|
|
}
|
2019-11-04 10:47:25 +02:00
|
|
|
|
2022-06-13 03:01:26 +02:00
|
|
|
if err := gui.returnFocusFromPatchExplorerIfNecessary(); err != nil {
|
2019-11-05 08:57:59 +02:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2020-03-28 03:43:31 +02:00
|
|
|
pull := func(stash bool) error {
|
2022-01-16 05:46:53 +02:00
|
|
|
return gui.c.WithWaitingStatus(gui.c.Tr.RebasingStatus, func() error {
|
2020-03-28 03:43:31 +02:00
|
|
|
commitIndex := gui.getPatchCommitIndex()
|
2022-01-16 05:46:53 +02:00
|
|
|
gui.c.LogAction(gui.c.Tr.Actions.MovePatchIntoIndex)
|
2022-01-31 13:11:34 +02:00
|
|
|
err := gui.git.Patch.MovePatchIntoIndex(gui.State.Model.Commits, commitIndex, stash)
|
2022-02-06 06:54:26 +02:00
|
|
|
return gui.helpers.MergeAndRebase.CheckMergeOrRebase(err)
|
2020-03-28 03:43:31 +02:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2022-01-31 13:11:34 +02:00
|
|
|
if gui.helpers.WorkingTree.IsWorkingTreeDirty() {
|
2022-03-30 08:48:29 +02:00
|
|
|
return gui.c.Confirm(types.ConfirmOpts{
|
2022-01-16 05:46:53 +02:00
|
|
|
Title: gui.c.Tr.MustStashTitle,
|
|
|
|
Prompt: gui.c.Tr.MustStashWarning,
|
2022-01-28 11:44:36 +02:00
|
|
|
HandleConfirm: func() error {
|
2020-08-15 08:36:39 +02:00
|
|
|
return pull(true)
|
|
|
|
},
|
|
|
|
})
|
2020-03-28 03:43:31 +02:00
|
|
|
} else {
|
|
|
|
return pull(false)
|
|
|
|
}
|
2019-11-04 10:47:25 +02:00
|
|
|
}
|
|
|
|
|
2020-04-27 18:31:22 +02:00
|
|
|
func (gui *Gui) handlePullPatchIntoNewCommit() error {
|
|
|
|
if ok, err := gui.validateNormalWorkingTreeState(); !ok {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2022-06-13 03:01:26 +02:00
|
|
|
if err := gui.returnFocusFromPatchExplorerIfNecessary(); err != nil {
|
2020-04-27 18:31:22 +02:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2022-01-16 05:46:53 +02:00
|
|
|
return gui.c.WithWaitingStatus(gui.c.Tr.RebasingStatus, func() error {
|
2020-04-27 18:31:22 +02:00
|
|
|
commitIndex := gui.getPatchCommitIndex()
|
2022-01-16 05:46:53 +02:00
|
|
|
gui.c.LogAction(gui.c.Tr.Actions.MovePatchIntoNewCommit)
|
2022-01-31 13:11:34 +02:00
|
|
|
err := gui.git.Patch.PullPatchIntoNewCommit(gui.State.Model.Commits, commitIndex)
|
2022-02-06 06:54:26 +02:00
|
|
|
return gui.helpers.MergeAndRebase.CheckMergeOrRebase(err)
|
2020-04-27 18:31:22 +02:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2020-03-29 23:49:20 +02:00
|
|
|
func (gui *Gui) handleApplyPatch(reverse bool) error {
|
2022-06-13 03:01:26 +02:00
|
|
|
if err := gui.returnFocusFromPatchExplorerIfNecessary(); err != nil {
|
2020-03-26 12:00:08 +02:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2022-01-16 05:46:53 +02:00
|
|
|
action := gui.c.Tr.Actions.ApplyPatch
|
2021-04-10 08:01:46 +02:00
|
|
|
if reverse {
|
2022-01-05 03:01:59 +02:00
|
|
|
action = "Apply patch in reverse"
|
2021-04-10 08:01:46 +02:00
|
|
|
}
|
2022-01-16 05:46:53 +02:00
|
|
|
gui.c.LogAction(action)
|
2023-03-19 07:09:03 +02:00
|
|
|
if err := gui.git.Patch.PatchBuilder.ApplyPatches(reverse); err != nil {
|
2022-01-16 05:46:53 +02:00
|
|
|
return gui.c.Error(err)
|
2020-03-26 12:00:08 +02:00
|
|
|
}
|
2022-01-16 05:46:53 +02:00
|
|
|
return gui.c.Refresh(types.RefreshOptions{Mode: types.ASYNC})
|
2020-03-26 12:00:08 +02:00
|
|
|
}
|
2023-01-17 05:37:07 +02:00
|
|
|
|
2023-01-18 06:44:48 +02:00
|
|
|
func (gui *Gui) copyPatchToClipboard() error {
|
2023-03-19 07:09:03 +02:00
|
|
|
patch := gui.git.Patch.PatchBuilder.RenderAggregatedPatch(true)
|
2023-01-17 05:37:07 +02:00
|
|
|
|
|
|
|
gui.c.LogAction(gui.c.Tr.Actions.CopyPatchToClipboard)
|
|
|
|
if err := gui.os.CopyToClipboard(patch); err != nil {
|
|
|
|
return gui.c.Error(err)
|
|
|
|
}
|
|
|
|
|
2023-01-29 06:33:59 +02:00
|
|
|
gui.c.Toast(gui.c.Tr.PatchCopiedToClipboard)
|
2023-01-17 05:37:07 +02:00
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|