From 198d237679bcc19655138f76a11770c3ef91ec4f Mon Sep 17 00:00:00 2001 From: Jesse Duffield Date: Fri, 27 Mar 2020 19:12:15 +1100 Subject: [PATCH] more centralised handling of refreshing --- AgeMQemvPk | 1 + CqSiBeejXz | 1 + EzGTvaqMIv | 1 + FcKgiBNeUX | 1 + KtDIVguUOP | 1 + TGpKLocWft | 1 + UkUKNwQtgP | 1 + kTrVvqUAxG | 1 + pkg/commands/branch_list_builder.go | 9 +-- pkg/commands/commit.go | 16 ++-- pkg/commands/commit_list_builder.go | 19 +++-- pkg/commands/git.go | 18 ++--- pkg/gui/branches_panel.go | 20 ++--- pkg/gui/commit_files_panel.go | 2 +- pkg/gui/commit_message_panel.go | 2 +- pkg/gui/commits_panel.go | 13 +-- pkg/gui/credentials_panel.go | 2 +- pkg/gui/files_panel.go | 10 +-- pkg/gui/gui.go | 5 +- pkg/gui/merge_panel.go | 2 +- pkg/gui/patch_options_panel.go | 4 +- pkg/gui/presentation/commits.go | 3 +- pkg/gui/presentation/reflog_commits.go | 6 +- pkg/gui/rebase_options_panel.go | 8 +- pkg/gui/remote_branches_panel.go | 2 +- pkg/gui/reset_menu_panel.go | 5 +- pkg/gui/status_panel.go | 31 +++---- pkg/gui/undoing.go | 13 ++- pkg/gui/view_helpers.go | 107 +++++++++++++++++++++---- pkg/utils/date.go | 8 +- wiKrApOPpr | 1 + zQgAQNYHAL | 1 + 32 files changed, 189 insertions(+), 126 deletions(-) create mode 100644 AgeMQemvPk create mode 100644 CqSiBeejXz create mode 100644 EzGTvaqMIv create mode 100644 FcKgiBNeUX create mode 100644 KtDIVguUOP create mode 100644 TGpKLocWft create mode 100644 UkUKNwQtgP create mode 100644 kTrVvqUAxG create mode 100644 wiKrApOPpr create mode 100644 zQgAQNYHAL diff --git a/AgeMQemvPk b/AgeMQemvPk new file mode 100644 index 000000000..0e90a6d4e --- /dev/null +++ b/AgeMQemvPk @@ -0,0 +1 @@ +YrWrygkDZr \ No newline at end of file diff --git a/CqSiBeejXz b/CqSiBeejXz new file mode 100644 index 000000000..f69cbb804 --- /dev/null +++ b/CqSiBeejXz @@ -0,0 +1 @@ +pnzuDhnmXj \ No newline at end of file diff --git a/EzGTvaqMIv b/EzGTvaqMIv new file mode 100644 index 000000000..83656069a --- /dev/null +++ b/EzGTvaqMIv @@ -0,0 +1 @@ +FwtesbRmIy \ No newline at end of file diff --git a/FcKgiBNeUX b/FcKgiBNeUX new file mode 100644 index 000000000..ac1bb7afd --- /dev/null +++ b/FcKgiBNeUX @@ -0,0 +1 @@ +yZXPONHgYA \ No newline at end of file diff --git a/KtDIVguUOP b/KtDIVguUOP new file mode 100644 index 000000000..d54ab58db --- /dev/null +++ b/KtDIVguUOP @@ -0,0 +1 @@ +zTceFimWln \ No newline at end of file diff --git a/TGpKLocWft b/TGpKLocWft new file mode 100644 index 000000000..fb7ff4e41 --- /dev/null +++ b/TGpKLocWft @@ -0,0 +1 @@ +wYOKNLUbIn \ No newline at end of file diff --git a/UkUKNwQtgP b/UkUKNwQtgP new file mode 100644 index 000000000..31db6aafd --- /dev/null +++ b/UkUKNwQtgP @@ -0,0 +1 @@ +KJkGhkBJvv \ No newline at end of file diff --git a/kTrVvqUAxG b/kTrVvqUAxG new file mode 100644 index 000000000..7bdb57304 --- /dev/null +++ b/kTrVvqUAxG @@ -0,0 +1 @@ +LdOMEqAOcq \ No newline at end of file diff --git a/pkg/commands/branch_list_builder.go b/pkg/commands/branch_list_builder.go index f7949d2bc..1430bbf92 100644 --- a/pkg/commands/branch_list_builder.go +++ b/pkg/commands/branch_list_builder.go @@ -2,7 +2,6 @@ package commands import ( "regexp" - "strconv" "strings" "github.com/jesseduffield/lazygit/pkg/utils" @@ -145,13 +144,7 @@ func (b *BranchListBuilder) obtainReflogBranches() []*Branch { 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 - } - - recency := utils.UnixToTimeAgo(timestamp) + recency := utils.UnixToTimeAgo(commit.UnixTimestamp) for _, branchName := range match[1:] { if !foundBranchesMap[branchName] { foundBranchesMap[branchName] = true diff --git a/pkg/commands/commit.go b/pkg/commands/commit.go index a400da928..ea4192b33 100644 --- a/pkg/commands/commit.go +++ b/pkg/commands/commit.go @@ -2,14 +2,14 @@ package commands // Commit : A git commit type Commit struct { - Sha string - Name string - Status string // one of "unpushed", "pushed", "merged", "rebasing" or "selected" - Action string // one of "", "pick", "edit", "squash", "reword", "drop", "fixup" - Tags []string - ExtraInfo string // something like 'HEAD -> master, tag: v0.15.2' - Author string - Date string + Sha string + Name string + Status string // one of "unpushed", "pushed", "merged", "rebasing" or "selected" + Action string // one of "", "pick", "edit", "squash", "reword", "drop", "fixup" + Tags []string + ExtraInfo string // something like 'HEAD -> master, tag: v0.15.2' + Author string + UnixTimestamp int64 } func (c *Commit) ShortSha() string { diff --git a/pkg/commands/commit_list_builder.go b/pkg/commands/commit_list_builder.go index a39ab7593..b48c305c4 100644 --- a/pkg/commands/commit_list_builder.go +++ b/pkg/commands/commit_list_builder.go @@ -7,6 +7,7 @@ import ( "os/exec" "path/filepath" "regexp" + "strconv" "strings" "github.com/fatih/color" @@ -56,7 +57,7 @@ func (c *CommitListBuilder) extractCommitFromLine(line string) *Commit { split := strings.Split(line, SEPARATION_CHAR) sha := split[0] - date := split[1] + unixTimestamp := split[1] author := split[2] extraInfo := strings.TrimSpace(split[3]) message := strings.Join(split[4:], SEPARATION_CHAR) @@ -70,13 +71,15 @@ func (c *CommitListBuilder) extractCommitFromLine(line string) *Commit { } } + unitTimestampInt, _ := strconv.Atoi(unixTimestamp) + return &Commit{ - Sha: sha, - Name: message, - Tags: tags, - ExtraInfo: extraInfo, - Date: date, - Author: author, + Sha: sha, + Name: message, + Tags: tags, + ExtraInfo: extraInfo, + UnixTimestamp: int64(unitTimestampInt), + Author: author, } } @@ -305,5 +308,5 @@ func (c *CommitListBuilder) getLogCmd(limit bool) *exec.Cmd { 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)) } diff --git a/pkg/commands/git.go b/pkg/commands/git.go index 42b075915..803cfe2d4 100644 --- a/pkg/commands/git.go +++ b/pkg/commands/git.go @@ -484,11 +484,7 @@ func (c *GitCommand) GitStatus() (string, error) { // IsInMergeState states whether we are still mid-merge func (c *GitCommand) IsInMergeState() (bool, error) { - output, err := c.OSCommand.RunCommandWithOutput("git status --untracked-files=all") - if err != nil { - return false, err - } - return strings.Contains(output, "conclude merge") || strings.Contains(output, "unmerged paths"), nil + return c.OSCommand.FileExists(fmt.Sprintf("%s/MERGE_HEAD", c.DotGitDir)) } // 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 } + unixTimestamp, _ := strconv.Atoi(match[2]) + commit := &Commit{ - Sha: match[1], - Name: match[3], - Date: match[2], - Status: "reflog", + Sha: match[1], + Name: match[3], + UnixTimestamp: int64(unixTimestamp), + 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 return true, nil } diff --git a/pkg/gui/branches_panel.go b/pkg/gui/branches_panel.go index 268247630..6efb52264 100644 --- a/pkg/gui/branches_panel.go +++ b/pkg/gui/branches_panel.go @@ -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 { _ = gui.createErrorPanel(g, err.Error()) } - return gui.refreshSidePanels(g) + return gui.refreshSidePanels(refreshOptions{mode: ASYNC}) }, nil) } @@ -167,14 +167,13 @@ func (gui *Gui) handleCheckoutRef(ref string, options handleCheckoutRefOptions) } onSuccess() - 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 gui.createErrorPanel(g, err.Error()) } - return gui.refreshSidePanels(g) + return gui.refreshSidePanels(refreshOptions{mode: BLOCK_UI}) }, nil) } @@ -182,10 +181,9 @@ func (gui *Gui) handleCheckoutRef(ref string, options handleCheckoutRefOptions) return err } } - 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 { return gui.createErrorPanel(g, err.Error()) } - if err := gui.refreshSidePanels(g); err != nil { - return gui.createErrorPanel(g, err.Error()) - } - return gui.handleBranchSelect(g, v) + gui.State.Panels.Branches.SelectedLine = 0 + return gui.refreshSidePanels(refreshOptions{mode: ASYNC}) }) } @@ -263,7 +259,7 @@ func (gui *Gui) deleteNamedBranch(g *gocui.Gui, v *gocui.View, selectedBranch *c } return gui.createErrorPanel(g, errMessage) } - return gui.refreshSidePanels(g) + return gui.refreshSidePanels(refreshOptions{mode: ASYNC, scope: []int{BRANCHES}}) }, 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 { _ = gui.createErrorPanel(gui.g, err.Error()) } - _ = gui.refreshSidePanels(gui.g) + _ = gui.refreshSidePanels(refreshOptions{mode: ASYNC}) } else { if err := gui.GitCommand.FastForward(branch.Name, remoteName, remoteBranchName); err != nil { _ = gui.createErrorPanel(gui.g, err.Error()) diff --git a/pkg/gui/commit_files_panel.go b/pkg/gui/commit_files_panel.go index cafc4f95b..4d4cdcbbb 100644 --- a/pkg/gui/commit_files_panel.go +++ b/pkg/gui/commit_files_panel.go @@ -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) } diff --git a/pkg/gui/commit_message_panel.go b/pkg/gui/commit_message_panel.go index ea65dc9cf..8c11e5a83 100644 --- a/pkg/gui/commit_message_panel.go +++ b/pkg/gui/commit_message_panel.go @@ -48,7 +48,7 @@ func (gui *Gui) handleCommitConfirm(g *gocui.Gui, v *gocui.View) error { _ = v.SetOrigin(0, 0) _, _ = g.SetViewOnBottom("commitMessage") _ = 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 { diff --git a/pkg/gui/commits_panel.go b/pkg/gui/commits_panel.go index e0b904f5b..c2757ab93 100644 --- a/pkg/gui/commits_panel.go +++ b/pkg/gui/commits_panel.go @@ -72,10 +72,6 @@ func (gui *Gui) handleCommitSelect(g *gocui.Gui, v *gocui.View) 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.Add(2) @@ -87,6 +83,9 @@ func (gui *Gui) refreshCommits(g *gocui.Gui) error { go func() { gui.refreshCommitsWithLimit() + if g.CurrentView() == gui.getCommitFilesView() || (g.CurrentView() == gui.getMainView() || gui.State.MainContext == "patch-building") { + gui.refreshCommitFilesView() + } wg.Done() }() @@ -94,10 +93,6 @@ func (gui *Gui) refreshCommits(g *gocui.Gui) error { gui.refreshStatus() - if g.CurrentView() == gui.getCommitFilesView() || (g.CurrentView() == gui.getMainView() || gui.State.MainContext == "patch-building") { - return gui.refreshCommitFilesView() - } - 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.refreshSidePanels(gui.g) + return gui.refreshSidePanels(refreshOptions{mode: ASYNC}) }, nil) } diff --git a/pkg/gui/credentials_panel.go b/pkg/gui/credentials_panel.go index aa2caecfa..7be93cc94 100644 --- a/pkg/gui/credentials_panel.go +++ b/pkg/gui/credentials_panel.go @@ -100,6 +100,6 @@ func (gui *Gui) HandleCredentialsPopup(g *gocui.Gui, popupOpened bool, cmdErr er _ = gui.createSpecificErrorPanel(errMessage, gui.getFilesView(), false) } else { _ = gui.closeConfirmationPrompt(g, true) - _ = gui.refreshSidePanels(g) + _ = gui.refreshSidePanels(refreshOptions{mode: ASYNC}) } } diff --git a/pkg/gui/files_panel.go b/pkg/gui/files_panel.go index bcfeccaa1..bee4cc6f8 100644 --- a/pkg/gui/files_panel.go +++ b/pkg/gui/files_panel.go @@ -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 { - 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")) } 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 { - 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")) } if len(gui.State.Commits) == 0 { @@ -317,14 +317,14 @@ func (gui *Gui) handleAmendCommitPress(g *gocui.Gui, filesView *gocui.View) erro return nil } - return gui.refreshSidePanels(g) + return gui.refreshSidePanels(refreshOptions{mode: ASYNC}) }, nil) } // handleCommitEditorPress - handle when the user wants to commit changes via // their editor rather than via the popup panel 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")) } 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)) - return gui.updateWorkTreeState() + return nil } func (gui *Gui) catSelectedFile(g *gocui.Gui) (string, error) { diff --git a/pkg/gui/gui.go b/pkg/gui/gui.go index b4805b7f3..1c3c733c0 100644 --- a/pkg/gui/gui.go +++ b/pkg/gui/gui.go @@ -194,7 +194,6 @@ type guiState struct { Platform commands.Platform Updating bool Panels *panelStates - WorkingTreeState string // one of "merging", "rebasing", "normal" MainContext string // used to keep the main and secondary views' contexts in sync CherryPickedCommits []*commands.Commit 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 { - return gui.refreshSidePanels(g) + return gui.refreshSidePanels(refreshOptions{mode: ASYNC}) } func max(a, b int) int { @@ -863,7 +862,7 @@ func (gui *Gui) loadNewRepo() error { } gui.waitForIntro.Done() - if err := gui.refreshSidePanels(gui.g); err != nil { + if err := gui.refreshSidePanels(refreshOptions{mode: ASYNC}); err != nil { return err } diff --git a/pkg/gui/merge_panel.go b/pkg/gui/merge_panel.go index fa0928f22..e94d5541c 100644 --- a/pkg/gui/merge_panel.go +++ b/pkg/gui/merge_panel.go @@ -281,7 +281,7 @@ func (gui *Gui) handleCompleteMerge() error { } // if we got conflicts after unstashing, we don't want to call any git // commands to continue rebasing/merging here - if gui.State.WorkingTreeState == "normal" { + if gui.workingTreeState() == "normal" { 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 diff --git a/pkg/gui/patch_options_panel.go b/pkg/gui/patch_options_panel.go index 3d24c2b11..c47374889 100644 --- a/pkg/gui/patch_options_panel.go +++ b/pkg/gui/patch_options_panel.go @@ -59,7 +59,7 @@ func (gui *Gui) getPatchCommitIndex() int { } 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 true, nil @@ -128,7 +128,7 @@ func (gui *Gui) handleApplyPatch() error { if err := gui.GitCommand.PatchManager.ApplyPatches(false); err != nil { return gui.createErrorPanel(gui.g, err.Error()) } - return gui.refreshSidePanels(gui.g) + return gui.refreshSidePanels(refreshOptions{mode: ASYNC}) } func (gui *Gui) handleResetPatch() error { diff --git a/pkg/gui/presentation/commits.go b/pkg/gui/presentation/commits.go index dedf4a01b..b54f928ac 100644 --- a/pkg/gui/presentation/commits.go +++ b/pkg/gui/presentation/commits.go @@ -63,8 +63,7 @@ func getFullDescriptionDisplayStringsForCommit(c *commands.Commit, cherryPickedC } tagString := "" - truncatedDate := utils.TruncateWithEllipsis(c.Date, 15) - secondColumnString := blue.Sprint(truncatedDate) + secondColumnString := blue.Sprint(utils.UnixToDate(c.UnixTimestamp)) if c.Action != "" { secondColumnString = cyan.Sprint(c.Action) } else if c.ExtraInfo != "" { diff --git a/pkg/gui/presentation/reflog_commits.go b/pkg/gui/presentation/reflog_commits.go index a3e39a70d..e57560b76 100644 --- a/pkg/gui/presentation/reflog_commits.go +++ b/pkg/gui/presentation/reflog_commits.go @@ -27,7 +27,11 @@ func GetReflogCommitListDisplayStrings(commits []*commands.Commit, fullDescripti func getFullDescriptionDisplayStringsForReflogCommit(c *commands.Commit) []string { 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 { diff --git a/pkg/gui/rebase_options_panel.go b/pkg/gui/rebase_options_panel.go index a4ba8e35a..05bc44bb3 100644 --- a/pkg/gui/rebase_options_panel.go +++ b/pkg/gui/rebase_options_panel.go @@ -10,7 +10,7 @@ import ( func (gui *Gui) handleCreateRebaseOptionsMenu(g *gocui.Gui, v *gocui.View) error { options := []string{"continue", "abort"} - if gui.State.WorkingTreeState == "rebasing" { + if gui.workingTreeState() == "rebasing" { options = append(options, "skip") } @@ -27,7 +27,7 @@ func (gui *Gui) handleCreateRebaseOptionsMenu(g *gocui.Gui, v *gocui.View) error } var title string - if gui.State.WorkingTreeState == "merging" { + if gui.workingTreeState() == "merging" { title = gui.Tr.SLocalize("MergeOptionsTitle") } else { 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 { - status := gui.State.WorkingTreeState + status := gui.workingTreeState() if status != "merging" && status != "rebasing" { 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 { - if err := gui.refreshSidePanels(gui.g); err != nil { + if err := gui.refreshSidePanels(refreshOptions{mode: ASYNC}); err != nil { return err } if result == nil { diff --git a/pkg/gui/remote_branches_panel.go b/pkg/gui/remote_branches_panel.go index ffc353de4..69628e6f9 100644 --- a/pkg/gui/remote_branches_panel.go +++ b/pkg/gui/remote_branches_panel.go @@ -126,7 +126,7 @@ func (gui *Gui) handleSetBranchUpstream(g *gocui.Gui, v *gocui.View) error { return err } - return gui.refreshSidePanels(gui.g) + return gui.refreshSidePanels(refreshOptions{scope: []int{BRANCHES, REMOTES}}) }, nil) } diff --git a/pkg/gui/reset_menu_panel.go b/pkg/gui/reset_menu_panel.go index dab7ee9dd..1c3dce5bf 100644 --- a/pkg/gui/reset_menu_panel.go +++ b/pkg/gui/reset_menu_panel.go @@ -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 gui.State.Panels.Commits.LimitCommits = true - if err := gui.refreshCommits(gui.g); err != nil { - return err - } - if err := gui.refreshFiles(); err != nil { + if err := gui.refreshSidePanels(refreshOptions{scope: []int{FILES, BRANCHES, REFLOG, COMMITS}}); err != nil { return err } if err := gui.resetOrigin(gui.getCommitsView()); err != nil { diff --git a/pkg/gui/status_panel.go b/pkg/gui/status_panel.go index c6ebff794..6a952b580 100644 --- a/pkg/gui/status_panel.go +++ b/pkg/gui/status_panel.go @@ -12,6 +12,7 @@ import ( // never call this on its own, it should only be called from within refreshCommits() func (gui *Gui) refreshStatus() { + currentBranch := gui.currentBranch() status := "" @@ -26,8 +27,8 @@ func (gui *Gui) refreshStatus() { status = utils.ColoredString(fmt.Sprintf("ā†‘%sā†“%s ", currentBranch.Pushables, currentBranch.Pullables), trackColor) } - if gui.State.WorkingTreeState != "normal" { - status += utils.ColoredString(fmt.Sprintf("(%s) ", gui.State.WorkingTreeState), color.FgYellow) + if gui.workingTreeState() != "normal" { + status += utils.ColoredString(fmt.Sprintf("(%s) ", gui.workingTreeState()), color.FgYellow) } 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() upstreamStatus := fmt.Sprintf("ā†‘%sā†“%s", currentBranch.Pushables, currentBranch.Pullables) repoName := utils.GetCurrentRepoName() - gui.Log.Warn(gui.State.WorkingTreeState) - switch gui.State.WorkingTreeState { + switch gui.workingTreeState() { case "rebasing", "merging": - workingTreeStatus := fmt.Sprintf("(%s)", gui.State.WorkingTreeState) + workingTreeStatus := fmt.Sprintf("(%s)", gui.workingTreeState()) if cursorInSubstring(cx, upstreamStatus+" ", workingTreeStatus) { return gui.handleCreateRebaseOptionsMenu(gui.g, v) } @@ -128,23 +128,14 @@ func lazygitTitle() string { |___/ |___/ ` } -func (gui *Gui) updateWorkTreeState() error { - rebaseMode, err := gui.GitCommand.RebaseMode() - if err != nil { - return err - } +func (gui *Gui) workingTreeState() string { + rebaseMode, _ := gui.GitCommand.RebaseMode() if rebaseMode != "" { - gui.State.WorkingTreeState = "rebasing" - return nil - } - merging, err := gui.GitCommand.IsInMergeState() - if err != nil { - return err + return "rebasing" } + merging, _ := gui.GitCommand.IsInMergeState() if merging { - gui.State.WorkingTreeState = "merging" - return nil + return "merging" } - gui.State.WorkingTreeState = "normal" - return nil + return "normal" } diff --git a/pkg/gui/undoing.go b/pkg/gui/undoing.go index 0fba4b86b..4bdff1421 100644 --- a/pkg/gui/undoing.go +++ b/pkg/gui/undoing.go @@ -87,7 +87,7 @@ func (gui *Gui) reflogUndo(g *gocui.Gui, v *gocui.View) error { undoEnvVars := []string{"GIT_REFLOG_ACTION=[lazygit undo]"} undoingStatus := gui.Tr.SLocalize("UndoingStatus") - if gui.State.WorkingTreeState == "rebasing" { + if gui.workingTreeState() == "rebasing" { 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]"} redoingStatus := gui.Tr.SLocalize("RedoingStatus") - if gui.State.WorkingTreeState == "rebasing" { + if gui.workingTreeState() == "rebasing" { 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.refreshSidePanels(g); err != nil { + if err := gui.refreshSidePanels(refreshOptions{}); err != nil { return err } return gui.createErrorPanel(g, err.Error()) } - return gui.refreshSidePanels(g) + return nil }) }, nil) } return gui.WithWaitingStatus(options.WaitingStatus, func() error { - if err := reset(); err != nil { - return err - } - return gui.refreshSidePanels(gui.g) + return reset() }) } diff --git a/pkg/gui/view_helpers.go b/pkg/gui/view_helpers.go index 831facb84..f4227ba67 100644 --- a/pkg/gui/view_helpers.go +++ b/pkg/gui/view_helpers.go @@ -14,27 +14,104 @@ import ( 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.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() { - gui.refreshCommits(g) - wg.Done() - }() + if scopeMap[COMMITS] || scopeMap[BRANCHES] || scopeMap[REFLOG] || scopeMap[TAGS] || scopeMap[REMOTES] { + wg.Add(1) + func() { + if options.mode == ASYNC { + go gui.refreshCommits(gui.g) + } else { + gui.refreshCommits(gui.g) + } + wg.Done() + }() + } - func() { - gui.refreshFiles() - wg.Done() - }() + if scopeMap[FILES] { + wg.Add(1) + 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 } diff --git a/pkg/utils/date.go b/pkg/utils/date.go index 7f8f8f8a5..40165ecaa 100644 --- a/pkg/utils/date.go +++ b/pkg/utils/date.go @@ -5,9 +5,9 @@ import ( "time" ) -func UnixToTimeAgo(timestamp int) string { +func UnixToTimeAgo(timestamp int64) string { now := time.Now().Unix() - delta := float64(now - int64(timestamp)) + delta := float64(now - 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"} @@ -19,3 +19,7 @@ func UnixToTimeAgo(timestamp int) string { } return fmt.Sprintf("%dy", int(delta)) } + +func UnixToDate(timestamp int64) string { + return time.Unix(timestamp, 0).Format(time.RFC822) +} diff --git a/wiKrApOPpr b/wiKrApOPpr new file mode 100644 index 000000000..9abe8ef9b --- /dev/null +++ b/wiKrApOPpr @@ -0,0 +1 @@ +gPmoiDUdxe \ No newline at end of file diff --git a/zQgAQNYHAL b/zQgAQNYHAL new file mode 100644 index 000000000..fabdcb3de --- /dev/null +++ b/zQgAQNYHAL @@ -0,0 +1 @@ +lWzCfsAImp \ No newline at end of file