1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-07-30 03:23:08 +03:00

Support range select in rebase actions

This commit is contained in:
Jesse Duffield
2024-01-08 11:49:42 +11:00
parent 44e2542e4a
commit f0de880136
26 changed files with 776 additions and 366 deletions

View File

@ -9,27 +9,46 @@ import (
"github.com/samber/lo"
)
// Read a git-rebase-todo file, change the action for the given sha to
// newAction, and write it back
func EditRebaseTodo(filePath string, sha string, oldAction todo.TodoCommand, newAction todo.TodoCommand, commentChar byte) error {
type Todo struct {
Sha string
Action todo.TodoCommand
}
// In order to change a TODO in git-rebase-todo, we need to specify the old action,
// because sometimes the same sha appears multiple times in the file (e.g. in a pick
// and later in a merge)
type TodoChange struct {
Sha string
OldAction todo.TodoCommand
NewAction todo.TodoCommand
}
// Read a git-rebase-todo file, change the actions for the given commits,
// and write it back
func EditRebaseTodo(filePath string, changes []TodoChange, commentChar byte) error {
todos, err := ReadRebaseTodoFile(filePath, commentChar)
if err != nil {
return err
}
matchCount := 0
for i := range todos {
t := &todos[i]
// 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)
if t.Command == oldAction && equalShas(t.Commit, sha) {
t.Command = newAction
return WriteRebaseTodoFile(filePath, todos, commentChar)
// This is a nested loop, but it's ok because the number of todos should be small
for _, change := range changes {
if t.Command == change.OldAction && equalShas(t.Commit, change.Sha) {
matchCount++
t.Command = change.NewAction
}
}
}
// Should never get here
return fmt.Errorf("Todo %s not found in git-rebase-todo", sha)
if matchCount < len(changes) {
// Should never get here
return fmt.Errorf("Some todos not found in git-rebase-todo")
}
return WriteRebaseTodoFile(filePath, todos, commentChar)
}
func equalShas(a, b string) bool {
@ -73,24 +92,24 @@ func PrependStrToTodoFile(filePath string, linesToPrepend []byte) error {
return os.WriteFile(filePath, linesToPrepend, 0o644)
}
func MoveTodoDown(fileName string, sha string, action todo.TodoCommand, commentChar byte) error {
func MoveTodosDown(fileName string, todosToMove []Todo, commentChar byte) error {
todos, err := ReadRebaseTodoFile(fileName, commentChar)
if err != nil {
return err
}
rearrangedTodos, err := moveTodoDown(todos, sha, action)
rearrangedTodos, err := moveTodosDown(todos, todosToMove)
if err != nil {
return err
}
return WriteRebaseTodoFile(fileName, rearrangedTodos, commentChar)
}
func MoveTodoUp(fileName string, sha string, action todo.TodoCommand, commentChar byte) error {
func MoveTodosUp(fileName string, todosToMove []Todo, commentChar byte) error {
todos, err := ReadRebaseTodoFile(fileName, commentChar)
if err != nil {
return err
}
rearrangedTodos, err := moveTodoUp(todos, sha, action)
rearrangedTodos, err := moveTodosUp(todos, todosToMove)
if err != nil {
return err
}
@ -102,6 +121,11 @@ func moveTodoDown(todos []todo.Todo, sha string, action todo.TodoCommand) ([]tod
return lo.Reverse(rearrangedTodos), err
}
func moveTodosDown(todos []todo.Todo, todosToMove []Todo) ([]todo.Todo, error) {
rearrangedTodos, err := moveTodosUp(lo.Reverse(todos), lo.Reverse(todosToMove))
return lo.Reverse(rearrangedTodos), err
}
func moveTodoUp(todos []todo.Todo, sha string, action todo.TodoCommand) ([]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
@ -134,6 +158,19 @@ func moveTodoUp(todos []todo.Todo, sha string, action todo.TodoCommand) ([]todo.
return rearrangedTodos, nil
}
func moveTodosUp(todos []todo.Todo, todosToMove []Todo) ([]todo.Todo, error) {
for _, todoToMove := range todosToMove {
var newTodos []todo.Todo
newTodos, err := moveTodoUp(todos, todoToMove.Sha, todoToMove.Action)
if err != nil {
return nil, err
}
todos = newTodos
}
return todos, nil
}
func MoveFixupCommitDown(fileName string, originalSha string, fixupSha string, commentChar byte) error {
todos, err := ReadRebaseTodoFile(fileName, commentChar)
if err != nil {