mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-04-19 12:12:42 +02:00
Make EditRebaseTodo more robust
It used to work on the assumption that rebasing commits in lazygit's model correspond one-to-one to lines in the git-rebase-todo file, which isn't necessarily true (e.g. when users use "git rebase --edit-todo" at the custom command prompt and add a "break" between lines).
This commit is contained in:
parent
860a8d102b
commit
120dd1530a
@ -12,6 +12,7 @@ import (
|
|||||||
"github.com/jesseduffield/lazygit/pkg/app/daemon"
|
"github.com/jesseduffield/lazygit/pkg/app/daemon"
|
||||||
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
||||||
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
|
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
|
||||||
|
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
type RebaseCommands struct {
|
type RebaseCommands struct {
|
||||||
@ -202,25 +203,27 @@ func (self *RebaseCommands) AmendTo(commit *models.Commit) error {
|
|||||||
return self.SquashAllAboveFixupCommits(commit)
|
return self.SquashAllAboveFixupCommits(commit)
|
||||||
}
|
}
|
||||||
|
|
||||||
// EditRebaseTodo sets the action at a given index in the git-rebase-todo file
|
// EditRebaseTodo sets the action for a given rebase commit in the git-rebase-todo file
|
||||||
func (self *RebaseCommands) EditRebaseTodo(index int, action todo.TodoCommand) error {
|
func (self *RebaseCommands) EditRebaseTodo(commit *models.Commit, action todo.TodoCommand) error {
|
||||||
fileName := filepath.Join(self.dotGitDir, "rebase-merge/git-rebase-todo")
|
fileName := filepath.Join(self.dotGitDir, "rebase-merge/git-rebase-todo")
|
||||||
bytes, err := os.ReadFile(fileName)
|
todos, err := utils.ReadRebaseTodoFile(fileName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
content := strings.Split(string(bytes), "\n")
|
for i := range todos {
|
||||||
commitCount := self.getTodoCommitCount(content)
|
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 == commit.Action && t.Commit == commit.Sha {
|
||||||
|
t.Command = action
|
||||||
|
return utils.WriteRebaseTodoFile(fileName, todos)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// we have the most recent commit at the bottom whereas the todo file has
|
// Should never get here
|
||||||
// it at the bottom, so we need to subtract our index from the commit count
|
return fmt.Errorf("Todo %s not found in git-rebase-todo", commit.Sha)
|
||||||
contentIndex := commitCount - 1 - index
|
|
||||||
splitLine := strings.Split(content[contentIndex], " ")
|
|
||||||
content[contentIndex] = action.String() + " " + strings.Join(splitLine[1:], " ")
|
|
||||||
result := strings.Join(content, "\n")
|
|
||||||
|
|
||||||
return os.WriteFile(fileName, []byte(result), 0o644)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *RebaseCommands) getTodoCommitCount(content []string) int {
|
func (self *RebaseCommands) getTodoCommitCount(content []string) int {
|
||||||
|
@ -354,9 +354,7 @@ func (self *LocalCommitsController) handleMidRebaseCommand(action todo.TodoComma
|
|||||||
false,
|
false,
|
||||||
)
|
)
|
||||||
|
|
||||||
if err := self.git.Rebase.EditRebaseTodo(
|
if err := self.git.Rebase.EditRebaseTodo(commit, action); err != nil {
|
||||||
self.context().GetSelectedLineIdx(), action,
|
|
||||||
); err != nil {
|
|
||||||
return false, self.c.Error(err)
|
return false, self.c.Error(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,10 +60,7 @@ var DropTodoCommitWithUpdateRef = NewIntegrationTest(NewIntegrationTestArgs{
|
|||||||
IsFocused().
|
IsFocused().
|
||||||
Lines(
|
Lines(
|
||||||
Contains("(*) commit 06"),
|
Contains("(*) commit 06"),
|
||||||
/* EXPECTED:
|
|
||||||
Contains("commit 04"),
|
Contains("commit 04"),
|
||||||
ACTUAL: */
|
|
||||||
Contains("commit 05"),
|
|
||||||
Contains("(*) commit 03"),
|
Contains("(*) commit 03"),
|
||||||
Contains("commit 02"),
|
Contains("commit 02"),
|
||||||
Contains("commit 01"),
|
Contains("commit 01"),
|
||||||
|
34
pkg/utils/rebaseTodo.go
Normal file
34
pkg/utils/rebaseTodo.go
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/fsmiamoto/git-todo-parser/todo"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ReadRebaseTodoFile(fileName string) ([]todo.Todo, error) {
|
||||||
|
f, err := os.Open(fileName)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
todos, err := todo.Parse(f)
|
||||||
|
err2 := f.Close()
|
||||||
|
if err == nil {
|
||||||
|
err = err2
|
||||||
|
}
|
||||||
|
return todos, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func WriteRebaseTodoFile(fileName string, todos []todo.Todo) error {
|
||||||
|
f, err := os.Create(fileName)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = todo.Write(f, todos)
|
||||||
|
err2 := f.Close()
|
||||||
|
if err == nil {
|
||||||
|
err = err2
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user