1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-01-10 04:07:18 +02:00

Use comment char on interactive rebase (#2639)

This commit is contained in:
Stefan Haller 2023-07-02 09:52:35 +02:00 committed by GitHub
commit 2be4359e87
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 132 additions and 43 deletions

2
go.mod
View File

@ -9,7 +9,7 @@ require (
github.com/cli/safeexec v1.0.0
github.com/cloudfoundry/jibber_jabber v0.0.0-20151120183258-bcc4c8345a21
github.com/creack/pty v1.1.11
github.com/fsmiamoto/git-todo-parser v0.0.4
github.com/fsmiamoto/git-todo-parser v0.0.5
github.com/fsnotify/fsnotify v1.4.7
github.com/gdamore/tcell/v2 v2.6.0
github.com/go-errors/errors v1.4.2

4
go.sum
View File

@ -28,8 +28,8 @@ github.com/fatih/color v1.7.1-0.20180516100307-2d684516a886/go.mod h1:Zm6kSWBoL9
github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s=
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
github.com/fsmiamoto/git-todo-parser v0.0.4 h1:fzcGaoAFDHWzJRKw//CSZFrXucsLKplIvOSab3FtWWM=
github.com/fsmiamoto/git-todo-parser v0.0.4/go.mod h1:B+AgTbNE2BARvJqzXygThzqxLIaEWvwr2sxKYYb0Fas=
github.com/fsmiamoto/git-todo-parser v0.0.5 h1:Bhzd/vz/6Qm3udfkd6NO9fWfD3TpwR9ucp3N75/J5I8=
github.com/fsmiamoto/git-todo-parser v0.0.5/go.mod h1:B+AgTbNE2BARvJqzXygThzqxLIaEWvwr2sxKYYb0Fas=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/gdamore/encoding v1.0.0 h1:+7OoQ1Bc6eTm5niUzBa0Ctsh6JbMW6Ra+YNuAtDBdko=

View File

@ -10,6 +10,7 @@ import (
"github.com/fsmiamoto/git-todo-parser/todo"
"github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/common"
"github.com/jesseduffield/lazygit/pkg/secureexec"
"github.com/jesseduffield/lazygit/pkg/utils"
"github.com/samber/lo"
)
@ -90,6 +91,15 @@ func getDaemonKind() DaemonKind {
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.
// It is serialized to json and passed to lazygit via environment variables
type Instruction interface {
@ -199,7 +209,7 @@ func (self *ChangeTodoActionsInstruction) SerializedInstructions() string {
func (self *ChangeTodoActionsInstruction) run(common *common.Common) error {
return handleInteractiveRebase(common, func(path string) error {
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
}
}
@ -233,7 +243,7 @@ func (self *MoveFixupCommitDownInstruction) SerializedInstructions() string {
func (self *MoveFixupCommitDownInstruction) run(common *common.Common) 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 {
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 {
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)
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)
remoteLoader := git_commands.NewRemoteLoader(cmn, cmd, repo.Remotes)
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 an empty slice, we've obtained the list and it's empty.
mainBranches []string
*GitCommon
}
// making our dependencies explicit for the sake of easier testing
@ -46,6 +47,7 @@ func NewCommitLoader(
cmd oscommands.ICmdObjBuilder,
dotGitDir string,
getRebaseMode func() (enums.RebaseMode, error),
gitCommon *GitCommon,
) *CommitLoader {
return &CommitLoader{
Common: cmn,
@ -55,6 +57,7 @@ func NewCommitLoader(
walkFiles: filepath.Walk,
dotGitDir: dotGitDir,
mainBranches: nil,
GitCommon: gitCommon,
}
}
@ -304,7 +307,7 @@ func (self *CommitLoader) getInteractiveRebasingCommits() ([]*models.Commit, err
commits := []*models.Commit{}
todos, err := todo.Parse(bytes.NewBuffer(bytesContent))
todos, err := todo.Parse(bytes.NewBuffer(bytesContent), self.config.GetCoreCommentChar())
if err != nil {
self.Log.Error(fmt.Sprintf("error occurred while parsing git-rebase-todo file: %s", err.Error()))
return nil, nil
@ -346,7 +349,7 @@ func (self *CommitLoader) getConflictedCommit(todos []todo.Todo) string {
return ""
}
doneTodos, err := todo.Parse(bytes.NewBuffer(bytesContent))
doneTodos, err := todo.Parse(bytes.NewBuffer(bytesContent), self.config.GetCoreCommentChar())
if err != nil {
self.Log.Error(fmt.Sprintf("error occurred while parsing rebase-merge/done file: %s", err.Error()))
return ""

View File

@ -99,3 +99,11 @@ func (self *ConfigCommands) Branches() (map[string]*config.Branch, error) {
func (self *ConfigCommands) GetGitFlowPrefixes() string {
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
func (self *RebaseCommands) EditRebaseTodo(commit *models.Commit, action todo.TodoCommand) error {
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
func (self *RebaseCommands) MoveTodoDown(commit *models.Commit) error {
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
func (self *RebaseCommands) MoveTodoUp(commit *models.Commit) error {
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

View File

@ -0,0 +1,34 @@
package interactive_rebase
import (
"github.com/jesseduffield/lazygit/pkg/config"
. "github.com/jesseduffield/lazygit/pkg/integration/components"
)
var DropWithCustomCommentChar = NewIntegrationTest(NewIntegrationTestArgs{
Description: "Drops a commit with the 'core.commentChar' option set to a custom character",
ExtraCmdArgs: []string{},
Skip: false,
SetupConfig: func(config *config.AppConfig) {},
SetupRepo: func(shell *Shell) {
shell.SetConfig("core.commentChar", ";")
shell.CreateNCommits(2)
},
Run: func(t *TestDriver, keys config.KeybindingConfig) {
t.Views().Commits().Focus().
Lines(
Contains("commit 02").IsSelected(),
Contains("commit 01"),
).
Press(keys.Universal.Remove).
Tap(func() {
t.ExpectPopup().Confirmation().
Title(Equals("Delete commit")).
Content(Equals("Are you sure you want to delete this commit?")).
Confirm()
}).
Lines(
Contains("commit 01").IsSelected(),
)
},
})

View File

@ -0,0 +1,34 @@
package interactive_rebase
import (
"github.com/jesseduffield/lazygit/pkg/config"
. "github.com/jesseduffield/lazygit/pkg/integration/components"
)
var MoveWithCustomCommentChar = NewIntegrationTest(NewIntegrationTestArgs{
Description: "Directly moves a commit down and back up with the 'core.commentChar' option set to a custom character",
ExtraCmdArgs: []string{},
Skip: false,
SetupConfig: func(config *config.AppConfig) {},
SetupRepo: func(shell *Shell) {
shell.SetConfig("core.commentChar", ";")
shell.CreateNCommits(2)
},
Run: func(t *TestDriver, keys config.KeybindingConfig) {
t.Views().Commits().Focus().
Lines(
Contains("commit 02").IsSelected(),
Contains("commit 01"),
).
Press(keys.Commits.MoveDownCommit).
Lines(
Contains("commit 01"),
Contains("commit 02").IsSelected(),
).
Press(keys.Commits.MoveUpCommit).
Lines(
Contains("commit 02").IsSelected(),
Contains("commit 01"),
)
},
})

View File

@ -103,6 +103,7 @@ var tests = []*components.IntegrationTest{
interactive_rebase.AmendNonHeadCommitDuringRebase,
interactive_rebase.DropTodoCommitWithUpdateRef,
interactive_rebase.DropTodoCommitWithUpdateRefShowBranchHeads,
interactive_rebase.DropWithCustomCommentChar,
interactive_rebase.EditFirstCommit,
interactive_rebase.EditNonTodoCommitDuringRebase,
interactive_rebase.EditTheConflCommit,
@ -110,6 +111,7 @@ var tests = []*components.IntegrationTest{
interactive_rebase.FixupSecondCommit,
interactive_rebase.Move,
interactive_rebase.MoveInRebase,
interactive_rebase.MoveWithCustomCommentChar,
interactive_rebase.PickRescheduled,
interactive_rebase.Rebase,
interactive_rebase.RewordCommitWithEditorAndFail,

View File

@ -11,8 +11,8 @@ import (
// 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) error {
todos, err := ReadRebaseTodoFile(filePath)
func EditRebaseTodo(filePath string, sha string, oldAction todo.TodoCommand, newAction todo.TodoCommand, commentChar byte) error {
todos, err := ReadRebaseTodoFile(filePath, commentChar)
if err != nil {
return err
}
@ -24,7 +24,7 @@ func EditRebaseTodo(filePath string, sha string, oldAction todo.TodoCommand, new
// pick and later in a merge)
if t.Command == oldAction && equalShas(t.Commit, sha) {
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)
}
func ReadRebaseTodoFile(fileName string) ([]todo.Todo, error) {
func ReadRebaseTodoFile(fileName string, commentChar byte) ([]todo.Todo, error) {
f, err := os.Open(fileName)
if err != nil {
return nil, err
}
todos, err := todo.Parse(f)
todos, err := todo.Parse(f, commentChar)
err2 := f.Close()
if err == nil {
err = err2
@ -50,12 +50,12 @@ func ReadRebaseTodoFile(fileName string) ([]todo.Todo, error) {
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)
if err != nil {
return err
}
err = todo.Write(f, todos)
err = todo.Write(f, todos, commentChar)
err2 := f.Close()
if err == nil {
err = err2
@ -73,8 +73,8 @@ func PrependStrToTodoFile(filePath string, linesToPrepend []byte) error {
return os.WriteFile(filePath, linesToPrepend, 0o644)
}
func MoveTodoDown(fileName string, sha string, action todo.TodoCommand) error {
todos, err := ReadRebaseTodoFile(fileName)
func MoveTodoDown(fileName string, sha string, action todo.TodoCommand, commentChar byte) error {
todos, err := ReadRebaseTodoFile(fileName, commentChar)
if err != nil {
return err
}
@ -82,11 +82,11 @@ func MoveTodoDown(fileName string, sha string, action todo.TodoCommand) error {
if err != nil {
return err
}
return WriteRebaseTodoFile(fileName, rearrangedTodos)
return WriteRebaseTodoFile(fileName, rearrangedTodos, commentChar)
}
func MoveTodoUp(fileName string, sha string, action todo.TodoCommand) error {
todos, err := ReadRebaseTodoFile(fileName)
func MoveTodoUp(fileName string, sha string, action todo.TodoCommand, commentChar byte) error {
todos, err := ReadRebaseTodoFile(fileName, commentChar)
if err != nil {
return err
}
@ -94,7 +94,7 @@ func MoveTodoUp(fileName string, sha string, action todo.TodoCommand) error {
if err != nil {
return err
}
return WriteRebaseTodoFile(fileName, rearrangedTodos)
return WriteRebaseTodoFile(fileName, rearrangedTodos, commentChar)
}
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
}
func MoveFixupCommitDown(fileName string, originalSha string, fixupSha string) error {
todos, err := ReadRebaseTodoFile(fileName)
func MoveFixupCommitDown(fileName string, originalSha string, fixupSha string, commentChar byte) error {
todos, err := ReadRebaseTodoFile(fileName, commentChar)
if err != nil {
return err
}
@ -145,7 +145,7 @@ func MoveFixupCommitDown(fileName string, originalSha string, fixupSha string) e
return err
}
return WriteRebaseTodoFile(fileName, newTodos)
return WriteRebaseTodoFile(fileName, newTodos, commentChar)
}
func moveFixupCommitDown(todos []todo.Todo, originalSha string, fixupSha string) ([]todo.Todo, error) {

View File

@ -16,7 +16,7 @@ var (
ErrMissingRef = errors.New("missing ref")
)
func Parse(f io.Reader) ([]Todo, error) {
func Parse(f io.Reader, commentChar byte) ([]Todo, error) {
var result []Todo
scanner := bufio.NewScanner(f)
@ -30,7 +30,7 @@ func Parse(f io.Reader) ([]Todo, error) {
continue
}
cmd, err := parseLine(line)
cmd, err := parseLine(line, commentChar)
if err != nil {
return nil, fmt.Errorf("failed to parse line %q: %w", line, err)
}
@ -45,12 +45,12 @@ func Parse(f io.Reader) ([]Todo, error) {
return result, nil
}
func parseLine(line string) (Todo, error) {
func parseLine(line string, commentChar byte) (Todo, error) {
var todo Todo
if strings.HasPrefix(line, CommentChar) {
if line[0] == commentChar {
todo.Command = Comment
todo.Comment = strings.TrimLeft(line, CommentChar)
todo.Comment = line[1:]
return todo, nil
}
@ -143,8 +143,8 @@ func parseLine(line string) (Todo, error) {
todo.Commit = fields[0]
fields = fields[1:]
// Trim # and whitespace
todo.Msg = strings.TrimPrefix(strings.Join(fields, " "), CommentChar+" ")
// Trim comment char and whitespace
todo.Msg = strings.TrimPrefix(strings.Join(fields, " "), fmt.Sprintf("%c ", commentChar))
return todo, nil
}

View File

@ -23,8 +23,6 @@ const (
Comment
)
const CommentChar = "#"
type Todo struct {
Command TodoCommand
Commit string

View File

@ -5,9 +5,9 @@ import (
"strings"
)
func Write(f io.Writer, todos []Todo) error {
func Write(f io.Writer, todos []Todo, commentChar byte) error {
for _, todo := range todos {
if err := writeTodo(f, todo); err != nil {
if err := writeTodo(f, todo, commentChar); err != nil {
return err
}
}
@ -15,7 +15,7 @@ func Write(f io.Writer, todos []Todo) error {
return nil
}
func writeTodo(f io.Writer, todo Todo) error {
func writeTodo(f io.Writer, todo Todo, commentChar byte) error {
var sb strings.Builder
if todo.Command != Comment {
sb.WriteString(todo.Command.String())
@ -26,7 +26,7 @@ func writeTodo(f io.Writer, todo Todo) error {
return nil
case Comment:
sb.WriteString(CommentChar)
sb.WriteByte(commentChar)
sb.WriteString(todo.Comment)
case Break:

2
vendor/modules.txt vendored
View File

@ -30,7 +30,7 @@ github.com/emirpasic/gods/utils
# github.com/fatih/color v1.9.0
## explicit; go 1.13
github.com/fatih/color
# github.com/fsmiamoto/git-todo-parser v0.0.4
# github.com/fsmiamoto/git-todo-parser v0.0.5
## explicit; go 1.13
github.com/fsmiamoto/git-todo-parser/todo
# github.com/fsnotify/fsnotify v1.4.7