summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Haller <stefan@haller-berlin.de>2024-03-09 07:46:34 +0100
committerGitHub <noreply@github.com>2024-03-09 07:46:34 +0100
commitbbc680266b37d32ebb84d9357ef7aaf6e13559b5 (patch)
tree252aab39302a832ba5d4dc77ebe31db038db0b28
parent44f553b6093c69d09718f617e0a7659c64f51015 (diff)
parent40232440b7249b8e214265cbb13a9c84bf5e2d05 (diff)
Support setting a range of commits to "edit" outside of a rebase (#3370)
- **PR Description** It is now possible to select a range of commits (while not in a rebase), and hit "e" to edit them all. This starts a rebase on the bottom-most commit of the range, and sets all the selected commits to "edit" (skipping merge commits, because they can't be edited).
-rw-r--r--pkg/gui/controllers/local_commits_controller.go31
-rw-r--r--pkg/integration/tests/interactive_rebase/edit_range_select_outside_rebase.go51
-rw-r--r--pkg/integration/tests/interactive_rebase/mid_rebase_range_select.go21
-rw-r--r--pkg/integration/tests/test_list.go1
4 files changed, 70 insertions, 34 deletions
diff --git a/pkg/gui/controllers/local_commits_controller.go b/pkg/gui/controllers/local_commits_controller.go
index 68a0ea742..d290192e4 100644
--- a/pkg/gui/controllers/local_commits_controller.go
+++ b/pkg/gui/controllers/local_commits_controller.go
@@ -115,7 +115,6 @@ func (self *LocalCommitsController) GetKeybindings(opts types.KeybindingsOpts) [
{
Key: opts.GetKey(editCommitKey),
Handler: self.withItems(self.edit),
- // TODO: have disabled reason ensure that if we're not rebasing, we only select one commit
GetDisabledReason: self.require(
self.itemRangeSelected(self.midRebaseCommandEnabled),
),
@@ -457,15 +456,7 @@ func (self *LocalCommitsController) edit(selectedCommits []*models.Commit) error
return self.updateTodos(todo.Edit, selectedCommits)
}
- // TODO: support range select here (start a rebase and set the selected commits
- // to 'edit' in the todo file)
- if len(selectedCommits) > 1 {
- return self.c.ErrorMsg(self.c.Tr.RangeSelectNotSupported)
- }
-
- selectedCommit := selectedCommits[0]
-
- return self.startInteractiveRebaseWithEdit(selectedCommit)
+ return self.startInteractiveRebaseWithEdit(selectedCommits)
}
func (self *LocalCommitsController) quickStartInteractiveRebase() error {
@@ -474,11 +465,11 @@ func (self *LocalCommitsController) quickStartInteractiveRebase() error {
return self.c.Error(err)
}
- return self.startInteractiveRebaseWithEdit(commitToEdit)
+ return self.startInteractiveRebaseWithEdit([]*models.Commit{commitToEdit})
}
func (self *LocalCommitsController) startInteractiveRebaseWithEdit(
- commitToEdit *models.Commit,
+ commitsToEdit []*models.Commit,
) error {
return self.c.WithWaitingStatus(self.c.Tr.RebasingStatus, func(gocui.Task) error {
self.c.LogAction(self.c.Tr.Actions.EditCommit)
@@ -486,10 +477,24 @@ func (self *LocalCommitsController) startInteractiveRebaseWithEdit(
commits := self.c.Model().Commits
selectedSha := commits[selectedIdx].Sha
rangeStartSha := commits[rangeStartIdx].Sha
- err := self.c.Git().Rebase.EditRebase(commitToEdit.Sha)
+ err := self.c.Git().Rebase.EditRebase(commitsToEdit[len(commitsToEdit)-1].Sha)
return self.c.Helpers().MergeAndRebase.CheckMergeOrRebaseWithRefreshOptions(
err,
types.RefreshOptions{Mode: types.BLOCK_UI, Then: func() {
+ todos := make([]*models.Commit, 0, len(commitsToEdit)-1)
+ for _, c := range commitsToEdit[:len(commitsToEdit)-1] {
+ // Merge commits can't be set to "edit", so just skip them
+ if !c.IsMerge() {
+ todos = append(todos, &models.Commit{Sha: c.Sha, Action: todo.Pick})
+ }
+ }
+ if len(todos) > 0 {
+ err := self.updateTodos(todo.Edit, todos)
+ if err != nil {
+ _ = self.c.Error(err)
+ }
+ }
+
// We need to select the same commit range again because after starting a rebase,
// new lines can be added for update-ref commands in the TODO file, due to
// stacked branches. So the selected commits may be in different positions in the list.
diff --git a/pkg/integration/tests/interactive_rebase/edit_range_select_outside_rebase.go b/pkg/integration/tests/interactive_rebase/edit_range_select_outside_rebase.go
new file mode 100644
index 000000000..4ff2a8c83
--- /dev/null
+++ b/pkg/integration/tests/interactive_rebase/edit_range_select_outside_rebase.go
@@ -0,0 +1,51 @@
+package interactive_rebase
+
+import (
+ "github.com/jesseduffield/lazygit/pkg/config"
+ . "github.com/jesseduffield/lazygit/pkg/integration/components"
+ "github.com/jesseduffield/lazygit/pkg/integration/tests/shared"
+)
+
+var EditRangeSelectOutsideRebase = NewIntegrationTest(NewIntegrationTestArgs{
+ Description: "Select a range of commits to edit outside of a rebase",
+ ExtraCmdArgs: []string{},
+ Skip: false,
+ GitVersion: AtLeast("2.22.0"), // first version that supports the --rebase-merges option
+ SetupConfig: func(config *config.AppConfig) {},
+ SetupRepo: func(shell *Shell) {
+ shared.CreateMergeCommit(shell)
+ },
+ Run: func(t *TestDriver, keys config.KeybindingConfig) {
+ t.Views().Commits().
+ Focus().
+ TopLines(
+ Contains("Merge branch 'second-change-branch' into first-change-branch").IsSelected(),
+ ).
+ Press(keys.Universal.RangeSelectDown).
+ Press(keys.Universal.RangeSelectDown).
+ Press(keys.Universal.RangeSelectDown).
+ Press(keys.Universal.RangeSelectDown).
+ Press(keys.Universal.RangeSelectDown).
+ Lines(
+ Contains("CI ⏣─╮ Merge branch 'second-change-branch' into first-change-branch").IsSelected(),
+ Contains("CI │ ◯ * second-change-branch unrelated change").IsSelected(),
+ Contains("CI │ ◯ second change").IsSelected(),
+ Contains("CI ◯ │ first change").IsSelected(),
+ Contains("CI ◯─╯ * original").IsSelected(),
+ Contains("CI ◯ three").IsSelected(),
+ Contains("CI ◯ two"),
+ Contains("CI ◯ one"),
+ ).
+ Press(keys.Universal.Edit).
+ Lines(
+ Contains("merge CI Merge branch 'second-change-branch' into first-change-branch").IsSelected(),
+ Contains("edit CI first change").IsSelected(),
+ Contains("edit CI * second-change-branch unrelated change").IsSelected(),
+ Contains("edit CI second change").IsSelected(),
+ Contains("edit CI * original").IsSelected(),
+ Contains(" CI ◯ <-- YOU ARE HERE --- three").IsSelected(),
+ Contains(" CI ◯ two"),
+ Contains(" CI ◯ one"),
+ )
+ },
+})
diff --git a/pkg/integration/tests/interactive_rebase/mid_rebase_range_select.go b/pkg/integration/tests/interactive_rebase/mid_rebase_range_select.go
index 6dcb12ea6..c94b63295 100644
--- a/pkg/integration/tests/interactive_rebase/mid_rebase_range_select.go
+++ b/pkg/integration/tests/interactive_rebase/mid_rebase_range_select.go
@@ -20,27 +20,6 @@ var MidRebaseRangeSelect = NewIntegrationTest(NewIntegrationTestArgs{
TopLines(
Contains("commit 10").IsSelected(),
).
- NavigateToLine(Contains("commit 07")).
- Press(keys.Universal.RangeSelectDown).
- TopLines(
- Contains("commit 10"),
- Contains("commit 09"),
- Contains("commit 08"),
- Contains("commit 07").IsSelected(),
- Contains("commit 06").IsSelected(),
- Contains("commit 05"),
- Contains("commit 04"),
- ).
- // Verify we can't perform an edit on multiple commits (it's not supported
- // yet)
- Press(keys.Universal.Edit).
- Tap(func() {
- // This ought to be a toast but I'm too lazy to implement that right now.
- t.ExpectPopup().Alert().
- Title(Equals("Error")).
- Content(Contains("Action does not support range selection, please select a single item")).
- Confirm()
- }).
NavigateToLine(Contains("commit 05")).
// Start a rebase
Press(keys.Universal.Edit).
diff --git a/pkg/integration/tests/test_list.go b/pkg/integration/tests/test_list.go
index 531fce5d9..d0525fa59 100644
--- a/pkg/integration/tests/test_list.go
+++ b/pkg/integration/tests/test_list.go
@@ -167,6 +167,7 @@ var tests = []*components.IntegrationTest{
interactive_rebase.DropWithCustomCommentChar,
interactive_rebase.EditFirstCommit,
interactive_rebase.EditNonTodoCommitDuringRebase,
+ interactive_rebase.EditRangeSelectOutsideRebase,
interactive_rebase.EditTheConflCommit,
interactive_rebase.FixupFirstCommit,
interactive_rebase.FixupSecondCommit,