1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-04-17 12:06:38 +02:00

Allow moving update-ref todos up/down

This commit is contained in:
Stefan Haller 2024-03-16 15:51:14 +01:00
parent e5fa9e1c4a
commit bd975a8dcb
6 changed files with 132 additions and 13 deletions

View File

@ -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())

View File

@ -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{

View File

@ -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"),
)
},
})

View File

@ -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,

View File

@ -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 {

View File

@ -48,6 +48,21 @@ func TestRebaseCommands_moveTodoDown(t *testing.T) {
{Command: todo.Pick, Commit: "5678"},
},
},
{
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{
@ -159,6 +174,21 @@ func TestRebaseCommands_moveTodoUp(t *testing.T) {
{Command: todo.Pick, Commit: "abcd"},
},
},
{
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{