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:
@ -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 {
|
||||
|
Reference in New Issue
Block a user