summaryrefslogtreecommitdiffstats
path: root/pkg
diff options
context:
space:
mode:
Diffstat (limited to 'pkg')
-rw-r--r--pkg/commands/branch_list_builder.go89
-rw-r--r--pkg/commands/git.go2
-rw-r--r--pkg/gui/branches_panel.go6
-rw-r--r--pkg/gui/commits_panel.go13
-rw-r--r--pkg/gui/reset_menu_panel.go3
-rw-r--r--pkg/gui/view_helpers.go5
-rw-r--r--pkg/utils/date.go21
7 files changed, 64 insertions, 75 deletions
diff --git a/pkg/commands/branch_list_builder.go b/pkg/commands/branch_list_builder.go
index a04691b47..f7949d2bc 100644
--- a/pkg/commands/branch_list_builder.go
+++ b/pkg/commands/branch_list_builder.go
@@ -2,10 +2,10 @@ package commands
import (
"regexp"
+ "strconv"
"strings"
"github.com/jesseduffield/lazygit/pkg/utils"
-
"github.com/sirupsen/logrus"
)
@@ -22,15 +22,17 @@ import (
// BranchListBuilder returns a list of Branch objects for the current repo
type BranchListBuilder struct {
- Log *logrus.Entry
- GitCommand *GitCommand
+ Log *logrus.Entry
+ GitCommand *GitCommand
+ ReflogCommits []*Commit
}
// NewBranchListBuilder builds a new branch list builder
-func NewBranchListBuilder(log *logrus.Entry, gitCommand *GitCommand) (*BranchListBuilder, error) {
+func NewBranchListBuilder(log *logrus.Entry, gitCommand *GitCommand, reflogCommits []*Commit) (*BranchListBuilder, error) {
return &BranchListBuilder{
- Log: log,
- GitCommand: gitCommand,
+ Log: log,
+ GitCommand: gitCommand,
+ ReflogCommits: reflogCommits,
}, nil
}
@@ -132,63 +134,34 @@ outer:
}
branches = append([]*Branch{{Name: currentBranchName, DisplayName: currentBranchDisplayName, Head: true, Recency: " *"}}, branches...)
}
-
return branches
}
-// A line will have the form '10 days ago master' so we need to strip out the
-// useful information from that into timeNumber, timeUnit, and branchName
-func branchInfoFromLine(line string) (string, string) {
- // example line: HEAD@{12 minutes ago}|checkout: moving from pulling-from-forks to tim77-patch-1
- r := regexp.MustCompile(`HEAD\@\{([^\s]+) ([^\s]+) ago\}\|.*?([^\s]*)$`)
- matches := r.FindStringSubmatch(strings.TrimSpace(line))
- if len(matches) == 0 {
- return "", ""
- }
- since := matches[1]
- unit := matches[2]
- branchName := matches[3]
- return since + abbreviatedTimeUnit(unit), branchName
-}
-
-func abbreviatedTimeUnit(timeUnit string) string {
- r := regexp.MustCompile("s$")
- timeUnit = r.ReplaceAllString(timeUnit, "")
- timeUnitMap := map[string]string{
- "hour": "h",
- "minute": "m",
- "second": "s",
- "week": "w",
- "year": "y",
- "day": "d",
- "month": "m",
- }
- return timeUnitMap[timeUnit]
-}
-
+// TODO: only look at the new reflog commits, and otherwise store the recencies in
+// int form against the branch to recalculate the time ago
func (b *BranchListBuilder) obtainReflogBranches() []*Branch {
- branches := make([]*Branch, 0)
- // if we directly put this string in RunCommandWithOutput the compiler complains because it thinks it's a format string
- unescaped := "git reflog --date=relative --pretty='%gd|%gs' --grep-reflog='checkout: moving' HEAD"
- rawString, err := b.GitCommand.OSCommand.RunCommandWithOutput(unescaped)
- if err != nil {
- return branches
- }
-
- branchNameMap := map[string]bool{}
+ foundBranchesMap := map[string]bool{}
+ re := regexp.MustCompile(`checkout: moving from ([\S]+) to ([\S]+)`)
+ reflogBranches := make([]*Branch, 0, len(b.ReflogCommits))
+ for _, commit := range b.ReflogCommits {
+ if match := re.FindStringSubmatch(commit.Name); len(match) == 3 {
+ timestamp, err := strconv.Atoi(commit.Date)
+ if err != nil {
+ b.Log.Errorf("couldn't parse reflog date: %s", commit.Date)
+ continue
+ }
- branchLines := utils.SplitLines(rawString)
- for _, line := range branchLines {
- recency, branchName := branchInfoFromLine(line)
- if branchName == "" {
- continue
- }
- if _, ok := branchNameMap[branchName]; ok {
- continue
+ recency := utils.UnixToTimeAgo(timestamp)
+ for _, branchName := range match[1:] {
+ if !foundBranchesMap[branchName] {
+ foundBranchesMap[branchName] = true
+ reflogBranches = append(reflogBranches, &Branch{
+ Recency: recency,
+ Name: branchName,
+ })
+ }
+ }
}
- branchNameMap[branchName] = true
- branch := &Branch{Name: branchName, Recency: recency}
- branches = append(branches, branch)
}
- return branches
+ return reflogBranches
}
diff --git a/pkg/commands/git.go b/pkg/commands/git.go
index 95bd380bd..42b075915 100644
--- a/pkg/commands/git.go
+++ b/pkg/commands/git.go
@@ -1126,7 +1126,7 @@ func (c *GitCommand) FetchRemote(remoteName string) error {
func (c *GitCommand) GetNewReflogCommits(lastReflogCommit *Commit) ([]*Commit, error) {
commits := make([]*Commit, 0)
re := regexp.MustCompile(`(\w+).*HEAD@\{([^\}]+)\}: (.*)`)
- cmd := c.OSCommand.ExecutableFromString("git reflog --abbrev=20 --date=iso")
+ cmd := c.OSCommand.ExecutableFromString("git reflog --abbrev=20 --date=unix")
err := RunLineOutputCmd(cmd, func(line string) (bool, error) {
match := re.FindStringSubmatch(line)
if len(match) <= 1 {
diff --git a/pkg/gui/branches_panel.go b/pkg/gui/branches_panel.go
index 6ca257ed4..fe947f50f 100644
--- a/pkg/gui/branches_panel.go
+++ b/pkg/gui/branches_panel.go
@@ -63,7 +63,7 @@ func (gui *Gui) refreshBranches(g *gocui.Gui) error {
}
g.Update(func(g *gocui.Gui) error {
- builder, err := commands.NewBranchListBuilder(gui.Log, gui.GitCommand)
+ builder, err := commands.NewBranchListBuilder(gui.Log, gui.GitCommand, gui.State.ReflogCommits)
if err != nil {
return err
}
@@ -374,7 +374,7 @@ func (gui *Gui) handleFastForward(g *gocui.Gui, v *gocui.View) error {
if err := gui.GitCommand.FastForward(branch.Name, remoteName, remoteBranchName); err != nil {
_ = gui.createErrorPanel(gui.g, err.Error())
}
- _ = gui.refreshBranches(gui.g)
+ _ = gui.refreshCommits(gui.g)
}
_ = gui.closeConfirmationPrompt(gui.g, true)
@@ -481,7 +481,7 @@ func (gui *Gui) handleRenameBranch(g *gocui.Gui, v *gocui.View) error {
return gui.createErrorPanel(gui.g, err.Error())
}
- return gui.refreshBranches(gui.g)
+ return gui.refreshCommits(gui.g)
})
}
diff --git a/pkg/gui/commits_panel.go b/pkg/gui/commits_panel.go
index 25be221d7..f0c391755 100644
--- a/pkg/gui/commits_panel.go
+++ b/pkg/gui/commits_panel.go
@@ -79,12 +79,13 @@ func (gui *Gui) refreshCommits(g *gocui.Gui) error {
return err
}
- // doing this async because it shouldn't hold anything up
- go func() {
- if err := gui.refreshReflogCommits(); err != nil {
- _ = gui.createErrorPanel(gui.g, err.Error())
- }
- }()
+ if err := gui.refreshReflogCommits(); err != nil {
+ return gui.createErrorPanel(gui.g, err.Error())
+ }
+
+ if err := gui.refreshBranches(gui.g); err != nil {
+ return gui.createErrorPanel(gui.g, err.Error())
+ }
if g.CurrentView() == gui.getCommitFilesView() || (g.CurrentView() == gui.getMainView() || gui.State.MainContext == "patch-building") {
return gui.refreshCommitFilesView()
diff --git a/pkg/gui/reset_menu_panel.go b/pkg/gui/reset_menu_panel.go
index 05bdb5e9b..dab7ee9dd 100644
--- a/pkg/gui/reset_menu_panel.go
+++ b/pkg/gui/reset_menu_panel.go
@@ -27,9 +27,6 @@ func (gui *Gui) resetToRef(ref string, strength string, options commands.RunComm
if err := gui.refreshFiles(); err != nil {
return err
}
- if err := gui.refreshBranches(gui.g); err != nil {
- return err
- }
if err := gui.resetOrigin(gui.getCommitsView()); err != nil {
return err
}
diff --git a/pkg/gui/view_helpers.go b/pkg/gui/view_helpers.go
index 4d9fbb36e..7a1285bbb 100644
--- a/pkg/gui/view_helpers.go
+++ b/pkg/gui/view_helpers.go
@@ -14,15 +14,12 @@ import (
var cyclableViews = []string{"status", "files", "branches", "commits", "stash"}
func (gui *Gui) refreshSidePanels(g *gocui.Gui) error {
- if err := gui.refreshBranches(g); err != nil {
+ if err := gui.refreshCommits(g); err != nil {
return err
}
if err := gui.refreshFiles(); err != nil {
return err
}
- if err := gui.refreshCommits(g); err != nil {
- return err
- }
return gui.refreshStashEntries(g)
}
diff --git a/pkg/utils/date.go b/pkg/utils/date.go
new file mode 100644
index 000000000..7f8f8f8a5
--- /dev/null
+++ b/pkg/utils/date.go
@@ -0,0 +1,21 @@
+package utils
+
+import (
+ "fmt"
+ "time"
+)
+
+func UnixToTimeAgo(timestamp int) string {
+ now := time.Now().Unix()
+ delta := float64(now - int64(timestamp))
+ // we go seconds, minutes, hours, days, weeks, months, years
+ conversions := []float64{60, 60, 24, 7, 4.34524, 12}
+ labels := []string{"s", "m", "h", "d", "w", "m", "y"}
+ for i, conversion := range conversions {
+ if delta < conversion {
+ return fmt.Sprintf("%d%s", int(delta), labels[i])
+ }
+ delta /= conversion
+ }
+ return fmt.Sprintf("%dy", int(delta))
+}