summaryrefslogtreecommitdiffstats
path: root/pkg
diff options
context:
space:
mode:
authorJesse Duffield <jessedduffield@gmail.com>2024-01-13 17:40:28 +1100
committerJesse Duffield <jessedduffield@gmail.com>2024-01-19 10:50:49 +1100
commit280b4d60f893a0e20897091ab02617c32180b45d (patch)
tree9665a327ae7fe4d468637fc0e10327a223a113ed /pkg
parent54bd94ad24ca24ca12fab59e9dbf0d79fe7681da (diff)
Support select range for cherry pick
This requires us to change the 'v' keybinding for paste to something else, now that 'v' is used globally for toggling range select. So I'm using 'shift+v' and I'm likewise changing 'c' to 'shift+c' for copying, so that they're consistent. We will need to clearly communicate this change in keybindings.
Diffstat (limited to 'pkg')
-rw-r--r--pkg/config/user_config.go6
-rw-r--r--pkg/gui/controllers/basic_commits_controller.go14
-rw-r--r--pkg/gui/controllers/helpers/cherry_pick_helper.go30
-rw-r--r--pkg/i18n/chinese.go1
-rw-r--r--pkg/i18n/dutch.go1
-rw-r--r--pkg/i18n/english.go2
-rw-r--r--pkg/i18n/japanese.go5
-rw-r--r--pkg/i18n/korean.go1
-rw-r--r--pkg/i18n/polish.go1
-rw-r--r--pkg/i18n/russian.go1
-rw-r--r--pkg/i18n/traditional_chinese.go1
-rw-r--r--pkg/integration/tests/cherry_pick/cherry_pick_range.go85
-rw-r--r--pkg/integration/tests/test_list.go1
13 files changed, 111 insertions, 38 deletions
diff --git a/pkg/config/user_config.go b/pkg/config/user_config.go
index a966905d0..e9f739a1d 100644
--- a/pkg/config/user_config.go
+++ b/pkg/config/user_config.go
@@ -418,7 +418,6 @@ type KeybindingCommitsConfig struct {
PickCommit string `yaml:"pickCommit"`
RevertCommit string `yaml:"revertCommit"`
CherryPickCopy string `yaml:"cherryPickCopy"`
- CherryPickCopyRange string `yaml:"cherryPickCopyRange"`
PasteCommits string `yaml:"pasteCommits"`
MarkCommitAsBaseForRebase string `yaml:"markCommitAsBaseForRebase"`
CreateTag string `yaml:"tagCommit"`
@@ -812,9 +811,8 @@ func GetDefaultConfig() *UserConfig {
ResetCommitAuthor: "a",
PickCommit: "p",
RevertCommit: "t",
- CherryPickCopy: "c",
- CherryPickCopyRange: "C",
- PasteCommits: "v",
+ CherryPickCopy: "C",
+ PasteCommits: "V",
MarkCommitAsBaseForRebase: "B",
CreateTag: "T",
CheckoutCommit: "<space>",
diff --git a/pkg/gui/controllers/basic_commits_controller.go b/pkg/gui/controllers/basic_commits_controller.go
index 551349466..2f120a0f4 100644
--- a/pkg/gui/controllers/basic_commits_controller.go
+++ b/pkg/gui/controllers/basic_commits_controller.go
@@ -14,6 +14,7 @@ var _ types.IController = &BasicCommitsController{}
type ContainsCommits interface {
types.Context
+ types.IListContext
GetSelected() *models.Commit
GetCommits() []*models.Commit
GetSelectedLineIdx() int
@@ -64,13 +65,8 @@ func (self *BasicCommitsController) GetKeybindings(opts types.KeybindingsOpts) [
},
{
Key: opts.GetKey(opts.Config.Commits.CherryPickCopy),
- Handler: self.checkSelected(self.copy),
- Description: self.c.Tr.CherryPickCopy,
- },
- {
- Key: opts.GetKey(opts.Config.Commits.CherryPickCopyRange),
Handler: self.checkSelected(self.copyRange),
- Description: self.c.Tr.CherryPickCopyRange,
+ Description: self.c.Tr.CherryPickCopy,
},
{
Key: opts.GetKey(opts.Config.Commits.ResetCherryPick),
@@ -271,12 +267,8 @@ func (self *BasicCommitsController) checkout(commit *models.Commit) error {
})
}
-func (self *BasicCommitsController) copy(commit *models.Commit) error {
- return self.c.Helpers().CherryPick.Copy(commit, self.context.GetCommits(), self.context)
-}
-
func (self *BasicCommitsController) copyRange(*models.Commit) error {
- return self.c.Helpers().CherryPick.CopyRange(self.context.GetSelectedLineIdx(), self.context.GetCommits(), self.context)
+ return self.c.Helpers().CherryPick.CopyRange(self.context.GetCommits(), self.context)
}
func (self *BasicCommitsController) openDiffTool(commit *models.Commit) error {
diff --git a/pkg/gui/controllers/helpers/cherry_pick_helper.go b/pkg/gui/controllers/helpers/cherry_pick_helper.go
index 4f455ca30..61a37220b 100644
--- a/pkg/gui/controllers/helpers/cherry_pick_helper.go
+++ b/pkg/gui/controllers/helpers/cherry_pick_helper.go
@@ -5,6 +5,7 @@ import (
"github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/gui/modes/cherrypicking"
"github.com/jesseduffield/lazygit/pkg/gui/types"
+ "github.com/samber/lo"
)
type CherryPickHelper struct {
@@ -45,25 +46,30 @@ func (self *CherryPickHelper) Copy(commit *models.Commit, commitsList []*models.
return self.rerender()
}
-func (self *CherryPickHelper) CopyRange(selectedIndex int, commitsList []*models.Commit, context types.Context) error {
+func (self *CherryPickHelper) CopyRange(commitsList []*models.Commit, context types.IListContext) error {
+ startIdx, endIdx := context.GetList().GetSelectionRange()
+
if err := self.resetIfNecessary(context); err != nil {
return err
}
commitSet := self.getData().SelectedShaSet()
- // find the last commit that is copied that's above our position
- // if there are none, startIndex = 0
- startIndex := 0
- for index, commit := range commitsList[0:selectedIndex] {
- if commitSet.Includes(commit.Sha) {
- startIndex = index
- }
- }
+ allCommitsCopied := lo.EveryBy(commitsList[startIdx:endIdx+1], func(commit *models.Commit) bool {
+ return commitSet.Includes(commit.Sha)
+ })
- for index := startIndex; index <= selectedIndex; index++ {
- commit := commitsList[index]
- self.getData().Add(commit, commitsList)
+ // if all selected commits are already copied, we'll uncopy them
+ if allCommitsCopied {
+ for index := startIdx; index <= endIdx; index++ {
+ commit := commitsList[index]
+ self.getData().Remove(commit, commitsList)
+ }
+ } else {
+ for index := startIdx; index <= endIdx; index++ {
+ commit := commitsList[index]
+ self.getData().Add(commit, commitsList)
+ }
}
return self.rerender()
diff --git a/pkg/i18n/chinese.go b/pkg/i18n/chinese.go
index 0482f4046..8386bce1e 100644
--- a/pkg/i18n/chinese.go
+++ b/pkg/i18n/chinese.go
@@ -198,7 +198,6 @@ func chineseTranslationSet() TranslationSet {
YouAreHere: "您在这里",
RewordNotSupported: "当前不支持交互式重新基准化时的重新措词提交",
CherryPickCopy: "复制提交(拣选)",
- CherryPickCopyRange: "复制提交范围(拣选)",
PasteCommits: "粘贴提交(拣选)",
SureCherryPick: "您确定要将选中的提交进行拣选到这个分支吗?",
CherryPick: "拣选 (Cherry-Pick)",
diff --git a/pkg/i18n/dutch.go b/pkg/i18n/dutch.go
index 79207490b..1e2eaa689 100644
--- a/pkg/i18n/dutch.go
+++ b/pkg/i18n/dutch.go
@@ -163,7 +163,6 @@ func dutchTranslationSet() TranslationSet {
YouAreHere: "JE BENT HIER",
RewordNotSupported: "Herformatteren van commits in interactief rebasen is nog niet ondersteund",
CherryPickCopy: "Kopieer commit (cherry-pick)",
- CherryPickCopyRange: "Kopieer commit reeks (cherry-pick)",
PasteCommits: "Plak commits (cherry-pick)",
SureCherryPick: "Weet je zeker dat je de gekopieerde commits naar deze branch wil cherry-picken?",
CherryPick: "Cherry-Pick",
diff --git a/pkg/i18n/english.go b/pkg/i18n/english.go
index ad859dc1d..e9d0c9a65 100644
--- a/pkg/i18n/english.go
+++ b/pkg/i18n/english.go
@@ -251,7 +251,6 @@ type TranslationSet struct {
RewordNotSupported string
ChangingThisActionIsNotAllowed string
CherryPickCopy string
- CherryPickCopyRange string
PasteCommits string
SureCherryPick string
CherryPick string
@@ -1090,7 +1089,6 @@ func EnglishTranslationSet() TranslationSet {
RewordNotSupported: "Rewording commits while interactively rebasing is not currently supported",
ChangingThisActionIsNotAllowed: "Changing this kind of rebase todo entry is not allowed",
CherryPickCopy: "Copy commit (cherry-pick)",
- CherryPickCopyRange: "Copy commit range (cherry-pick)",
PasteCommits: "Paste commits (cherry-pick)",
SureCherryPick: "Are you sure you want to cherry-pick the copied commits onto this branch?",
CherryPick: "Cherry-pick",
diff --git a/pkg/i18n/japanese.go b/pkg/i18n/japanese.go
index 660746384..3da17b097 100644
--- a/pkg/i18n/japanese.go
+++ b/pkg/i18n/japanese.go
@@ -201,9 +201,8 @@ func japaneseTranslationSet() TranslationSet {
// NoRoom: "Not enough room",
YouAreHere: "現在位置",
// LcRewordNotSupported: "Rewording commits while interactively rebasing is not currently supported",
- CherryPickCopy: "コミットをコピー (cherry-pick)",
- CherryPickCopyRange: "コミットを範囲コピー (cherry-pick)",
- PasteCommits: "コミットを貼り付け (cherry-pick)",
+ CherryPickCopy: "コミットをコピー (cherry-pick)",
+ PasteCommits: "コミットを貼り付け (cherry-pick)",
// SureCherryPick: "Are you sure you want to cherry-pick the copied commits onto this branch?",
CherryPick: "Cherry-Pick",
Donate: "支援",
diff --git a/pkg/i18n/korean.go b/pkg/i18n/korean.go
index ad23090e7..3c4d0ceab 100644
--- a/pkg/i18n/korean.go
+++ b/pkg/i18n/korean.go
@@ -199,7 +199,6 @@ func koreanTranslationSet() TranslationSet {
YouAreHere: "현재 위치",
RewordNotSupported: "Rewording commits while interactively rebasing is not currently supported",
CherryPickCopy: "커밋을 복사 (cherry-pick)",
- CherryPickCopyRange: "커밋을 범위로 복사 (cherry-pick)",
PasteCommits: "커밋을 붙여넣기 (cherry-pick)",
SureCherryPick: "정말로 복사한 커밋을 이 브랜치에 체리픽하시겠습니까?",
CherryPick: "체리픽",
diff --git a/pkg/i18n/polish.go b/pkg/i18n/polish.go
index ecab04281..e1515a948 100644
--- a/pkg/i18n/polish.go
+++ b/pkg/i18n/polish.go
@@ -131,7 +131,6 @@ func polishTranslationSet() TranslationSet {
YouAreHere: "JESTEŚ TU",
RewordNotSupported: "Przeredagowanie commitów podczas interaktywnej zmiany bazy nie jest obecnie wspierane",
CherryPickCopy: "Kopiuj commit (przebieranie)",
- CherryPickCopyRange: "Kopiuj zakres commitów (przebieranie)",
PasteCommits: "Wklej commity (przebieranie)",
SureCherryPick: "Czy na pewno chcesz przebierać w skopiowanych commitach na tej gałęzi?",
CherryPick: "Przebieranie",
diff --git a/pkg/i18n/russian.go b/pkg/i18n/russian.go
index 387e34974..1522a0f1c 100644
--- a/pkg/i18n/russian.go
+++ b/pkg/i18n/russian.go
@@ -243,7 +243,6 @@ func RussianTranslationSet() TranslationSet {
RewordNotSupported: "Переформулировка коммитов при интерактивном перебазировании в настоящее время не поддерживается",
ChangingThisActionIsNotAllowed: "Изменение этого типа записи todo перебазирования не допускается",
CherryPickCopy: "Скопировать отобранные коммит (cherry-pick)",
- CherryPickCopyRange: "Скопировать несколько отобранных коммитов (cherry-pick)",
PasteCommits: "Вставить отобранные коммиты (cherry-pick)",
SureCherryPick: "Вы уверены, что хотите выборочно применить (cherry-picked) отобранные коммиты в эту ветку?",
CherryPick: "Выборочная отборка (Cherry-Pick)",
diff --git a/pkg/i18n/traditional_chinese.go b/pkg/i18n/traditional_chinese.go
index 12207edcf..b9519bfcd 100644
--- a/pkg/i18n/traditional_chinese.go
+++ b/pkg/i18n/traditional_chinese.go
@@ -274,7 +274,6 @@ func traditionalChineseTranslationSet() TranslationSet {
RewordNotSupported: "在互動變基期間改寫提交目前不支持",
ChangingThisActionIsNotAllowed: "不允許更改此類變基待辦事項",
CherryPickCopy: "複製提交 (揀選)",
- CherryPickCopyRange: "複製提交範圍 (揀選)",
PasteCommits: "貼上提交 (揀選)",
SureCherryPick: "你確定要將複製的提交揀選到此分支嗎?",
CherryPick: "揀選 (Cherry-pick)",
diff --git a/pkg/integration/tests/cherry_pick/cherry_pick_range.go b/pkg/integration/tests/cherry_pick/cherry_pick_range.go
new file mode 100644
index 000000000..99b29618f
--- /dev/null
+++ b/pkg/integration/tests/cherry_pick/cherry_pick_range.go
@@ -0,0 +1,85 @@
+package cherry_pick
+
+import (
+ "github.com/jesseduffield/lazygit/pkg/config"
+ . "github.com/jesseduffield/lazygit/pkg/integration/components"
+)
+
+var CherryPickRange = NewIntegrationTest(NewIntegrationTestArgs{
+ Description: "Cherry pick range of commits from the subcommits view, without conflicts",
+ ExtraCmdArgs: []string{},
+ Skip: false,
+ SetupConfig: func(config *config.AppConfig) {},
+ SetupRepo: func(shell *Shell) {
+ shell.
+ EmptyCommit("base").
+ NewBranch("first-branch").
+ NewBranch("second-branch").
+ Checkout("first-branch").
+ EmptyCommit("one").
+ EmptyCommit("two").
+ Checkout("second-branch").
+ EmptyCommit("three").
+ EmptyCommit("four").
+ Checkout("first-branch")
+ },
+ Run: func(t *TestDriver, keys config.KeybindingConfig) {
+ t.Views().Branches().
+ Focus().
+ Lines(
+ Contains("first-branch"),
+ Contains("second-branch"),
+ Contains("master"),
+ ).
+ SelectNextItem().
+ PressEnter()
+
+ t.Views().SubCommits().
+ IsFocused().
+ Lines(
+ Contains("four").IsSelected(),
+ Contains("three"),
+ Contains("base"),
+ ).
+ // copy commits 'four' and 'three'
+ Press(keys.Universal.RangeSelectDown).
+ Lines(
+ Contains("four").IsSelected(),
+ Contains("three").IsSelected(),
+ Contains("base"),
+ ).
+ Press(keys.Commits.CherryPickCopy)
+
+ t.Views().Information().Content(Contains("2 commits copied"))
+
+ t.Views().Commits().
+ Focus().
+ Lines(
+ Contains("two").IsSelected(),
+ Contains("one"),
+ Contains("base"),
+ ).
+ Press(keys.Commits.PasteCommits).
+ Tap(func() {
+ t.ExpectPopup().Alert().
+ Title(Equals("Cherry-pick")).
+ Content(Contains("Are you sure you want to cherry-pick the copied commits onto this branch?")).
+ Confirm()
+ }).
+ Lines(
+ Contains("four"),
+ Contains("three"),
+ Contains("two"),
+ Contains("one"),
+ Contains("base"),
+ ).
+ Tap(func() {
+ // we need to manually exit out of cherry pick mode
+ t.Views().Information().Content(Contains("2 commits copied"))
+ }).
+ PressEscape().
+ Tap(func() {
+ t.Views().Information().Content(DoesNotContain("commits copied"))
+ })
+ },
+})
diff --git a/pkg/integration/tests/test_list.go b/pkg/integration/tests/test_list.go
index 5b8e21e4b..8541f9a5c 100644
--- a/pkg/integration/tests/test_list.go
+++ b/pkg/integration/tests/test_list.go
@@ -61,6 +61,7 @@ var tests = []*components.IntegrationTest{
cherry_pick.CherryPick,
cherry_pick.CherryPickConflicts,
cherry_pick.CherryPickDuringRebase,
+ cherry_pick.CherryPickRange,
commit.AddCoAuthor,
commit.Amend,
commit.Commit,