summaryrefslogtreecommitdiffstats
path: root/pkg
diff options
context:
space:
mode:
authorStefan Haller <stefan@haller-berlin.de>2024-03-16 15:51:14 +0100
committerStefan Haller <stefan@haller-berlin.de>2024-03-16 22:01:03 +0100
commitbd975a8dcb4205998e9c2594351c0977ad2b6775 (patch)
tree80525f9bdda496e1e92f0ec039fa9547a42ed475 /pkg
parente5fa9e1c4afd84da9d6cabb510c13fb66ebc66f2 (diff)
Allow moving update-ref todos up/down
Diffstat (limited to 'pkg')
-rw-r--r--pkg/commands/git_commands/rebase.go18
-rw-r--r--pkg/gui/controllers/local_commits_controller.go25
-rw-r--r--pkg/integration/tests/interactive_rebase/move_update_ref_todo.go61
-rw-r--r--pkg/integration/tests/test_list.go1
-rw-r--r--pkg/utils/rebase_todo.go10
-rw-r--r--pkg/utils/rebase_todo_test.go30
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"},