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:
parent
39315ca1e2
commit
198d237679
1
AgeMQemvPk
Normal file
1
AgeMQemvPk
Normal file
@ -0,0 +1 @@
|
|||||||
|
YrWrygkDZr
|
1
CqSiBeejXz
Normal file
1
CqSiBeejXz
Normal file
@ -0,0 +1 @@
|
|||||||
|
pnzuDhnmXj
|
1
EzGTvaqMIv
Normal file
1
EzGTvaqMIv
Normal file
@ -0,0 +1 @@
|
|||||||
|
FwtesbRmIy
|
1
FcKgiBNeUX
Normal file
1
FcKgiBNeUX
Normal file
@ -0,0 +1 @@
|
|||||||
|
yZXPONHgYA
|
1
KtDIVguUOP
Normal file
1
KtDIVguUOP
Normal file
@ -0,0 +1 @@
|
|||||||
|
zTceFimWln
|
1
TGpKLocWft
Normal file
1
TGpKLocWft
Normal file
@ -0,0 +1 @@
|
|||||||
|
wYOKNLUbIn
|
1
UkUKNwQtgP
Normal file
1
UkUKNwQtgP
Normal file
@ -0,0 +1 @@
|
|||||||
|
KJkGhkBJvv
|
1
kTrVvqUAxG
Normal file
1
kTrVvqUAxG
Normal file
@ -0,0 +1 @@
|
|||||||
|
LdOMEqAOcq
|
@ -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
|
||||||
|
@ -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 {
|
||||||
|
@ -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))
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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())
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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 {
|
||||||
|
@ -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 != "" {
|
||||||
|
@ -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 {
|
||||||
|
@ -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 {
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 {
|
||||||
|
@ -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
|
|
||||||
}
|
}
|
||||||
|
@ -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)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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
1
wiKrApOPpr
Normal file
@ -0,0 +1 @@
|
|||||||
|
gPmoiDUdxe
|
1
zQgAQNYHAL
Normal file
1
zQgAQNYHAL
Normal file
@ -0,0 +1 @@
|
|||||||
|
lWzCfsAImp
|
Loading…
x
Reference in New Issue
Block a user