1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-04-23 12:18:51 +02:00

more centralised handling of refreshing

This commit is contained in:
Jesse Duffield 2020-03-27 19:12:15 +11:00
parent 39315ca1e2
commit 198d237679
32 changed files with 189 additions and 126 deletions

1
AgeMQemvPk Normal file
View File

@ -0,0 +1 @@
YrWrygkDZr

1
CqSiBeejXz Normal file
View File

@ -0,0 +1 @@
pnzuDhnmXj

1
EzGTvaqMIv Normal file
View File

@ -0,0 +1 @@
FwtesbRmIy

1
FcKgiBNeUX Normal file
View File

@ -0,0 +1 @@
yZXPONHgYA

1
KtDIVguUOP Normal file
View File

@ -0,0 +1 @@
zTceFimWln

1
TGpKLocWft Normal file
View File

@ -0,0 +1 @@
wYOKNLUbIn

1
UkUKNwQtgP Normal file
View File

@ -0,0 +1 @@
KJkGhkBJvv

1
kTrVvqUAxG Normal file
View File

@ -0,0 +1 @@
LdOMEqAOcq

View File

@ -2,7 +2,6 @@ package commands
import ( import (
"regexp" "regexp"
"strconv"
"strings" "strings"
"github.com/jesseduffield/lazygit/pkg/utils" "github.com/jesseduffield/lazygit/pkg/utils"
@ -145,13 +144,7 @@ func (b *BranchListBuilder) obtainReflogBranches() []*Branch {
reflogBranches := make([]*Branch, 0, len(b.ReflogCommits)) reflogBranches := make([]*Branch, 0, len(b.ReflogCommits))
for _, commit := range b.ReflogCommits { for _, commit := range b.ReflogCommits {
if match := re.FindStringSubmatch(commit.Name); len(match) == 3 { if match := re.FindStringSubmatch(commit.Name); len(match) == 3 {
timestamp, err := strconv.Atoi(commit.Date) recency := utils.UnixToTimeAgo(commit.UnixTimestamp)
if err != nil {
b.Log.Errorf("couldn't parse reflog date: %s", commit.Date)
continue
}
recency := utils.UnixToTimeAgo(timestamp)
for _, branchName := range match[1:] { for _, branchName := range match[1:] {
if !foundBranchesMap[branchName] { if !foundBranchesMap[branchName] {
foundBranchesMap[branchName] = true foundBranchesMap[branchName] = true

View File

@ -2,14 +2,14 @@ package commands
// Commit : A git commit // Commit : A git commit
type Commit struct { type Commit struct {
Sha string Sha string
Name string Name string
Status string // one of "unpushed", "pushed", "merged", "rebasing" or "selected" Status string // one of "unpushed", "pushed", "merged", "rebasing" or "selected"
Action string // one of "", "pick", "edit", "squash", "reword", "drop", "fixup" Action string // one of "", "pick", "edit", "squash", "reword", "drop", "fixup"
Tags []string Tags []string
ExtraInfo string // something like 'HEAD -> master, tag: v0.15.2' ExtraInfo string // something like 'HEAD -> master, tag: v0.15.2'
Author string Author string
Date string UnixTimestamp int64
} }
func (c *Commit) ShortSha() string { func (c *Commit) ShortSha() string {

View File

@ -7,6 +7,7 @@ import (
"os/exec" "os/exec"
"path/filepath" "path/filepath"
"regexp" "regexp"
"strconv"
"strings" "strings"
"github.com/fatih/color" "github.com/fatih/color"
@ -56,7 +57,7 @@ func (c *CommitListBuilder) extractCommitFromLine(line string) *Commit {
split := strings.Split(line, SEPARATION_CHAR) split := strings.Split(line, SEPARATION_CHAR)
sha := split[0] sha := split[0]
date := split[1] unixTimestamp := split[1]
author := split[2] author := split[2]
extraInfo := strings.TrimSpace(split[3]) extraInfo := strings.TrimSpace(split[3])
message := strings.Join(split[4:], SEPARATION_CHAR) message := strings.Join(split[4:], SEPARATION_CHAR)
@ -70,13 +71,15 @@ func (c *CommitListBuilder) extractCommitFromLine(line string) *Commit {
} }
} }
unitTimestampInt, _ := strconv.Atoi(unixTimestamp)
return &Commit{ return &Commit{
Sha: sha, Sha: sha,
Name: message, Name: message,
Tags: tags, Tags: tags,
ExtraInfo: extraInfo, ExtraInfo: extraInfo,
Date: date, UnixTimestamp: int64(unitTimestampInt),
Author: author, Author: author,
} }
} }
@ -305,5 +308,5 @@ func (c *CommitListBuilder) getLogCmd(limit bool) *exec.Cmd {
limitFlag = "-300" limitFlag = "-300"
} }
return c.OSCommand.ExecutableFromString(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)) return c.OSCommand.ExecutableFromString(fmt.Sprintf("git log --oneline --pretty=format:\"%%H%s%%at%s%%aN%s%%d%s%%s\" %s --abbrev=%d --date=unix ", SEPARATION_CHAR, SEPARATION_CHAR, SEPARATION_CHAR, SEPARATION_CHAR, limitFlag, 20))
} }

View File

@ -484,11 +484,7 @@ func (c *GitCommand) GitStatus() (string, error) {
// IsInMergeState states whether we are still mid-merge // IsInMergeState states whether we are still mid-merge
func (c *GitCommand) IsInMergeState() (bool, error) { func (c *GitCommand) IsInMergeState() (bool, error) {
output, err := c.OSCommand.RunCommandWithOutput("git status --untracked-files=all") return c.OSCommand.FileExists(fmt.Sprintf("%s/MERGE_HEAD", c.DotGitDir))
if err != nil {
return false, err
}
return strings.Contains(output, "conclude merge") || strings.Contains(output, "unmerged paths"), nil
} }
// RebaseMode returns "" for non-rebase mode, "normal" for normal rebase // RebaseMode returns "" for non-rebase mode, "normal" for normal rebase
@ -1133,14 +1129,16 @@ func (c *GitCommand) GetNewReflogCommits(lastReflogCommit *Commit) ([]*Commit, e
return false, nil return false, nil
} }
unixTimestamp, _ := strconv.Atoi(match[2])
commit := &Commit{ commit := &Commit{
Sha: match[1], Sha: match[1],
Name: match[3], Name: match[3],
Date: match[2], UnixTimestamp: int64(unixTimestamp),
Status: "reflog", Status: "reflog",
} }
if lastReflogCommit != nil && commit.Sha == lastReflogCommit.Sha && commit.Date == lastReflogCommit.Date { if lastReflogCommit != nil && commit.Sha == lastReflogCommit.Sha && commit.UnixTimestamp == lastReflogCommit.UnixTimestamp {
// after this point we already have these reflogs loaded so we'll simply return the new ones // after this point we already have these reflogs loaded so we'll simply return the new ones
return true, nil return true, nil
} }

View File

@ -127,7 +127,7 @@ func (gui *Gui) handleForceCheckout(g *gocui.Gui, v *gocui.View) error {
if err := gui.GitCommand.Checkout(branch.Name, commands.CheckoutOptions{Force: true}); err != nil { if err := gui.GitCommand.Checkout(branch.Name, commands.CheckoutOptions{Force: true}); err != nil {
_ = gui.createErrorPanel(g, err.Error()) _ = gui.createErrorPanel(g, err.Error())
} }
return gui.refreshSidePanels(g) return gui.refreshSidePanels(refreshOptions{mode: ASYNC})
}, nil) }, nil)
} }
@ -167,14 +167,13 @@ func (gui *Gui) handleCheckoutRef(ref string, options handleCheckoutRefOptions)
} }
onSuccess() onSuccess()
if err := gui.GitCommand.StashDo(0, "pop"); err != nil { if err := gui.GitCommand.StashDo(0, "pop"); err != nil {
if err := gui.refreshSidePanels(g); err != nil { if err := gui.refreshSidePanels(refreshOptions{mode: BLOCK_UI}); err != nil {
return err return err
} }
return gui.createErrorPanel(g, err.Error()) return gui.createErrorPanel(g, err.Error())
} }
return gui.refreshSidePanels(g) return gui.refreshSidePanels(refreshOptions{mode: BLOCK_UI})
}, nil) }, nil)
} }
@ -182,10 +181,9 @@ func (gui *Gui) handleCheckoutRef(ref string, options handleCheckoutRefOptions)
return err return err
} }
} }
onSuccess() onSuccess()
return gui.refreshSidePanels(gui.g) return gui.refreshSidePanels(refreshOptions{mode: BLOCK_UI})
}) })
} }
@ -218,10 +216,8 @@ func (gui *Gui) handleNewBranch(g *gocui.Gui, v *gocui.View) error {
if err := gui.GitCommand.NewBranch(gui.trimmedContent(v), branch.Name); err != nil { if err := gui.GitCommand.NewBranch(gui.trimmedContent(v), branch.Name); err != nil {
return gui.createErrorPanel(g, err.Error()) return gui.createErrorPanel(g, err.Error())
} }
if err := gui.refreshSidePanels(g); err != nil { gui.State.Panels.Branches.SelectedLine = 0
return gui.createErrorPanel(g, err.Error()) return gui.refreshSidePanels(refreshOptions{mode: ASYNC})
}
return gui.handleBranchSelect(g, v)
}) })
} }
@ -263,7 +259,7 @@ func (gui *Gui) deleteNamedBranch(g *gocui.Gui, v *gocui.View, selectedBranch *c
} }
return gui.createErrorPanel(g, errMessage) return gui.createErrorPanel(g, errMessage)
} }
return gui.refreshSidePanels(g) return gui.refreshSidePanels(refreshOptions{mode: ASYNC, scope: []int{BRANCHES}})
}, nil) }, nil)
} }
@ -357,7 +353,7 @@ func (gui *Gui) handleFastForward(g *gocui.Gui, v *gocui.View) error {
if err := gui.GitCommand.PullWithoutPasswordCheck("--ff-only"); err != nil { if err := gui.GitCommand.PullWithoutPasswordCheck("--ff-only"); err != nil {
_ = gui.createErrorPanel(gui.g, err.Error()) _ = gui.createErrorPanel(gui.g, err.Error())
} }
_ = gui.refreshSidePanels(gui.g) _ = gui.refreshSidePanels(refreshOptions{mode: ASYNC})
} else { } else {
if err := gui.GitCommand.FastForward(branch.Name, remoteName, remoteBranchName); err != nil { if err := gui.GitCommand.FastForward(branch.Name, remoteName, remoteBranchName); err != nil {
_ = gui.createErrorPanel(gui.g, err.Error()) _ = gui.createErrorPanel(gui.g, err.Error())

View File

@ -85,7 +85,7 @@ func (gui *Gui) handleDiscardOldFileChange(g *gocui.Gui, v *gocui.View) error {
} }
} }
return gui.refreshSidePanels(gui.g) return gui.refreshSidePanels(refreshOptions{mode: BLOCK_UI})
}) })
}, nil) }, nil)
} }

