diff options
author | Stefan Haller <stefan@haller-berlin.de> | 2024-03-16 15:51:14 +0100 |
---|---|---|
committer | Stefan Haller <stefan@haller-berlin.de> | 2024-03-16 22:01:03 +0100 |
commit | bd975a8dcb4205998e9c2594351c0977ad2b6775 (patch) | |
tree | 80525f9bdda496e1e92f0ec039fa9547a42ed475 /pkg | |
parent | e5fa9e1c4afd84da9d6cabb510c13fb66ebc66f2 (diff) |
Allow moving update-ref todos up/down
Diffstat (limited to 'pkg')
-rw-r--r-- | pkg/commands/git_commands/rebase.go | 18 | ||||
-rw-r--r-- | pkg/gui/controllers/local_commits_controller.go | 25 | ||||
-rw-r--r-- | pkg/integration/tests/interactive_rebase/move_update_ref_todo.go | 61 | ||||
-rw-r--r-- | pkg/integration/tests/test_list.go | 1 | ||||
-rw-r--r-- | pkg/utils/rebase_todo.go | 10 | ||||
-rw-r--r-- | pkg/utils/rebase_todo_test.go | 30 |
6 files changed, 132 insertions, 13 deletions
diff --git a/pkg/commands/git_commands/rebase.go b/pkg/commands/git_commands/rebase.go index 0bcfa5f67..c628ad414 100644 --- a/pkg/commands/git_commands/rebase.go +++ b/pkg/commands/git_commands/rebase.go @@ -272,6 +272,14 @@ func (self *RebaseCommands) AmendTo(commits []*models.Commit, commitIndex int) e }).Run() } +func todoFromCommit(commit *models.Commit) utils.Todo { + if commit.Action == todo.UpdateRef { + return utils.Todo{Ref: commit.Name, Action: commit.Action} + } else { + return utils.Todo{Sha: commit.Sha, Action: commit.Action} + } +} + // Sets the action for the given commits in the git-rebase-todo file func (self *RebaseCommands) EditRebaseTodo(commits []*models.Commit, action todo.TodoCommand) error { commitsWithAction := lo.Map(commits, func(commit *models.Commit, _ int) utils.TodoChange { @@ -292,10 +300,7 @@ func (self *RebaseCommands) EditRebaseTodo(commits []*models.Commit, action todo func (self *RebaseCommands) MoveTodosDown(commits []*models.Commit) error { fileName := filepath.Join(self.repoPaths.WorktreeGitDirPath(), "rebase-merge/git-rebase-todo") todosToMove := lo.Map(commits, func(commit *models.Commit, _ int) utils.Todo { - return utils.Todo{ - Sha: commit.Sha, - Action: commit.Action, - } + return todoFromCommit(commit) }) return utils.MoveTodosDown(fileName, todosToMove, self.config.GetCoreCommentChar()) @@ -304,10 +309,7 @@ func (self *RebaseCommands) MoveTodosDown(commits []*models.Commit) error { func (self *RebaseCommands) MoveTodosUp(commits []*models.Commit) error { fileName := filepath.Join(self.repoPaths.WorktreeGitDirPath(), "rebase-merge/git-rebase-todo") todosToMove := lo.Map(commits, func(commit *models.Commit, _ int) utils.Todo { - return utils.Todo{ - Sha: commit.Sha, - Action: commit.Action, - } + return todoFromCommit(commit) }) return utils.MoveTodosUp(fileName, todosToMove, self.config.GetCoreCommentChar()) diff --git a/pkg/gui/controllers/local_commits_controller.go b/pkg/gui/controllers/local_commits_controller.go index dba00f4b6..4dd19109b 100644 --- a/pkg/gui/controllers/local_commits_controller.go +++ b/pkg/gui/controllers/local_commits_controller.go @@ -179,7 +179,7 @@ func (self *LocalCommitsController) GetKeybindings(opts types.KeybindingsOpts) [ Key: opts.GetKey(opts.Config.Commits.MoveDownCommit), Handler: self.withItemsRange(self.moveDown), GetDisabledReason: self.require(self.itemRangeSelected( - self.midRebaseCommandEnabled, + self.midRebaseMoveCommandEnabled, self.canMoveDown, )), Description: self.c.Tr.MoveDownCommit, @@ -188,7 +188,7 @@ func (self *LocalCommitsController) GetKeybindings(opts types.KeybindingsOpts) [ Key: opts.GetKey(opts.Config.Commits.MoveUpCommit), Handler: self.withItemsRange(self.moveUp), GetDisabledReason: self.require(self.itemRangeSelected( - self.midRebaseCommandEnabled, + self.midRebaseMoveCommandEnabled, self.canMoveUp, )), Description: self.c.Tr.MoveUpCommit, @@ -1192,6 +1192,27 @@ func (self *LocalCommitsController) midRebaseCommandEnabled(selectedCommits []*m return nil } +// Ensures that if we are mid-rebase, we're only selecting commits that can be moved +func (self *LocalCommitsController) midRebaseMoveCommandEnabled(selectedCommits []*models.Commit, startIdx int, endIdx int) *types.DisabledReason { + if !self.isRebasing() { + return nil + } + + for _, commit := range selectedCommits { + if !commit.IsTODO() { + return &types.DisabledReason{Text: self.c.Tr.MustSelectTodoCommits} + } + + // All todo types that can be edited are allowed to be moved, plus + // update-ref todos + if !isChangeOfRebaseTodoAllowed(commit.Action) && commit.Action != todo.UpdateRef { + return &types.DisabledReason{Text: self.c.Tr.ChangingThisActionIsNotAllowed} + } + } + + return nil +} + // These actions represent standard things you might want to do with a commit, // as opposed to TODO actions like 'merge', 'update-ref', etc. var standardActions = []todo.TodoCommand{ diff --git a/pkg/integration/tests/interactive_rebase/move_update_ref_todo.go b/pkg/integration/tests/interactive_rebase/move_update_ref_todo.go new file mode 100644 index 000000000..3dbfcd9cb --- /dev/null +++ b/pkg/integration/tests/interactive_rebase/move_update_ref_todo.go @@ -0,0 +1,61 @@ +package interactive_rebase + +import ( + "github.com/jesseduffield/lazygit/pkg/config" + . "github.com/jesseduffield/lazygit/pkg/integration/components" +) + +var MoveUpdateRefTodo = NewIntegrationTest(NewIntegrationTestArgs{ + Description: "Move an update-ref item in the rebase todo list", + ExtraCmdArgs: []string{}, + Skip: false, + GitVersion: AtLeast("2.38.0"), + SetupConfig: func(config *config.AppConfig) {}, + SetupRepo: func(shell *Shell) { + shell. + NewBranch("branch1"). + CreateNCommits(3). + NewBranch("branch2"). + CreateNCommitsStartingAt(3, 4) + + shell.SetConfig("rebase.updateRefs", "true") + }, + Run: func(t *TestDriver, keys config.KeybindingConfig) { + t.Views().Commits(). + Focus(). + NavigateToLine(Contains("commit 01")). + Press(keys.Universal.Edit). + Lines( + Contains("pick").Contains("CI commit 06"), + Contains("pick").Contains("CI commit 05"), + Contains("pick").Contains("CI commit 04"), + Contains("update-ref").Contains("branch1"), + Contains("pick").Contains("CI commit 03"), + Contains("pick").Contains("CI commit 02"), + Contains("CI ◯ <-- YOU ARE HERE --- commit 01"), + ). + NavigateToLine(Contains("update-ref")). + Press(keys.Commits.MoveUpCommit). + Press(keys.Commits.MoveUpCommit). + Lines( + Contains("pick").Contains("CI commit 06"), + Contains("update-ref").Contains("branch1"), + Contains("pick").Contains("CI commit 05"), + Contains("pick").Contains("CI commit 04"), + Contains("pick").Contains("CI commit 03"), + Contains("pick").Contains("CI commit 02"), + Contains("CI ◯ <-- YOU ARE HERE --- commit 01"), + ). + Tap(func() { + t.Common().ContinueRebase() + }). + Lines( + Contains("CI ◯ commit 06"), + Contains("CI ◯ * commit 05"), + Contains("CI ◯ commit 04"), + Contains("CI ◯ commit 03"), + Contains("CI ◯ commit 02"), + Contains("CI ◯ commit 01"), + ) + }, +}) diff --git a/pkg/integration/tests/test_list.go b/pkg/integration/tests/test_list.go index e5a540e8b..be463fc87 100644 --- a/pkg/integration/tests/test_list.go +++ b/pkg/integration/tests/test_list.go @@ -176,6 +176,7 @@ var tests = []*components.IntegrationTest{ interactive_rebase.MidRebaseRangeSelect, interactive_rebase.Move, interactive_rebase.MoveInRebase, + interactive_rebase.MoveUpdateRefTodo, interactive_rebase.MoveWithCustomCommentChar, interactive_rebase.OutsideRebaseRangeSelect, interactive_rebase.PickRescheduled, diff --git a/pkg/utils/rebase_todo.go b/pkg/utils/rebase_todo.go index c0eda8f0b..f8a4de998 100644 --- a/pkg/utils/rebase_todo.go +++ b/pkg/utils/rebase_todo.go @@ -10,7 +10,8 @@ import ( ) type Todo struct { - Sha string + Sha string // for todos that have one, e.g. pick, drop, fixup, etc. + Ref string // for update-ref todos Action todo.TodoCommand } @@ -130,8 +131,11 @@ func moveTodoUp(todos []todo.Todo, todoToMove Todo) ([]todo.Todo, error) { _, sourceIdx, ok := lo.FindIndexOf(todos, func(t todo.Todo) bool { // Comparing just the sha is not enough; we need to compare both the // action and the sha, as the sha could appear multiple times (e.g. in a - // pick and later in a merge) - return t.Command == todoToMove.Action && equalShas(t.Commit, todoToMove.Sha) + // pick and later in a merge). For update-ref todos we also must compare + // the Ref. + return t.Command == todoToMove.Action && + equalShas(t.Commit, todoToMove.Sha) && + t.Ref == todoToMove.Ref }) if !ok { diff --git a/pkg/utils/rebase_todo_test.go b/pkg/utils/rebase_todo_test.go index fd736d7a0..458b4ee14 100644 --- a/pkg/utils/rebase_todo_test.go +++ b/pkg/utils/rebase_todo_test.go @@ -49,6 +49,21 @@ func TestRebaseCommands_moveTodoDown(t *testing.T) { }, }, { + testName: "move update-ref todo", + todos: []todo.Todo{ + {Command: todo.Pick, Commit: "1234"}, + {Command: todo.Pick, Commit: "5678"}, + {Command: todo.UpdateRef, Ref: "refs/heads/some_branch"}, + }, + todoToMoveDown: Todo{Ref: "refs/heads/some_branch", Action: todo.UpdateRef}, + expectedErr: "", + expectedTodos: []todo.Todo{ + {Command: todo.Pick, Commit: "1234"}, + {Command: todo.UpdateRef, Ref: "refs/heads/some_branch"}, + {Command: todo.Pick, Commit: "5678"}, + }, + }, + { testName: "skip an invisible todo", todos: []todo.Todo{ {Command: todo.Pick, Commit: "1234"}, @@ -160,6 +175,21 @@ func TestRebaseCommands_moveTodoUp(t *testing.T) { }, }, { + testName: "move update-ref todo", + todos: []todo.Todo{ + {Command: todo.Pick, Commit: "1234"}, + {Command: todo.UpdateRef, Ref: "refs/heads/some_branch"}, + {Command: todo.Pick, Commit: "5678"}, + }, + todoToMoveUp: Todo{Ref: "refs/heads/some_branch", Action: todo.UpdateRef}, + expectedErr: "", + expectedTodos: []todo.Todo{ + {Command: todo.Pick, Commit: "1234"}, + {Command: todo.Pick, Commit: "5678"}, + {Command: todo.UpdateRef, Ref: "refs/heads/some_branch"}, + }, + }, + { testName: "skip an invisible todo", todos: []todo.Todo{ {Command: todo.Pick, Commit: "1234"}, |