1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-03-17 21:18:31 +02:00

Merge pull request #1960 from fsmiamoto/fix-interactive-rebase

This commit is contained in:
Jesse Duffield 2022-06-13 12:44:07 +10:00 committed by GitHub
commit a5821f5ec8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 236 additions and 10 deletions

1
go.mod
View File

@ -9,6 +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.2
github.com/fsnotify/fsnotify v1.4.7
github.com/go-errors/errors v1.4.2
github.com/gookit/color v1.4.2

2
go.sum
View File

@ -28,6 +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.2 h1:l6Y+9q7jbM+yK/w6kASpHO7ejL9ARCErm3tCEqOT278=
github.com/fsmiamoto/git-todo-parser v0.0.2/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

@ -1,6 +1,7 @@
package loaders
import (
"bytes"
"fmt"
"io/ioutil"
"os"
@ -9,6 +10,7 @@ import (
"strconv"
"strings"
"github.com/fsmiamoto/git-todo-parser/todo"
"github.com/jesseduffield/generics/slices"
"github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
@ -307,21 +309,23 @@ func (self *CommitLoader) getInteractiveRebasingCommits() ([]*models.Commit, err
}
commits := []*models.Commit{}
lines := strings.Split(string(bytesContent), "\n")
for _, line := range lines {
if line == "" || line == "noop" {
return commits, nil
}
if strings.HasPrefix(line, "#") {
todos, err := todo.Parse(bytes.NewBuffer(bytesContent))
if err != nil {
self.Log.Error(fmt.Sprintf("error occurred while parsing git-rebase-todo file: %s", err.Error()))
return nil, nil
}
for _, t := range todos {
if t.Commit == "" {
// Command does not have a commit associated, skip
continue
}
splitLine := strings.Split(line, " ")
commits = slices.Prepend(commits, &models.Commit{
Sha: splitLine[1],
Name: strings.Join(splitLine[2:], " "),
Sha: t.Commit,
Name: t.Msg,
Status: "rebasing",
Action: splitLine[0],
Action: t.Command.String(),
})
}

View File

@ -0,0 +1,141 @@
package todo
import (
"bufio"
"errors"
"fmt"
"io"
"strings"
)
var (
ErrUnexpectedCommand = errors.New("unexpected command")
ErrMissingLabel = errors.New("missing label")
ErrMissingCommit = errors.New("missing commit")
ErrMissingExecCmd = errors.New("missing command for exec")
)
func Parse(f io.Reader) ([]Todo, error) {
var result []Todo
scanner := bufio.NewScanner(f)
scanner.Split(bufio.ScanLines)
for scanner.Scan() {
line := scanner.Text()
trimmed := strings.TrimSpace(line)
if trimmed == "" {
continue
}
cmd, err := parseLine(line)
if err != nil {
return nil, fmt.Errorf("failed to parse line %q: %w", line, err)
}
result = append(result, cmd)
}
if err := scanner.Err(); err != nil {
return nil, fmt.Errorf("failed to parse input: %w", err)
}
return result, nil
}
func parseLine(line string) (Todo, error) {
var todo Todo
if strings.HasPrefix(line, CommentChar) {
todo.Command = Comment
todo.Comment = strings.TrimLeft(line, CommentChar)
return todo, nil
}
fields := strings.Fields(line)
for i := TodoCommand(Pick); i < Comment; i++ {
if isCommand(i, fields[0]) {
todo.Command = TodoCommand(i)
fields = fields[1:]
break
}
}
if todo.Command == 0 {
// unexpected command
return todo, ErrUnexpectedCommand
}
if todo.Command == Break {
return todo, nil
}
if todo.Command == Label || todo.Command == Reset {
if len(fields) == 0 {
return todo, ErrMissingLabel
}
todo.Label = fields[0]
return todo, nil
}
if todo.Command == Exec {
if len(fields) == 0 {
return todo, ErrMissingExecCmd
}
todo.ExecCommand = strings.Join(fields, " ")
return todo, nil
}
if todo.Command == Merge {
if fields[0] == "-C" || fields[0] == "-c" {
fields = fields[1:]
if len(fields) == 0 {
return todo, ErrMissingCommit
}
todo.Commit = fields[0]
fields = fields[1:]
}
if len(fields) == 0 {
return todo, ErrMissingLabel
}
todo.Label = fields[0]
fields = fields[1:]
if fields[0] == "#" {
fields = fields[1:]
todo.Msg = strings.Join(fields, " ")
}
return todo, nil
}
if todo.Command == Fixup {
if len(fields) == 0 {
return todo, ErrMissingCommit
}
// Skip flags
if fields[0] == "-C" || fields[0] == "-c" {
fields = fields[1:]
}
}
if len(fields) == 0 {
return todo, ErrMissingCommit
}
todo.Commit = fields[0]
fields = fields[1:]
// Trim # and whitespace
todo.Msg = strings.TrimPrefix(strings.Join(fields, " "), CommentChar+" ")
return todo, nil
}
func isCommand(i TodoCommand, s string) bool {
if i < 0 || i > Comment {
return false
}
return len(s) > 0 &&
(todoCommandInfo[i].cmd == s || todoCommandInfo[i].nickname == s)
}

View File

@ -0,0 +1,75 @@
package todo
type TodoCommand int
const (
Pick TodoCommand = iota + 1
Revert
Edit
Reword
Fixup
Squash
Exec
Break
Label
Reset
Merge
NoOp
Drop
Comment
)
const CommentChar = "#"
type Todo struct {
Command TodoCommand
Commit string
Comment string
ExecCommand string
Label string
Msg string
}
func (t TodoCommand) String() string {
return commandToString[t]
}
var commandToString = map[TodoCommand]string{
Pick: "pick",
Revert: "revert",
Edit: "edit",
Reword: "reword",
Fixup: "fixup",
Squash: "squash",
Exec: "exec",
Break: "break",
Label: "label",
Reset: "reset",
Merge: "merge",
NoOp: "noop",
Drop: "drop",
Comment: "comment",
}
var todoCommandInfo = [14]struct {
nickname string
cmd string
}{
{"", ""}, // dummy value since we're using 1-based indexing
{"p", "pick"},
{"", "revert"},
{"e", "edit"},
{"r", "reword"},
{"f", "fixup"},
{"s", "squash"},
{"x", "exec"},
{"b", "break"},
{"l", "label"},
{"t", "reset"},
{"m", "merge"},
{"", "noop"},
{"d", "drop"},
}

3
vendor/modules.txt vendored
View File

@ -30,6 +30,9 @@ 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.2
## explicit; go 1.13
github.com/fsmiamoto/git-todo-parser/todo
# github.com/fsnotify/fsnotify v1.4.7
## explicit
github.com/fsnotify/fsnotify