View File

@ -48,7 +48,7 @@ func (gui *Gui) handleCommitConfirm(g *gocui.Gui, v *gocui.View) error {
_ = v.SetOrigin(0, 0) _ = v.SetOrigin(0, 0)
_, _ = g.SetViewOnBottom("commitMessage") _, _ = g.SetViewOnBottom("commitMessage")
_ = gui.switchFocus(g, v, gui.getFilesView()) _ = gui.switchFocus(g, v, gui.getFilesView())
return gui.refreshSidePanels(g) return gui.refreshSidePanels(refreshOptions{mode: ASYNC})
} }
func (gui *Gui) handleCommitClose(g *gocui.Gui, v *gocui.View) error { func (gui *Gui) handleCommitClose(g *gocui.Gui, v *gocui.View) error {

View File

@ -72,10 +72,6 @@ func (gui *Gui) handleCommitSelect(g *gocui.Gui, v *gocui.View) error {
} }
func (gui *Gui) refreshCommits(g *gocui.Gui) error { func (gui *Gui) refreshCommits(g *gocui.Gui) error {
if err := gui.updateWorkTreeState(); err != nil {
return gui.createErrorPanel(gui.g, err.Error())
}
wg := sync.WaitGroup{} wg := sync.WaitGroup{}
wg.Add(2) wg.Add(2)
@ -87,6 +83,9 @@ func (gui *Gui) refreshCommits(g *gocui.Gui) error {
go func() { go func() {
gui.refreshCommitsWithLimit() gui.refreshCommitsWithLimit()
if g.CurrentView() == gui.getCommitFilesView() || (g.CurrentView() == gui.getMainView() || gui.State.MainContext == "patch-building") {
gui.refreshCommitFilesView()
}
wg.Done() wg.Done()
}() }()
@ -94,10 +93,6 @@ func (gui *Gui) refreshCommits(g *gocui.Gui) error {
gui.refreshStatus() gui.refreshStatus()
if g.CurrentView() == gui.getCommitFilesView() || (g.CurrentView() == gui.getMainView() || gui.State.MainContext == "patch-building") {
return gui.refreshCommitFilesView()
}
return nil return nil
} }
@ -497,7 +492,7 @@ func (gui *Gui) handleCreateFixupCommit(g *gocui.Gui, v *gocui.View) error {
return gui.createErrorPanel(g, err.Error()) return gui.createErrorPanel(g, err.Error())
} }
return gui.refreshSidePanels(gui.g) return gui.refreshSidePanels(refreshOptions{mode: ASYNC})
}, nil) }, nil)
} }

