diff options
author | Jesse Duffield <jessedduffield@gmail.com> | 2020-03-26 22:51:24 +1100 |
---|---|---|
committer | Jesse Duffield <jessedduffield@gmail.com> | 2020-03-28 11:59:45 +1100 |
commit | fbbd16bd829d6f2a8797453f2d05856b33d34d44 (patch) | |
tree | c49e5347d0cfa7dd7706724c8cc03942aece641f | |
parent | bd2c1eef53fbc6d76a34c6cf5c340e7a2eb5851b (diff) |
use reflogs from state to work out branch recencies
-rw-r--r-- | pkg/commands/branch_list_builder.go | 89 | ||||
-rw-r--r-- | pkg/commands/git.go | 2 | ||||
-rw-r--r-- | pkg/gui/branches_panel.go | 6 | ||||
-rw-r--r-- | pkg/gui/commits_panel.go | 13 | ||||
-rw-r--r-- | pkg/gui/reset_menu_panel.go | 3 | ||||
-rw-r--r-- | pkg/gui/view_helpers.go | 5 | ||||
-rw-r--r-- | pkg/utils/date.go | 21 |
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)) +} |