1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-07-28 16:02:01 +03:00

Use comment char config on interactive rebase

Co-authored-by: Stefan Haller <stefan@haller-berlin.de>
This commit is contained in:
Gustavo Krieger
2023-07-02 01:03:16 -03:00
parent 87fe30d50d
commit 9ae7710850
8 changed files with 53 additions and 42 deletions

View File

@ -10,6 +10,7 @@ import (
"github.com/fsmiamoto/git-todo-parser/todo" "github.com/fsmiamoto/git-todo-parser/todo"
"github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/common" "github.com/jesseduffield/lazygit/pkg/common"
"github.com/jesseduffield/lazygit/pkg/secureexec"
"github.com/jesseduffield/lazygit/pkg/utils" "github.com/jesseduffield/lazygit/pkg/utils"
"github.com/samber/lo" "github.com/samber/lo"
) )
@ -90,6 +91,15 @@ func getDaemonKind() DaemonKind {
return DaemonKind(intValue) return DaemonKind(intValue)
} }
func getCommentChar() byte {
cmd := secureexec.Command("git", "config", "--get", "--null", "core.commentChar")
if output, err := cmd.Output(); err == nil && len(output) == 2 {
return output[0]
}
return '#'
}
// An Instruction is a command to be run by lazygit in daemon mode. // An Instruction is a command to be run by lazygit in daemon mode.
// It is serialized to json and passed to lazygit via environment variables // It is serialized to json and passed to lazygit via environment variables
type Instruction interface { type Instruction interface {
@ -199,7 +209,7 @@ func (self *ChangeTodoActionsInstruction) SerializedInstructions() string {
func (self *ChangeTodoActionsInstruction) run(common *common.Common) error { func (self *ChangeTodoActionsInstruction) run(common *common.Common) error {
return handleInteractiveRebase(common, func(path string) error { return handleInteractiveRebase(common, func(path string) error {
for _, c := range self.Changes { for _, c := range self.Changes {
if err := utils.EditRebaseTodo(path, c.Sha, todo.Pick, c.NewAction); err != nil { if err := utils.EditRebaseTodo(path, c.Sha, todo.Pick, c.NewAction, getCommentChar()); err != nil {
return err return err
} }
} }
@ -233,7 +243,7 @@ func (self *MoveFixupCommitDownInstruction) SerializedInstructions() string {
func (self *MoveFixupCommitDownInstruction) run(common *common.Common) error { func (self *MoveFixupCommitDownInstruction) run(common *common.Common) error {
return handleInteractiveRebase(common, func(path string) error { return handleInteractiveRebase(common, func(path string) error {
return utils.MoveFixupCommitDown(path, self.OriginalSha, self.FixupSha) return utils.MoveFixupCommitDown(path, self.OriginalSha, self.FixupSha, getCommentChar())
}) })
} }
@ -257,7 +267,7 @@ func (self *MoveTodoUpInstruction) SerializedInstructions() string {
func (self *MoveTodoUpInstruction) run(common *common.Common) error { func (self *MoveTodoUpInstruction) run(common *common.Common) error {
return handleInteractiveRebase(common, func(path string) error { return handleInteractiveRebase(common, func(path string) error {
return utils.MoveTodoUp(path, self.Sha, todo.Pick) return utils.MoveTodoUp(path, self.Sha, todo.Pick, getCommentChar())
}) })
} }
@ -281,7 +291,7 @@ func (self *MoveTodoDownInstruction) SerializedInstructions() string {
func (self *MoveTodoDownInstruction) run(common *common.Common) error { func (self *MoveTodoDownInstruction) run(common *common.Common) error {
return handleInteractiveRebase(common, func(path string) error { return handleInteractiveRebase(common, func(path string) error {
return utils.MoveTodoDown(path, self.Sha, todo.Pick) return utils.MoveTodoDown(path, self.Sha, todo.Pick, getCommentChar())
}) })
} }

View File

@ -130,7 +130,7 @@ func NewGitCommandAux(
branchLoader := git_commands.NewBranchLoader(cmn, cmd, branchCommands.CurrentBranchInfo, configCommands) branchLoader := git_commands.NewBranchLoader(cmn, cmd, branchCommands.CurrentBranchInfo, configCommands)
commitFileLoader := git_commands.NewCommitFileLoader(cmn, cmd) commitFileLoader := git_commands.NewCommitFileLoader(cmn, cmd)
commitLoader := git_commands.NewCommitLoader(cmn, cmd, dotGitDir, statusCommands.RebaseMode) commitLoader := git_commands.NewCommitLoader(cmn, cmd, dotGitDir, statusCommands.RebaseMode, gitCommon)
reflogCommitLoader := git_commands.NewReflogCommitLoader(cmn, cmd) reflogCommitLoader := git_commands.NewReflogCommitLoader(cmn, cmd)
remoteLoader := git_commands.NewRemoteLoader(cmn, cmd, repo.Remotes) remoteLoader := git_commands.NewRemoteLoader(cmn, cmd, repo.Remotes)
stashLoader := git_commands.NewStashLoader(cmn, cmd) stashLoader := git_commands.NewStashLoader(cmn, cmd)

View File

@ -38,6 +38,7 @@ type CommitLoader struct {
// When nil, we're yet to obtain the list of existing main branches. // When nil, we're yet to obtain the list of existing main branches.
// When an empty slice, we've obtained the list and it's empty. // When an empty slice, we've obtained the list and it's empty.
mainBranches []string mainBranches []string
*GitCommon
} }
// making our dependencies explicit for the sake of easier testing // making our dependencies explicit for the sake of easier testing
@ -46,6 +47,7 @@ func NewCommitLoader(
cmd oscommands.ICmdObjBuilder, cmd oscommands.ICmdObjBuilder,
dotGitDir string, dotGitDir string,
getRebaseMode func() (enums.RebaseMode, error), getRebaseMode func() (enums.RebaseMode, error),
gitCommon *GitCommon,
) *CommitLoader { ) *CommitLoader {
return &CommitLoader{ return &CommitLoader{
Common: cmn, Common: cmn,
@ -55,6 +57,7 @@ func NewCommitLoader(
walkFiles: filepath.Walk, walkFiles: filepath.Walk,
dotGitDir: dotGitDir, dotGitDir: dotGitDir,
mainBranches: nil, mainBranches: nil,
GitCommon: gitCommon,
} }
} }
@ -304,7 +307,7 @@ func (self *CommitLoader) getInteractiveRebasingCommits() ([]*models.Commit, err
commits := []*models.Commit{} commits := []*models.Commit{}
todos, err := todo.Parse(bytes.NewBuffer(bytesContent), '#') todos, err := todo.Parse(bytes.NewBuffer(bytesContent), self.config.GetCoreCommentChar())
if err != nil { if err != nil {
self.Log.Error(fmt.Sprintf("error occurred while parsing git-rebase-todo file: %s", err.Error())) self.Log.Error(fmt.Sprintf("error occurred while parsing git-rebase-todo file: %s", err.Error()))
return nil, nil return nil, nil
@ -346,7 +349,7 @@ func (self *CommitLoader) getConflictedCommit(todos []todo.Todo) string {
return "" return ""
} }
doneTodos, err := todo.Parse(bytes.NewBuffer(bytesContent), '#') doneTodos, err := todo.Parse(bytes.NewBuffer(bytesContent), self.config.GetCoreCommentChar())
if err != nil { if err != nil {
self.Log.Error(fmt.Sprintf("error occurred while parsing rebase-merge/done file: %s", err.Error())) self.Log.Error(fmt.Sprintf("error occurred while parsing rebase-merge/done file: %s", err.Error()))
return "" return ""

View File

@ -99,3 +99,11 @@ func (self *ConfigCommands) Branches() (map[string]*config.Branch, error) {
func (self *ConfigCommands) GetGitFlowPrefixes() string { func (self *ConfigCommands) GetGitFlowPrefixes() string {
return self.gitConfig.GetGeneral("--local --get-regexp gitflow.prefix") return self.gitConfig.GetGeneral("--local --get-regexp gitflow.prefix")
} }
func (self *ConfigCommands) GetCoreCommentChar() byte {
if commentCharStr := self.gitConfig.Get("core.commentChar"); len(commentCharStr) == 1 {
return commentCharStr[0]
}
return '#'
}

View File

@ -243,19 +243,19 @@ func (self *RebaseCommands) AmendTo(commits []*models.Commit, commitIndex int) e
// EditRebaseTodo sets the action for a given rebase commit 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(commit *models.Commit, action todo.TodoCommand) error { func (self *RebaseCommands) EditRebaseTodo(commit *models.Commit, action todo.TodoCommand) error {
return utils.EditRebaseTodo( return utils.EditRebaseTodo(
filepath.Join(self.dotGitDir, "rebase-merge/git-rebase-todo"), commit.Sha, commit.Action, action) filepath.Join(self.dotGitDir, "rebase-merge/git-rebase-todo"), commit.Sha, commit.Action, action, self.config.GetCoreCommentChar())
} }
// MoveTodoDown moves a rebase todo item down by one position // MoveTodoDown moves a rebase todo item down by one position
func (self *RebaseCommands) MoveTodoDown(commit *models.Commit) error { func (self *RebaseCommands) MoveTodoDown(commit *models.Commit) error {
fileName := filepath.Join(self.dotGitDir, "rebase-merge/git-rebase-todo") fileName := filepath.Join(self.dotGitDir, "rebase-merge/git-rebase-todo")
return utils.MoveTodoDown(fileName, commit.Sha, commit.Action) return utils.MoveTodoDown(fileName, commit.Sha, commit.Action, self.config.GetCoreCommentChar())
} }
// MoveTodoDown moves a rebase todo item down by one position // MoveTodoDown moves a rebase todo item down by one position
func (self *RebaseCommands) MoveTodoUp(commit *models.Commit) error { func (self *RebaseCommands) MoveTodoUp(commit *models.Commit) error {
fileName := filepath.Join(self.dotGitDir, "rebase-merge/git-rebase-todo") fileName := filepath.Join(self.dotGitDir, "rebase-merge/git-rebase-todo")
return utils.MoveTodoUp(fileName, commit.Sha, commit.Action) return utils.MoveTodoUp(fileName, commit.Sha, commit.Action, self.config.GetCoreCommentChar())
} }
// SquashAllAboveFixupCommits squashes all fixup! commits above the given one // SquashAllAboveFixupCommits squashes all fixup! commits above the given one

View File

@ -27,16 +27,8 @@ var DropWithCustomCommentChar = NewIntegrationTest(NewIntegrationTestArgs{
Content(Equals("Are you sure you want to delete this commit?")). Content(Equals("Are you sure you want to delete this commit?")).
Confirm() Confirm()
}). }).
// The following behavior requires correction:
Tap(func() {
t.ExpectPopup().Alert().
Title(Equals("Error")).
Content(Contains("failed to parse line")).
Confirm()
}).
Lines( Lines(
Contains("commit 02").IsSelected(), Contains("commit 01").IsSelected(),
Contains("commit 01"),
) )
}, },
}) })

View File

@ -21,13 +21,11 @@ var MoveWithCustomCommentChar = NewIntegrationTest(NewIntegrationTestArgs{
Contains("commit 01"), Contains("commit 01"),
). ).
Press(keys.Commits.MoveDownCommit). Press(keys.Commits.MoveDownCommit).
// The following behavior requires correction: Lines(
Tap(func() { Contains("commit 01"),
t.ExpectPopup().Alert(). Contains("commit 02").IsSelected(),
Title(Equals("Error")). ).
Content(Contains("failed to parse line")). Press(keys.Commits.MoveUpCommit).
Confirm()
}).
Lines( Lines(
Contains("commit 02").IsSelected(), Contains("commit 02").IsSelected(),
Contains("commit 01"), Contains("commit 01"),

View File

@ -11,8 +11,8 @@ import (
// Read a git-rebase-todo file, change the action for the given sha to // Read a git-rebase-todo file, change the action for the given sha to
// newAction, and write it back // newAction, and write it back
func EditRebaseTodo(filePath string, sha string, oldAction todo.TodoCommand, newAction todo.TodoCommand) error { func EditRebaseTodo(filePath string, sha string, oldAction todo.TodoCommand, newAction todo.TodoCommand, commentChar byte) error {
todos, err := ReadRebaseTodoFile(filePath) todos, err := ReadRebaseTodoFile(filePath, commentChar)
if err != nil { if err != nil {
return err return err
} }
@ -24,7 +24,7 @@ func EditRebaseTodo(filePath string, sha string, oldAction todo.TodoCommand, new
// pick and later in a merge) // pick and later in a merge)
if t.Command == oldAction && equalShas(t.Commit, sha) { if t.Command == oldAction && equalShas(t.Commit, sha) {
t.Command = newAction t.Command = newAction
return WriteRebaseTodoFile(filePath, todos) return WriteRebaseTodoFile(filePath, todos, commentChar)
} }
} }
@ -36,13 +36,13 @@ func equalShas(a, b string) bool {
return strings.HasPrefix(a, b) || strings.HasPrefix(b, a) return strings.HasPrefix(a, b) || strings.HasPrefix(b, a)
} }
func ReadRebaseTodoFile(fileName string) ([]todo.Todo, error) { func ReadRebaseTodoFile(fileName string, commentChar byte) ([]todo.Todo, error) {
f, err := os.Open(fileName) f, err := os.Open(fileName)
if err != nil { if err != nil {
return nil, err return nil, err
} }
todos, err := todo.Parse(f, '#') todos, err := todo.Parse(f, commentChar)
err2 := f.Close() err2 := f.Close()
if err == nil { if err == nil {
err = err2 err = err2
@ -50,12 +50,12 @@ func ReadRebaseTodoFile(fileName string) ([]todo.Todo, error) {
return todos, err return todos, err
} }
func WriteRebaseTodoFile(fileName string, todos []todo.Todo) error { func WriteRebaseTodoFile(fileName string, todos []todo.Todo, commentChar byte) error {
f, err := os.Create(fileName) f, err := os.Create(fileName)
if err != nil { if err != nil {
return err return err
} }
err = todo.Write(f, todos, '#') err = todo.Write(f, todos, commentChar)
err2 := f.Close() err2 := f.Close()
if err == nil { if err == nil {
err = err2 err = err2
@ -73,8 +73,8 @@ func PrependStrToTodoFile(filePath string, linesToPrepend []byte) error {
return os.WriteFile(filePath, linesToPrepend, 0o644) return os.WriteFile(filePath, linesToPrepend, 0o644)
} }
func MoveTodoDown(fileName string, sha string, action todo.TodoCommand) error { func MoveTodoDown(fileName string, sha string, action todo.TodoCommand, commentChar byte) error {
todos, err := ReadRebaseTodoFile(fileName) todos, err := ReadRebaseTodoFile(fileName, commentChar)
if err != nil { if err != nil {
return err return err
} }
@ -82,11 +82,11 @@ func MoveTodoDown(fileName string, sha string, action todo.TodoCommand) error {
if err != nil { if err != nil {
return err return err
} }
return WriteRebaseTodoFile(fileName, rearrangedTodos) return WriteRebaseTodoFile(fileName, rearrangedTodos, commentChar)
} }
func MoveTodoUp(fileName string, sha string, action todo.TodoCommand) error { func MoveTodoUp(fileName string, sha string, action todo.TodoCommand, commentChar byte) error {
todos, err := ReadRebaseTodoFile(fileName) todos, err := ReadRebaseTodoFile(fileName, commentChar)
if err != nil { if err != nil {
return err return err
} }
@ -94,7 +94,7 @@ func MoveTodoUp(fileName string, sha string, action todo.TodoCommand) error {
if err != nil { if err != nil {
return err return err
} }
return WriteRebaseTodoFile(fileName, rearrangedTodos) return WriteRebaseTodoFile(fileName, rearrangedTodos, commentChar)
} }
func moveTodoDown(todos []todo.Todo, sha string, action todo.TodoCommand) ([]todo.Todo, error) { func moveTodoDown(todos []todo.Todo, sha string, action todo.TodoCommand) ([]todo.Todo, error) {
@ -134,8 +134,8 @@ func moveTodoUp(todos []todo.Todo, sha string, action todo.TodoCommand) ([]todo.
return rearrangedTodos, nil return rearrangedTodos, nil
} }
func MoveFixupCommitDown(fileName string, originalSha string, fixupSha string) error { func MoveFixupCommitDown(fileName string, originalSha string, fixupSha string, commentChar byte) error {
todos, err := ReadRebaseTodoFile(fileName) todos, err := ReadRebaseTodoFile(fileName, commentChar)
if err != nil { if err != nil {
return err return err
} }
@ -145,7 +145,7 @@ func MoveFixupCommitDown(fileName string, originalSha string, fixupSha string) e
return err return err
} }
return WriteRebaseTodoFile(fileName, newTodos) return WriteRebaseTodoFile(fileName, newTodos, commentChar)
} }
func moveFixupCommitDown(todos []todo.Todo, originalSha string, fixupSha string) ([]todo.Todo, error) { func moveFixupCommitDown(todos []todo.Todo, originalSha string, fixupSha string) ([]todo.Todo, error) {