View File

@ -100,6 +100,6 @@ func (gui *Gui) HandleCredentialsPopup(g *gocui.Gui, popupOpened bool, cmdErr er
_ = gui.createSpecificErrorPanel(errMessage, gui.getFilesView(), false) _ = gui.createSpecificErrorPanel(errMessage, gui.getFilesView(), false)
} else { } else {
_ = gui.closeConfirmationPrompt(g, true) _ = gui.closeConfirmationPrompt(g, true)
_ = gui.refreshSidePanels(g) _ = gui.refreshSidePanels(refreshOptions{mode: ASYNC})
} }
} }

View File

@ -278,7 +278,7 @@ func (gui *Gui) handleWIPCommitPress(g *gocui.Gui, filesView *gocui.View) error
} }
func (gui *Gui) handleCommitPress(g *gocui.Gui, filesView *gocui.View) error { func (gui *Gui) handleCommitPress(g *gocui.Gui, filesView *gocui.View) error {
if len(gui.stagedFiles()) == 0 && gui.State.WorkingTreeState == "normal" { if len(gui.stagedFiles()) == 0 && gui.workingTreeState() == "normal" {
return gui.createErrorPanel(g, gui.Tr.SLocalize("NoStagedFilesToCommit")) return gui.createErrorPanel(g, gui.Tr.SLocalize("NoStagedFilesToCommit"))
} }
commitMessageView := gui.getCommitMessageView() commitMessageView := gui.getCommitMessageView()
@ -298,7 +298,7 @@ func (gui *Gui) handleCommitPress(g *gocui.Gui, filesView *gocui.View) error {
} }
func (gui *Gui) handleAmendCommitPress(g *gocui.Gui, filesView *gocui.View) error { func (gui *Gui) handleAmendCommitPress(g *gocui.Gui, filesView *gocui.View) error {
if len(gui.stagedFiles()) == 0 && gui.State.WorkingTreeState == "normal" { if len(gui.stagedFiles()) == 0 && gui.workingTreeState() == "normal" {
return gui.createErrorPanel(g, gui.Tr.SLocalize("NoStagedFilesToCommit")) return gui.createErrorPanel(g, gui.Tr.SLocalize("NoStagedFilesToCommit"))
} }
if len(gui.State.Commits) == 0 { if len(gui.State.Commits) == 0 {
@ -317,14 +317,14 @@ func (gui *Gui) handleAmendCommitPress(g *gocui.Gui, filesView *gocui.View) erro
return nil return nil
} }
return gui.refreshSidePanels(g) return gui.refreshSidePanels(refreshOptions{mode: ASYNC})
}, nil) }, nil)
} }
// handleCommitEditorPress - handle when the user wants to commit changes via // handleCommitEditorPress - handle when the user wants to commit changes via
// their editor rather than via the popup panel // their editor rather than via the popup panel
func (gui *Gui) handleCommitEditorPress(g *gocui.Gui, filesView *gocui.View) error { func (gui *Gui) handleCommitEditorPress(g *gocui.Gui, filesView *gocui.View) error {
if len(gui.stagedFiles()) == 0 && gui.State.WorkingTreeState == "normal" { if len(gui.stagedFiles()) == 0 && gui.workingTreeState() == "normal" {
return gui.createErrorPanel(g, gui.Tr.SLocalize("NoStagedFilesToCommit")) return gui.createErrorPanel(g, gui.Tr.SLocalize("NoStagedFilesToCommit"))
} }
gui.PrepareSubProcess(g, "git", "commit") gui.PrepareSubProcess(g, "git", "commit")
@ -375,7 +375,7 @@ func (gui *Gui) refreshStateFiles() error {
} }
gui.refreshSelectedLine(&gui.State.Panels.Files.SelectedLine, len(gui.State.Files)) gui.refreshSelectedLine(&gui.State.Panels.Files.SelectedLine, len(gui.State.Files))
return gui.updateWorkTreeState() return nil
} }
func (gui *Gui) catSelectedFile(g *gocui.Gui) (string, error) { func (gui *Gui) catSelectedFile(g *gocui.Gui) (string, error) {

View File

@ -194,7 +194,6 @@ type guiState struct {
Platform commands.Platform Platform commands.Platform
Updating bool Updating bool
Panels *panelStates Panels *panelStates
WorkingTreeState string // one of "merging", "rebasing", "normal"
MainContext string // used to keep the main and secondary views' contexts in sync MainContext string // used to keep the main and secondary views' contexts in sync
CherryPickedCommits []*commands.Commit CherryPickedCommits []*commands.Commit
SplitMainPanel bool SplitMainPanel bool
@ -351,7 +350,7 @@ func (gui *Gui) scrollDownConfirmationPanel(g *gocui.Gui, v *gocui.View) error {
} }
func (gui *Gui) handleRefresh(g *gocui.Gui, v *gocui.View) error { func (gui *Gui) handleRefresh(g *gocui.Gui, v *gocui.View) error {
return gui.refreshSidePanels(g) return gui.refreshSidePanels(refreshOptions{mode: ASYNC})
} }
func max(a, b int) int { func max(a, b int) int {
@ -863,7 +862,7 @@ func (gui *Gui) loadNewRepo() error {
} }
gui.waitForIntro.Done() gui.waitForIntro.Done()
if err := gui.refreshSidePanels(gui.g); err != nil { if err := gui.refreshSidePanels(refreshOptions{mode: ASYNC}); err != nil {
return err return err
} }

View File

@ -281,7 +281,7 @@ func (gui *Gui) handleCompleteMerge() error {
} }
// if we got conflicts after unstashing, we don't want to call any git // if we got conflicts after unstashing, we don't want to call any git
// commands to continue rebasing/merging here // commands to continue rebasing/merging here
if gui.State.WorkingTreeState == "normal" { if gui.workingTreeState() == "normal" {
return gui.handleEscapeMerge(gui.g, gui.getMainView()) return gui.handleEscapeMerge(gui.g, gui.getMainView())
} }
// if there are no more files with merge conflicts, we should ask whether the user wants to continue // if there are no more files with merge conflicts, we should ask whether the user wants to continue

View File

@ -59,7 +59,7 @@ func (gui *Gui) getPatchCommitIndex() int {
} }
func (gui *Gui) validateNormalWorkingTreeState() (bool, error) { func (gui *Gui) validateNormalWorkingTreeState() (bool, error) {
if gui.State.WorkingTreeState != "normal" { if gui.workingTreeState() != "normal" {
return false, gui.createErrorPanel(gui.g, gui.Tr.SLocalize("CantPatchWhileRebasingError")) return false, gui.createErrorPanel(gui.g, gui.Tr.SLocalize("CantPatchWhileRebasingError"))
} }
return true, nil return true, nil
@ -128,7 +128,7 @@ func (gui *Gui) handleApplyPatch() error {
if err := gui.GitCommand.PatchManager.ApplyPatches(false); err != nil { if err := gui.GitCommand.PatchManager.ApplyPatches(false); err != nil {
return gui.createErrorPanel(gui.g, err.Error()) return gui.createErrorPanel(gui.g, err.Error())
} }
return gui.refreshSidePanels(gui.g) return gui.refreshSidePanels(refreshOptions{mode: ASYNC})
} }
func (gui *Gui) handleResetPatch() error { func (gui *Gui) handleResetPatch() error {

View File

@ -63,8 +63,7 @@ func getFullDescriptionDisplayStringsForCommit(c *commands.Commit, cherryPickedC
} }
tagString := "" tagString := ""
truncatedDate := utils.TruncateWithEllipsis(c.Date, 15) secondColumnString := blue.Sprint(utils.UnixToDate(c.UnixTimestamp))
secondColumnString := blue.Sprint(truncatedDate)
if c.Action != "" { if c.Action != "" {
secondColumnString = cyan.Sprint(c.Action) secondColumnString = cyan.Sprint(c.Action)
} else if c.ExtraInfo != "" { } else if c.ExtraInfo != "" {

View File

@ -27,7 +27,11 @@ func GetReflogCommitListDisplayStrings(commits []*commands.Commit, fullDescripti
func getFullDescriptionDisplayStringsForReflogCommit(c *commands.Commit) []string { func getFullDescriptionDisplayStringsForReflogCommit(c *commands.Commit) []string {
defaultColor := color.New(theme.DefaultTextColor) defaultColor := color.New(theme.DefaultTextColor)
return []string{utils.ColoredString(c.ShortSha(), color.FgBlue), utils.ColoredString(c.Date, color.FgMagenta), defaultColor.Sprint(c.Name)} return []string{
utils.ColoredString(c.ShortSha(), color.FgBlue),
utils.ColoredString(utils.UnixToDate(c.UnixTimestamp), color.FgMagenta),
defaultColor.Sprint(c.Name),
}
} }
func getDisplayStringsForReflogCommit(c *commands.Commit) []string { func getDisplayStringsForReflogCommit(c *commands.Commit) []string {

View File

@ -10,7 +10,7 @@ import (
func (gui *Gui) handleCreateRebaseOptionsMenu(g *gocui.Gui, v *gocui.View) error { func (gui *Gui) handleCreateRebaseOptionsMenu(g *gocui.Gui, v *gocui.View) error {
options := []string{"continue", "abort"} options := []string{"continue", "abort"}
if gui.State.WorkingTreeState == "rebasing" { if gui.workingTreeState() == "rebasing" {
options = append(options, "skip") options = append(options, "skip")
} }
@ -27,7 +27,7 @@ func (gui *Gui) handleCreateRebaseOptionsMenu(g *gocui.Gui, v *gocui.View) error
} }
var title string var title string
if gui.State.WorkingTreeState == "merging" { if gui.workingTreeState() == "merging" {
title = gui.Tr.SLocalize("MergeOptionsTitle") title = gui.Tr.SLocalize("MergeOptionsTitle")
} else { } else {
title = gui.Tr.SLocalize("RebaseOptionsTitle") title = gui.Tr.SLocalize("RebaseOptionsTitle")
@ -37,7 +37,7 @@ func (gui *Gui) handleCreateRebaseOptionsMenu(g *gocui.Gui, v *gocui.View) error
} }
func (gui *Gui) genericMergeCommand(command string) error { func (gui *Gui) genericMergeCommand(command string) error {
status := gui.State.WorkingTreeState status := gui.workingTreeState()
if status != "merging" && status != "rebasing" { if status != "merging" && status != "rebasing" {
return gui.createErrorPanel(gui.g, gui.Tr.SLocalize("NotMergingOrRebasing")) return gui.createErrorPanel(gui.g, gui.Tr.SLocalize("NotMergingOrRebasing"))
@ -63,7 +63,7 @@ func (gui *Gui) genericMergeCommand(command string) error {
} }
func (gui *Gui) handleGenericMergeCommandResult(result error) error { func (gui *Gui) handleGenericMergeCommandResult(result error) error {
if err := gui.refreshSidePanels(gui.g); err != nil { if err := gui.refreshSidePanels(refreshOptions{mode: ASYNC}); err != nil {
return err return err
} }
if result == nil { if result == nil {

View File

@ -126,7 +126,7 @@ func (gui *Gui) handleSetBranchUpstream(g *gocui.Gui, v *gocui.View) error {
return err return err
} }
return gui.refreshSidePanels(gui.g) return gui.refreshSidePanels(refreshOptions{scope: []int{BRANCHES, REMOTES}})
}, nil) }, nil)
} }

View File

@ -21,10 +21,7 @@ func (gui *Gui) resetToRef(ref string, strength string, options commands.RunComm
// loading a heap of commits is slow so we limit them whenever doing a reset // loading a heap of commits is slow so we limit them whenever doing a reset
gui.State.Panels.Commits.LimitCommits = true gui.State.Panels.Commits.LimitCommits = true
if err := gui.refreshCommits(gui.g); err != nil { if err := gui.refreshSidePanels(refreshOptions{scope: []int{FILES, BRANCHES, REFLOG, COMMITS}}); err != nil {
return err
}
if err := gui.refreshFiles(); err != nil {
return err return err
} }
if err := gui.resetOrigin(gui.getCommitsView()); err != nil { if err := gui.resetOrigin(gui.getCommitsView()); err != nil {

View File

@ -12,6 +12,7 @@ import (
// never call this on its own, it should only be called from within refreshCommits() // never call this on its own, it should only be called from within refreshCommits()
func (gui *Gui) refreshStatus() { func (gui *Gui) refreshStatus() {
currentBranch := gui.currentBranch() currentBranch := gui.currentBranch()
status := "" status := ""
@ -26,8 +27,8 @@ func (gui *Gui) refreshStatus() {
status = utils.ColoredString(fmt.Sprintf("↑%s↓%s ", currentBranch.Pushables, currentBranch.Pullables), trackColor) status = utils.ColoredString(fmt.Sprintf("↑%s↓%s ", currentBranch.Pushables, currentBranch.Pullables), trackColor)
} }
if gui.State.WorkingTreeState != "normal" { if gui.workingTreeState() != "normal" {
status += utils.ColoredString(fmt.Sprintf("(%s) ", gui.State.WorkingTreeState), color.FgYellow) status += utils.ColoredString(fmt.Sprintf("(%s) ", gui.workingTreeState()), color.FgYellow)
} }
name := utils.ColoredString(currentBranch.Name, presentation.GetBranchColor(currentBranch.Name)) name := utils.ColoredString(currentBranch.Name, presentation.GetBranchColor(currentBranch.Name))
@ -59,10 +60,9 @@ func (gui *Gui) handleStatusClick(g *gocui.Gui, v *gocui.View) error {
cx, _ := v.Cursor() cx, _ := v.Cursor()
upstreamStatus := fmt.Sprintf("↑%s↓%s", currentBranch.Pushables, currentBranch.Pullables) upstreamStatus := fmt.Sprintf("↑%s↓%s", currentBranch.Pushables, currentBranch.Pullables)
repoName := utils.GetCurrentRepoName() repoName := utils.GetCurrentRepoName()
gui.Log.Warn(gui.State.WorkingTreeState) switch gui.workingTreeState() {
switch gui.State.WorkingTreeState {
case "rebasing", "merging": case "rebasing", "merging":
workingTreeStatus := fmt.Sprintf("(%s)", gui.State.WorkingTreeState) workingTreeStatus := fmt.Sprintf("(%s)", gui.workingTreeState())
if cursorInSubstring(cx, upstreamStatus+" ", workingTreeStatus) { if cursorInSubstring(cx, upstreamStatus+" ", workingTreeStatus) {
return gui.handleCreateRebaseOptionsMenu(gui.g, v) return gui.handleCreateRebaseOptionsMenu(gui.g, v)
} }
@ -128,23 +128,14 @@ func lazygitTitle() string {
|___/ |___/ ` |___/ |___/ `
} }
func (gui *Gui) updateWorkTreeState() error { func (gui *Gui) workingTreeState() string {
rebaseMode, err := gui.GitCommand.RebaseMode() rebaseMode, _ := gui.GitCommand.RebaseMode()
if err != nil {
return err
}
if rebaseMode != "" { if rebaseMode != "" {
gui.State.WorkingTreeState = "rebasing" return "rebasing"
return nil
}
merging, err := gui.GitCommand.IsInMergeState()
if err != nil {
return err
} }
merging, _ := gui.GitCommand.IsInMergeState()
if merging { if merging {
gui.State.WorkingTreeState = "merging" return "merging"
return nil
} }
gui.State.WorkingTreeState = "normal" return "normal"
return nil
} }

View File

@ -87,7 +87,7 @@ func (gui *Gui) reflogUndo(g *gocui.Gui, v *gocui.View) error {
undoEnvVars := []string{"GIT_REFLOG_ACTION=[lazygit undo]"} undoEnvVars := []string{"GIT_REFLOG_ACTION=[lazygit undo]"}
undoingStatus := gui.Tr.SLocalize("UndoingStatus") undoingStatus := gui.Tr.SLocalize("UndoingStatus")
if gui.State.WorkingTreeState == "rebasing" { if gui.workingTreeState() == "rebasing" {
return gui.createErrorPanel(gui.g, gui.Tr.SLocalize("cantUndoWhileRebasing")) return gui.createErrorPanel(gui.g, gui.Tr.SLocalize("cantUndoWhileRebasing"))
} }
@ -118,7 +118,7 @@ func (gui *Gui) reflogRedo(g *gocui.Gui, v *gocui.View) error {
redoEnvVars := []string{"GIT_REFLOG_ACTION=[lazygit redo]"} redoEnvVars := []string{"GIT_REFLOG_ACTION=[lazygit redo]"}
redoingStatus := gui.Tr.SLocalize("RedoingStatus") redoingStatus := gui.Tr.SLocalize("RedoingStatus")
if gui.State.WorkingTreeState == "rebasing" { if gui.workingTreeState() == "rebasing" {
return gui.createErrorPanel(gui.g, gui.Tr.SLocalize("cantRedoWhileRebasing")) return gui.createErrorPanel(gui.g, gui.Tr.SLocalize("cantRedoWhileRebasing"))
} }
@ -183,20 +183,17 @@ func (gui *Gui) handleHardResetWithAutoStash(commitSha string, options handleHar
} }
if err := gui.GitCommand.StashDo(0, "pop"); err != nil { if err := gui.GitCommand.StashDo(0, "pop"); err != nil {
if err := gui.refreshSidePanels(g); err != nil { if err := gui.refreshSidePanels(refreshOptions{}); err != nil {
return err return err
} }
return gui.createErrorPanel(g, err.Error()) return gui.createErrorPanel(g, err.Error())
} }
return gui.refreshSidePanels(g) return nil
}) })
}, nil) }, nil)
} }
return gui.WithWaitingStatus(options.WaitingStatus, func() error { return gui.WithWaitingStatus(options.WaitingStatus, func() error {
if err := reset(); err != nil { return reset()
return err
}
return gui.refreshSidePanels(gui.g)
}) })
} }

View File

@ -14,27 +14,104 @@ import (
var cyclableViews = []string{"status", "files", "branches", "commits", "stash"} var cyclableViews = []string{"status", "files", "branches", "commits", "stash"}
func (gui *Gui) refreshSidePanels(g *gocui.Gui) error { const (
COMMITS = iota
BRANCHES
FILES
STASH
REFLOG
TAGS
REMOTES
)
const (
SYNC = iota // wait until everything is done before returning
ASYNC // return immediately, allowing each independent thing to update itself
BLOCK_UI // wrap code in an update call to ensure UI updates all at once and keybindings aren't executed till complete
)
type refreshOptions struct {
then func()
scope []int
mode int
}
type innerRefreshOptions struct {
scopeMap map[int]bool
mode int
}
func intArrToMap(arr []int) map[int]bool {
output := map[int]bool{}
for _, el := range arr {
output[el] = true
}
return output
}
func (gui *Gui) refreshSidePanels(options refreshOptions) error {
wg := sync.WaitGroup{} wg := sync.WaitGroup{}
wg.Add(3) f := func() {
var scopeMap map[int]bool
if len(options.scope) == 0 {
scopeMap = intArrToMap([]int{COMMITS, BRANCHES, FILES, STASH, REFLOG, TAGS, REMOTES})
} else {
scopeMap = intArrToMap(options.scope)
}
func() { if scopeMap[COMMITS] || scopeMap[BRANCHES] || scopeMap[REFLOG] || scopeMap[TAGS] || scopeMap[REMOTES] {
gui.refreshCommits(g) wg.Add(1)
wg.Done() func() {
}() if options.mode == ASYNC {
go gui.refreshCommits(gui.g)
} else {
gui.refreshCommits(gui.g)
}
wg.Done()
}()
}
func() { if scopeMap[FILES] {
gui.refreshFiles() wg.Add(1)
wg.Done() func() {
}() if options.mode == ASYNC {
go gui.refreshFiles()
} else {
gui.refreshFiles()
}
wg.Done()
}()
func() { }
gui.refreshStashEntries(g)
wg.Done()
}()
wg.Wait() if scopeMap[STASH] {
wg.Add(1)
func() {
if options.mode == ASYNC {
go gui.refreshStashEntries(gui.g)
} else {
gui.refreshStashEntries(gui.g)
}
wg.Done()
}()
}
wg.Wait()
if options.then != nil {
options.then()
}
}
if options.mode == BLOCK_UI {
gui.g.Update(func(g *gocui.Gui) error {
f()
return nil
})
} else {
f()
}
return nil return nil
} }

View File

@ -5,9 +5,9 @@ import (
"time" "time"
) )
func UnixToTimeAgo(timestamp int) string { func UnixToTimeAgo(timestamp int64) string {
now := time.Now().Unix() now := time.Now().Unix()
delta := float64(now - int64(timestamp)) delta := float64(now - timestamp)
// we go seconds, minutes, hours, days, weeks, months, years // we go seconds, minutes, hours, days, weeks, months, years
conversions := []float64{60, 60, 24, 7, 4.34524, 12} conversions := []float64{60, 60, 24, 7, 4.34524, 12}
labels := []string{"s", "m", "h", "d", "w", "m", "y"} labels := []string{"s", "m", "h", "d", "w", "m", "y"}
@ -19,3 +19,7 @@ func UnixToTimeAgo(timestamp int) string {
} }
return fmt.Sprintf("%dy", int(delta)) return fmt.Sprintf("%dy", int(delta))
} }
func UnixToDate(timestamp int64) string {
return time.Unix(timestamp, 0).Format(time.RFC822)
}

1
wiKrApOPpr Normal file
View File

@ -0,0 +1 @@
gPmoiDUdxe

1
zQgAQNYHAL Normal file
View File

@ -0,0 +1 @@
lWzCfsAImp