mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-07-28 16:02:01 +03:00
Allow moving update-ref todos up/down
This commit is contained in:
@ -272,6 +272,14 @@ func (self *RebaseCommands) AmendTo(commits []*models.Commit, commitIndex int) e
|
|||||||
}).Run()
|
}).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
|
// Sets the action for the given commits in the git-rebase-todo file
|
||||||
func (self *RebaseCommands) EditRebaseTodo(commits []*models.Commit, action todo.TodoCommand) error {
|
func (self *RebaseCommands) EditRebaseTodo(commits []*models.Commit, action todo.TodoCommand) error {
|
||||||
commitsWithAction := lo.Map(commits, func(commit *models.Commit, _ int) utils.TodoChange {
|
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 {
|
func (self *RebaseCommands) MoveTodosDown(commits []*models.Commit) error {
|
||||||
fileName := filepath.Join(self.repoPaths.WorktreeGitDirPath(), "rebase-merge/git-rebase-todo")
|
fileName := filepath.Join(self.repoPaths.WorktreeGitDirPath(), "rebase-merge/git-rebase-todo")
|
||||||
todosToMove := lo.Map(commits, func(commit *models.Commit, _ int) utils.Todo {
|
todosToMove := lo.Map(commits, func(commit *models.Commit, _ int) utils.Todo {
|
||||||
return utils.Todo{
|
return todoFromCommit(commit)
|
||||||
Sha: commit.Sha,
|
|
||||||
Action: commit.Action,
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
return utils.MoveTodosDown(fileName, todosToMove, self.config.GetCoreCommentChar())
|
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 {
|
func (self *RebaseCommands) MoveTodosUp(commits []*models.Commit) error {
|
||||||
fileName := filepath.Join(self.repoPaths.WorktreeGitDirPath(), "rebase-merge/git-rebase-todo")
|
fileName := filepath.Join(self.repoPaths.WorktreeGitDirPath(), "rebase-merge/git-rebase-todo")
|
||||||
todosToMove := lo.Map(commits, func(commit *models.Commit, _ int) utils.Todo {
|
todosToMove := lo.Map(commits, func(commit *models.Commit, _ int) utils.Todo {
|
||||||
return utils.Todo{
|
return todoFromCommit(commit)
|
||||||
Sha: commit.Sha,
|
|
||||||
Action: commit.Action,
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
return utils.MoveTodosUp(fileName, todosToMove, self.config.GetCoreCommentChar())
|
return utils.MoveTodosUp(fileName, todosToMove, self.config.GetCoreCommentChar())
|
||||||
|
@ -179,7 +179,7 @@ func (self *LocalCommitsController) GetKeybindings(opts types.KeybindingsOpts) [
|
|||||||
Key: opts.GetKey(opts.Config.Commits.MoveDownCommit),
|
Key: opts.GetKey(opts.Config.Commits.MoveDownCommit),
|
||||||
Handler: self.withItemsRange(self.moveDown),
|
Handler: self.withItemsRange(self.moveDown),
|
||||||
GetDisabledReason: self.require(self.itemRangeSelected(
|
GetDisabledReason: self.require(self.itemRangeSelected(
|
||||||
self.midRebaseCommandEnabled,
|
self.midRebaseMoveCommandEnabled,
|
||||||
self.canMoveDown,
|
self.canMoveDown,
|
||||||
)),
|
)),
|
||||||
Description: self.c.Tr.MoveDownCommit,
|
Description: self.c.Tr.MoveDownCommit,
|
||||||
@ -188,7 +188,7 @@ func (self *LocalCommitsController) GetKeybindings(opts types.KeybindingsOpts) [
|
|||||||
Key: opts.GetKey(opts.Config.Commits.MoveUpCommit),
|
Key: opts.GetKey(opts.Config.Commits.MoveUpCommit),
|
||||||
Handler: self.withItemsRange(self.moveUp),
|
Handler: self.withItemsRange(self.moveUp),
|
||||||
GetDisabledReason: self.require(self.itemRangeSelected(
|
GetDisabledReason: self.require(self.itemRangeSelected(
|
||||||
self.midRebaseCommandEnabled,
|
self.midRebaseMoveCommandEnabled,
|
||||||
self.canMoveUp,
|
self.canMoveUp,
|
||||||
)),
|
)),
|
||||||
Description: self.c.Tr.MoveUpCommit,
|
Description: self.c.Tr.MoveUpCommit,
|
||||||
@ -1192,6 +1192,27 @@ func (self *LocalCommitsController) midRebaseCommandEnabled(selectedCommits []*m
|
|||||||
return nil
|
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,
|
// These actions represent standard things you might want to do with a commit,
|
||||||
// as opposed to TODO actions like 'merge', 'update-ref', etc.
|
// as opposed to TODO actions like 'merge', 'update-ref', etc.
|
||||||
var standardActions = []todo.TodoCommand{
|
var standardActions = []todo.TodoCommand{
|
||||||
|
@ -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"),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
})
|
@ -176,6 +176,7 @@ var tests = []*components.IntegrationTest{
|
|||||||
interactive_rebase.MidRebaseRangeSelect,
|
interactive_rebase.MidRebaseRangeSelect,
|
||||||
interactive_rebase.Move,
|
interactive_rebase.Move,
|
||||||
interactive_rebase.MoveInRebase,
|
interactive_rebase.MoveInRebase,
|
||||||
|
interactive_rebase.MoveUpdateRefTodo,
|
||||||
interactive_rebase.MoveWithCustomCommentChar,
|
interactive_rebase.MoveWithCustomCommentChar,
|
||||||
interactive_rebase.OutsideRebaseRangeSelect,
|
interactive_rebase.OutsideRebaseRangeSelect,
|
||||||
interactive_rebase.PickRescheduled,
|
interactive_rebase.PickRescheduled,
|
||||||
|
@ -10,7 +10,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Todo struct {
|
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
|
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 {
|
_, sourceIdx, ok := lo.FindIndexOf(todos, func(t todo.Todo) bool {
|
||||||
// Comparing just the sha is not enough; we need to compare both the
|
// 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
|
// action and the sha, as the sha could appear multiple times (e.g. in a
|
||||||
// pick and later in a merge)
|
// pick and later in a merge). For update-ref todos we also must compare
|
||||||
return t.Command == todoToMove.Action && equalShas(t.Commit, todoToMove.Sha)
|
// the Ref.
|
||||||
|
return t.Command == todoToMove.Action &&
|
||||||
|
equalShas(t.Commit, todoToMove.Sha) &&
|
||||||
|
t.Ref == todoToMove.Ref
|
||||||
})
|
})
|
||||||
|
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -48,6 +48,21 @@ func TestRebaseCommands_moveTodoDown(t *testing.T) {
|
|||||||
{Command: todo.Pick, Commit: "5678"},
|
{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",
|
testName: "skip an invisible todo",
|
||||||
todos: []todo.Todo{
|
todos: []todo.Todo{
|
||||||
@ -159,6 +174,21 @@ func TestRebaseCommands_moveTodoUp(t *testing.T) {
|
|||||||
{Command: todo.Pick, Commit: "abcd"},
|
{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",
|
testName: "skip an invisible todo",
|
||||||
todos: []todo.Todo{
|
todos: []todo.Todo{
|
||||||
|
Reference in New Issue
Block a user