summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--pkg/commands/commit.go60
-rw-r--r--pkg/commands/commit_list_builder.go80
-rw-r--r--pkg/gui/commits_panel.go6
-rw-r--r--pkg/gui/gui.go8
-rw-r--r--pkg/gui/presentation/commits.go126
-rw-r--r--pkg/gui/view_helpers.go9
-rw-r--r--pkg/utils/utils.go19
7 files changed, 204 insertions, 104 deletions
diff --git a/pkg/commands/commit.go b/pkg/commands/commit.go
index f60e98abd..4d440d5e3 100644
--- a/pkg/commands/commit.go
+++ b/pkg/commands/commit.go
@@ -1,13 +1,5 @@
package commands
-import (
- "strings"
-
- "github.com/fatih/color"
- "github.com/jesseduffield/lazygit/pkg/theme"
- "github.com/jesseduffield/lazygit/pkg/utils"
-)
-
// Commit : A git commit
type Commit struct {
Sha string
@@ -17,53 +9,7 @@ type Commit struct {
Action string // one of "", "pick", "edit", "squash", "reword", "drop", "fixup"
Copied bool // to know if this commit is ready to be cherry-picked somewhere
Tags []string
-}
-
-// GetDisplayStrings is a function.
-func (c *Commit) GetDisplayStrings(isFocused bool) []string {
- red := color.New(color.FgRed)
- yellow := color.New(color.FgYellow)
- green := color.New(color.FgGreen)
- blue := color.New(color.FgBlue)
- cyan := color.New(color.FgCyan)
- defaultColor := color.New(theme.DefaultTextColor)
- magenta := color.New(color.FgMagenta)
-
- // for some reason, setting the background to blue pads out the other commits
- // horizontally. For the sake of accessibility I'm considering this a feature,
- // not a bug
- copied := color.New(color.FgCyan, color.BgBlue)
-
- var shaColor *color.Color
- switch c.Status {
- case "unpushed":
- shaColor = red
- case "pushed":
- shaColor = yellow
- case "merged":
- shaColor = green
- case "rebasing":
- shaColor = blue
- case "reflog":
- shaColor = blue
- case "selected":
- shaColor = magenta
- default:
- shaColor = defaultColor
- }
-
- if c.Copied {
- shaColor = copied
- }
-
- actionString := ""
- tagString := ""
- if c.Action != "" {
- actionString = cyan.Sprint(utils.WithPadding(c.Action, 7)) + " "
- } else if len(c.Tags) > 0 {
- tagColor := color.New(color.FgMagenta, color.Bold)
- tagString = utils.ColoredStringDirect(strings.Join(c.Tags, " "), tagColor) + " "
- }
-
- return []string{shaColor.Sprint(c.Sha[:8]), actionString + tagString + defaultColor.Sprint(c.Name)}
+ ExtraInfo string // something like 'HEAD -> master, tag: v0.15.2'
+ Author string
+ Date string
}
diff --git a/pkg/commands/commit_list_builder.go b/pkg/commands/commit_list_builder.go
index cf33fcac1..1e621f4e4 100644
--- a/pkg/commands/commit_list_builder.go
+++ b/pkg/commands/commit_list_builder.go
@@ -23,6 +23,8 @@ import (
// if we find out we need to use one of these functions in the git.go file, we
// can just pull them out of here and put them there and then call them from in here
+const SEPARATION_CHAR = "|"
+
// CommitListBuilder returns a list of Branch objects for the current repo
type CommitListBuilder struct {
Log *logrus.Entry
@@ -45,42 +47,37 @@ func NewCommitListBuilder(log *logrus.Entry, gitCommand *GitCommand, osCommand *
}, nil
}
-// nameAndTag takes a line from a git log and extracts the sha, message and tag (if present)
-// example inputs:
-// 66e6369c284e96ed5af5 (tag: v0.14.4) allow fastforwarding the current branch
-// 32e650e0bb3f4327749f (HEAD -> show-tags) this is my commit
-// 32e650e0bb3f4327749e this is my other commit
-func (c *CommitListBuilder) commitLineParts(line string) (string, string, []string) {
- re := regexp.MustCompile(`(\w+) (.*)`)
- shaMatch := re.FindStringSubmatch(line)
-
- if len(shaMatch) <= 1 {
- return line, "", nil
- }
- sha := shaMatch[1]
- rest := shaMatch[2]
-
- if !strings.HasPrefix(rest, "(") {
- return sha, rest, nil
- }
-
- re = regexp.MustCompile(`\((.*)\) (.*)`)
-
- parensMatch := re.FindStringSubmatch(rest)
- if len(parensMatch) <= 1 {
- return sha, rest, nil
+// extractCommitFromLine takes a line from a git log and extracts the sha, message, date, and tag if present
+// then puts them into a commit object
+// example input:
+// 8ad01fe32fcc20f07bc6693f87aa4977c327f1e1|10 hours ago|Jesse Duffield| (HEAD -> master, tag: v0.15.2)|refresh commits when adding a tag
+func (c *CommitListBuilder) extractCommitFromLine(line string) *Commit {
+ split := strings.Split(line, SEPARATION_CHAR)
+
+ sha := split[0]
+ date := split[1]
+ author := split[2]
+ extraInfo := strings.TrimSpace(split[3])
+ message := strings.Join(split[4:len(split)], SEPARATION_CHAR)
+ tags := []string{}
+
+ if extraInfo != "" {
+ re := regexp.MustCompile(`tag: ([^,\)]+)`)
+ tagMatch := re.FindStringSubmatch(extraInfo)
+ if len(tagMatch) > 1 {
+ tags = append(tags, tagMatch[1])
+ }
}
- notes := parensMatch[1]
- message := parensMatch[2]
- re = regexp.MustCompile(`tag: ([^,]+)`)
- tagMatch := re.FindStringSubmatch(notes)
- if len(tagMatch) <= 1 {
- return sha, message, nil
+ return &Commit{
+ Sha: sha,
+ Name: message,
+ DisplayString: line,
+ Tags: tags,
+ ExtraInfo: extraInfo,
+ Date: date,
+ Author: author,
}
-
- tag := tagMatch[1]
- return sha, message, []string{tag}
}
// GetCommits obtains the commits of the current branch
@@ -107,16 +104,10 @@ func (c *CommitListBuilder) GetCommits(limit bool) ([]*Commit, error) {
// now we can split it up and turn it into commits
for _, line := range utils.SplitLines(log) {
- sha, name, tags := c.commitLineParts(line)
- _, unpushed := unpushedCommits[sha]
- status := map[bool]string{true: "unpushed", false: "pushed"}[unpushed]
- commits = append(commits, &Commit{
- Sha: sha,
- Name: name,
- Status: status,
- DisplayString: line,
- Tags: tags,
- })
+ commit := c.extractCommitFromLine(line)
+ _, unpushed := unpushedCommits[commit.Sha]
+ commit.Status = map[bool]string{true: "unpushed", false: "pushed"}[unpushed]
+ commits = append(commits, commit)
}
if rebaseMode != "" {
currentCommit := commits[len(rebasingCommits)]
@@ -325,7 +316,8 @@ func (c *CommitListBuilder) getLog(limit bool) string {
limitFlag = "-30"
}
- result, err := c.OSCommand.RunCommandWithOutput(fmt.Sprintf("git log --decorate --oneline %s --abbrev=%d", limitFlag, 20))
+ result, err := c.OSCommand.RunCommandWithOutput(fmt.Sprintf("git log --oneline --pretty=format:\"%%H%s%%ar%s%%aN%s%%d%s%%s\" %s --abbrev=%d", SEPARATION_CHAR, SEPARATION_CHAR, SEPARATION_CHAR, SEPARATION_CHAR, limitFlag, 20))
+
if err != nil {
// assume if there is an error there are no commits yet for this branch
return ""
diff --git a/pkg/gui/commits_panel.go b/pkg/gui/commits_panel.go
index b84401e79..e42aabfd0 100644
--- a/pkg/gui/commits_panel.go
+++ b/pkg/gui/commits_panel.go
@@ -7,6 +7,7 @@ import (
"github.com/jesseduffield/gocui"
"github.com/jesseduffield/lazygit/pkg/commands"
+ "github.com/jesseduffield/lazygit/pkg/gui/presentation"
"github.com/jesseduffield/lazygit/pkg/utils"
)
@@ -600,9 +601,8 @@ func (gui *Gui) renderBranchCommitsWithSelection() error {
commitsView := gui.getCommitsView()
gui.refreshSelectedLine(&gui.State.Panels.Commits.SelectedLine, len(gui.State.Commits))
- if err := gui.renderListPanel(commitsView, gui.State.Commits); err != nil {
- return err
- }
+ displayStrings := presentation.GetCommitListDisplayStrings(gui.State.Commits, gui.State.ScreenMode != SCREEN_NORMAL)
+ gui.renderDisplayStrings(commitsView, displayStrings)
if gui.g.CurrentView() == commitsView && commitsView.Context == "branch-commits" {
if err := gui.handleCommitSelect(gui.g, commitsView); err != nil {
return err
diff --git a/pkg/gui/gui.go b/pkg/gui/gui.go
index f04032fb5..4cf435b8f 100644
--- a/pkg/gui/gui.go
+++ b/pkg/gui/gui.go
@@ -269,12 +269,20 @@ func NewGui(log *logrus.Entry, gitCommand *commands.GitCommand, oSCommand *comma
func (gui *Gui) nextScreenMode(g *gocui.Gui, v *gocui.View) error {
gui.State.ScreenMode = utils.NextIntInCycle([]int{SCREEN_NORMAL, SCREEN_HALF, SCREEN_FULL}, gui.State.ScreenMode)
+ // commits render differently depending on whether we're in fullscreen more or not
+ if err := gui.renderBranchCommitsWithSelection(); err != nil {
+ return err
+ }
return nil
}
func (gui *Gui) prevScreenMode(g *gocui.Gui, v *gocui.View) error {
gui.State.ScreenMode = utils.PrevIntInCycle([]int{SCREEN_NORMAL, SCREEN_HALF, SCREEN_FULL}, gui.State.ScreenMode)
+ // commits render differently depending on whether we're in fullscreen more or not
+ if err := gui.renderBranchCommitsWithSelection(); err != nil {
+ return err
+ }
return nil
}
diff --git a/pkg/gui/presentation/commits.go b/pkg/gui/presentation/commits.go
new file mode 100644
index 000000000..04dbb0780
--- /dev/null
+++ b/pkg/gui/presentation/commits.go
@@ -0,0 +1,126 @@
+package presentation
+
+import (
+ "strings"
+
+ "github.com/fatih/color"
+ "github.com/jesseduffield/lazygit/pkg/commands"
+ "github.com/jesseduffield/lazygit/pkg/theme"
+ "github.com/jesseduffield/lazygit/pkg/utils"
+)
+
+func GetCommitListDisplayStrings(commits []*commands.Commit, fullDescription bool) [][]string {
+ lines := make([][]string, len(commits))
+
+ var displayFunc func(*commands.Commit) []string
+ if fullDescription {
+ displayFunc = getFullDescriptionDisplayStringsForCommit
+ } else {
+ displayFunc = getDisplayStringsForCommit
+ }
+
+ for i := range commits {
+ lines[i] = displayFunc(commits[i])
+ }
+
+ return lines
+}
+
+func getFullDescriptionDisplayStringsForCommit(c *commands.Commit) []string {
+ red := color.New(color.FgRed)
+ yellow := color.New(color.FgYellow)
+ green := color.New(color.FgGreen)
+ blue := color.New(color.FgBlue)
+ cyan := color.New(color.FgCyan)
+ defaultColor := color.New(theme.DefaultTextColor)
+ magenta := color.New(color.FgMagenta)
+
+ // for some reason, setting the background to blue pads out the other commits
+ // horizontally. For the sake of accessibility I'm considering this a feature,
+ // not a bug
+ copied := color.New(color.FgCyan, color.BgBlue)
+
+ var shaColor *color.Color
+ switch c.Status {
+ case "unpushed":
+ shaColor = red
+ case "pushed":
+ shaColor = yellow
+ case "merged":
+ shaColor = green
+ case "rebasing":
+ shaColor = blue
+ case "reflog":
+ shaColor = blue
+ case "selected":
+ shaColor = magenta
+ default:
+ shaColor = defaultColor
+ }
+
+ if c.Copied {
+ shaColor = copied
+ }
+
+ tagString := ""
+ truncatedDate := utils.TruncateWithEllipsis(c.Date, 15)
+ secondColumnString := blue.Sprint(truncatedDate)
+ if c.Action != "" {
+ secondColumnString = cyan.Sprint(c.Action)
+ } else if len(c.Tags) > 0 {
+ tagColor := color.New(color.FgMagenta, color.Bold)
+ tagString = utils.ColoredStringDirect(c.ExtraInfo, tagColor) + " "
+ }
+
+ truncatedAuthor := utils.TruncateWithEllipsis(c.Author, 17)
+
+ return []string{shaColor.Sprint(c.Sha[:8]), secondColumnString, yellow.Sprint(truncatedAuthor), tagString + defaultColor.Sprint(c.Name)}
+}
+
+func getDisplayStringsForCommit(c *commands.Commit) []string {
+ red := color.New(color.FgRed)
+ yellow := color.New(color.FgYellow)
+ green := color.New(color.FgGreen)
+ blue := color.New(color.FgBlue)
+ cyan := color.New(color.FgCyan)
+ defaultColor := color.New(theme.DefaultTextColor)
+ magenta := color.New(color.FgMagenta)
+
+ // for some reason, setting the background to blue pads out the other commits
+ // horizontally. For the sake of accessibility I'm considering this a feature,
+ // not a bug
+ copied := color.New(color.FgCyan, color.BgBlue)
+
+ var shaColor *color.Color
+ switch c.Status {
+ case "unpushed":
+ shaColor = red
+ case "pushed":
+ shaColor = yellow
+ case "merged":
+ shaColor = green
+ case "rebasing":
+ shaColor = blue
+ case "reflog":
+ shaColor = blue
+ case "selected":
+ shaColor = magenta
+ default:
+ shaColor = defaultColor
+ }
+
+ if c.Copied {
+ shaColor = copied
+ }
+
+ actionString := ""
+ tagString := ""
+ if c.Action != "" {
+ actionString = cyan.Sprint(utils.WithPadding(c.Action, 7)) + " "
+ } else if len(c.Tags) > 0 {
+ tagColor := color.New(color.FgMagenta, color.Bold)
+ tagString = utils.ColoredStringDirect(strings.Join(c.Tags, " "), tagColor) + " "
+ }
+
+ return []string{shaColor.Sprint(c.Sha[:8]), actionString + tagString + defaultColor.Sprint(c.Name)}
+}
diff --git a/pkg/gui/view_helpers.go b/pkg/gui/view_helpers.go
index 5452f1754..119014802 100644
--- a/pkg/gui/view_helpers.go
+++ b/pkg/gui/view_helpers.go
@@ -387,6 +387,15 @@ func (gui *Gui) refreshSelectedLine(line *int, total int) {
}
}
+func (gui *Gui) renderDisplayStrings(v *gocui.View, displayStrings [][]string) {
+ gui.g.Update(func(g *gocui.Gui) error {
+ list := utils.RenderDisplayStrings(displayStrings)
+ v.Clear()
+ fmt.Fprint(v, list)
+ return nil
+ })
+}
+
func (gui *Gui) renderListPanel(v *gocui.View, items interface{}) error {
gui.g.Update(func(g *gocui.Gui) error {
isFocused := gui.g.CurrentView().Name() == v.Name()
diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go
index 42529776f..7fa33e769 100644
--- a/pkg/utils/utils.go
+++ b/pkg/utils/utils.go
@@ -348,3 +348,22 @@ func PrevIntInCycle(sl []int, current int) int {
}
return sl[len(sl)-1]
}
+
+// TruncateWithEllipsis returns a string, truncated to a certain length, with an ellipsis
+func TruncateWithEllipsis(str string, limit int) string {
+ if limit == 1 && len(str) > 1 {
+ return "."
+ }
+
+ if limit == 2 && len(str) > 2 {
+ return ".."
+ }
+
+ ellipsis := "..."
+ if len(str) <= limit {
+ return str
+ }
+
+ remainingLength := limit - len(ellipsis)
+ return str[0:remainingLength] + "..."
+}