mirror of
https://github.com/jesseduffield/lazygit.git
synced 2024-11-28 09:08:41 +02:00
Add inline status for pushing/pulling/fast-forwarding branches
When pulling/pushing/fast-forwarding a branch, show this state in the branches list for that branch for as long as the operation takes, to make it easier to see when it's done (without having to stare at the status bar in the lower left). This will hopefully help with making these operations feel more predictable, now that we no longer show a loader panel for them.
This commit is contained in:
parent
7075b66bc6
commit
707fa37160
@ -65,6 +65,10 @@ func (b *Branch) ID() string {
|
||||
return b.RefName()
|
||||
}
|
||||
|
||||
func (b *Branch) URN() string {
|
||||
return "branch-" + b.ID()
|
||||
}
|
||||
|
||||
func (b *Branch) Description() string {
|
||||
return b.RefName()
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ func NewBranchesContext(c *ContextCommon) *BranchesContext {
|
||||
getDisplayStrings := func(_ int, _ int) [][]string {
|
||||
return presentation.GetBranchListDisplayStrings(
|
||||
viewModel.GetItems(),
|
||||
c.State().GetItemOperation,
|
||||
c.State().GetRepoState().GetScreenMode() != types.SCREEN_NORMAL,
|
||||
c.Modes().Diffing.Ref,
|
||||
c.Tr,
|
||||
|
@ -563,14 +563,7 @@ func (self *BranchesController) fastForward(branch *models.Branch) error {
|
||||
|
||||
action := self.c.Tr.Actions.FastForwardBranch
|
||||
|
||||
message := utils.ResolvePlaceholderString(
|
||||
self.c.Tr.FastForwarding,
|
||||
map[string]string{
|
||||
"branch": branch.Name,
|
||||
},
|
||||
)
|
||||
|
||||
return self.c.WithWaitingStatus(message, func(task gocui.Task) error {
|
||||
return self.c.WithInlineStatus(branch, types.ItemOperationFastForwarding, context.LOCAL_BRANCHES_CONTEXT_KEY, func(task gocui.Task) error {
|
||||
worktree, ok := self.worktreeForBranch(branch)
|
||||
if ok {
|
||||
self.c.LogAction(action)
|
||||
|
@ -678,7 +678,7 @@ func (self *RefreshHelper) refreshStatus() {
|
||||
|
||||
repoName := self.c.Git().RepoPaths.RepoName()
|
||||
|
||||
status := presentation.FormatStatus(repoName, currentBranch, linkedWorktreeName, workingTreeState, self.c.Tr)
|
||||
status := presentation.FormatStatus(repoName, currentBranch, types.ItemOperationNone, linkedWorktreeName, workingTreeState, self.c.Tr)
|
||||
|
||||
self.c.SetViewContent(self.c.Views().Status, status)
|
||||
}
|
||||
|
@ -106,7 +106,7 @@ func (self *StatusController) onClick() error {
|
||||
}
|
||||
|
||||
cx, _ := self.c.Views().Status.Cursor()
|
||||
upstreamStatus := presentation.BranchStatus(currentBranch, self.c.Tr)
|
||||
upstreamStatus := presentation.BranchStatus(currentBranch, types.ItemOperationNone, self.c.Tr)
|
||||
repoName := self.c.Git().RepoPaths.RepoName()
|
||||
workingTreeState := self.c.Git().Status.WorkingTreeState()
|
||||
switch workingTreeState {
|
||||
|
@ -7,6 +7,7 @@ import (
|
||||
"github.com/jesseduffield/gocui"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/git_commands"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/context"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||
)
|
||||
@ -73,13 +74,13 @@ func (self *SyncController) push(currentBranch *models.Branch) error {
|
||||
if currentBranch.IsTrackingRemote() {
|
||||
opts := pushOpts{}
|
||||
if currentBranch.HasCommitsToPull() {
|
||||
return self.requestToForcePush(opts)
|
||||
return self.requestToForcePush(currentBranch, opts)
|
||||
} else {
|
||||
return self.pushAux(opts)
|
||||
return self.pushAux(currentBranch, opts)
|
||||
}
|
||||
} else {
|
||||
if self.c.Git().Config.GetPushToCurrent() {
|
||||
return self.pushAux(pushOpts{setUpstream: true})
|
||||
return self.pushAux(currentBranch, pushOpts{setUpstream: true})
|
||||
} else {
|
||||
return self.c.Helpers().Upstream.PromptForUpstreamWithInitialContent(currentBranch, func(upstream string) error {
|
||||
upstreamRemote, upstreamBranch, err := self.c.Helpers().Upstream.ParseUpstream(upstream)
|
||||
@ -87,7 +88,7 @@ func (self *SyncController) push(currentBranch *models.Branch) error {
|
||||
return self.c.Error(err)
|
||||
}
|
||||
|
||||
return self.pushAux(pushOpts{
|
||||
return self.pushAux(currentBranch, pushOpts{
|
||||
setUpstream: true,
|
||||
upstreamRemote: upstreamRemote,
|
||||
upstreamBranch: upstreamBranch,
|
||||
@ -107,11 +108,11 @@ func (self *SyncController) pull(currentBranch *models.Branch) error {
|
||||
return self.c.Error(err)
|
||||
}
|
||||
|
||||
return self.PullAux(PullFilesOptions{Action: action})
|
||||
return self.PullAux(currentBranch, PullFilesOptions{Action: action})
|
||||
})
|
||||
}
|
||||
|
||||
return self.PullAux(PullFilesOptions{Action: action})
|
||||
return self.PullAux(currentBranch, PullFilesOptions{Action: action})
|
||||
}
|
||||
|
||||
func (self *SyncController) setCurrentBranchUpstream(upstream string) error {
|
||||
@ -139,8 +140,8 @@ type PullFilesOptions struct {
|
||||
Action string
|
||||
}
|
||||
|
||||
func (self *SyncController) PullAux(opts PullFilesOptions) error {
|
||||
return self.c.WithWaitingStatus(self.c.Tr.PullingStatus, func(task gocui.Task) error {
|
||||
func (self *SyncController) PullAux(currentBranch *models.Branch, opts PullFilesOptions) error {
|
||||
return self.c.WithInlineStatus(currentBranch, types.ItemOperationPulling, context.LOCAL_BRANCHES_CONTEXT_KEY, func(task gocui.Task) error {
|
||||
return self.pullWithLock(task, opts)
|
||||
})
|
||||
}
|
||||
@ -167,8 +168,8 @@ type pushOpts struct {
|
||||
setUpstream bool
|
||||
}
|
||||
|
||||
func (self *SyncController) pushAux(opts pushOpts) error {
|
||||
return self.c.WithWaitingStatus(self.c.Tr.PushingStatus, func(task gocui.Task) error {
|
||||
func (self *SyncController) pushAux(currentBranch *models.Branch, opts pushOpts) error {
|
||||
return self.c.WithInlineStatus(currentBranch, types.ItemOperationPushing, context.LOCAL_BRANCHES_CONTEXT_KEY, func(task gocui.Task) error {
|
||||
self.c.LogAction(self.c.Tr.Actions.Push)
|
||||
err := self.c.Git().Sync.Push(
|
||||
task,
|
||||
@ -192,18 +193,18 @@ func (self *SyncController) pushAux(opts pushOpts) error {
|
||||
newOpts := opts
|
||||
newOpts.force = true
|
||||
|
||||
return self.pushAux(newOpts)
|
||||
return self.pushAux(currentBranch, newOpts)
|
||||
},
|
||||
})
|
||||
return nil
|
||||
}
|
||||
_ = self.c.Error(err)
|
||||
return err
|
||||
}
|
||||
return self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC})
|
||||
})
|
||||
}
|
||||
|
||||
func (self *SyncController) requestToForcePush(opts pushOpts) error {
|
||||
func (self *SyncController) requestToForcePush(currentBranch *models.Branch, opts pushOpts) error {
|
||||
forcePushDisabled := self.c.UserConfig.Git.DisableForcePushing
|
||||
if forcePushDisabled {
|
||||
return self.c.ErrorMsg(self.c.Tr.ForcePushDisabled)
|
||||
@ -214,7 +215,7 @@ func (self *SyncController) requestToForcePush(opts pushOpts) error {
|
||||
Prompt: self.forcePushPrompt(),
|
||||
HandleConfirm: func() error {
|
||||
opts.force = true
|
||||
return self.pushAux(opts)
|
||||
return self.pushAux(currentBranch, opts)
|
||||
},
|
||||
})
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ import (
|
||||
"github.com/jesseduffield/lazygit/pkg/config"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/presentation/icons"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/style"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||
"github.com/jesseduffield/lazygit/pkg/i18n"
|
||||
"github.com/jesseduffield/lazygit/pkg/theme"
|
||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||
@ -19,6 +20,7 @@ var branchPrefixColorCache = make(map[string]style.TextStyle)
|
||||
|
||||
func GetBranchListDisplayStrings(
|
||||
branches []*models.Branch,
|
||||
getItemOperation func(item types.HasUrn) types.ItemOperation,
|
||||
fullDescription bool,
|
||||
diffName string,
|
||||
tr *i18n.TranslationSet,
|
||||
@ -27,13 +29,14 @@ func GetBranchListDisplayStrings(
|
||||
) [][]string {
|
||||
return lo.Map(branches, func(branch *models.Branch, _ int) []string {
|
||||
diffed := branch.Name == diffName
|
||||
return getBranchDisplayStrings(branch, fullDescription, diffed, tr, userConfig, worktrees)
|
||||
return getBranchDisplayStrings(branch, getItemOperation(branch), fullDescription, diffed, tr, userConfig, worktrees)
|
||||
})
|
||||
}
|
||||
|
||||
// getBranchDisplayStrings returns the display string of branch
|
||||
func getBranchDisplayStrings(
|
||||
b *models.Branch,
|
||||
itemOperation types.ItemOperation,
|
||||
fullDescription bool,
|
||||
diffed bool,
|
||||
tr *i18n.TranslationSet,
|
||||
@ -51,7 +54,7 @@ func getBranchDisplayStrings(
|
||||
}
|
||||
|
||||
coloredName := nameTextStyle.Sprint(displayName)
|
||||
branchStatus := utils.WithPadding(ColoredBranchStatus(b, tr), 2, utils.AlignLeft)
|
||||
branchStatus := utils.WithPadding(ColoredBranchStatus(b, itemOperation, tr), 2, utils.AlignLeft)
|
||||
if git_commands.CheckedOutByOtherWorktree(b, worktrees) {
|
||||
worktreeIcon := lo.Ternary(icons.IsIconEnabled(), icons.LINKED_WORKTREE_ICON, fmt.Sprintf("(%s)", tr.LcWorktree))
|
||||
coloredName = fmt.Sprintf("%s %s", coloredName, style.FgDefault.Sprint(worktreeIcon))
|
||||
@ -109,9 +112,11 @@ func GetBranchTextStyle(name string) style.TextStyle {
|
||||
}
|
||||
}
|
||||
|
||||
func ColoredBranchStatus(branch *models.Branch, tr *i18n.TranslationSet) string {
|
||||
func ColoredBranchStatus(branch *models.Branch, itemOperation types.ItemOperation, tr *i18n.TranslationSet) string {
|
||||
colour := style.FgYellow
|
||||
if branch.UpstreamGone {
|
||||
if itemOperation != types.ItemOperationNone {
|
||||
colour = style.FgCyan
|
||||
} else if branch.UpstreamGone {
|
||||
colour = style.FgRed
|
||||
} else if branch.MatchesUpstream() {
|
||||
colour = style.FgGreen
|
||||
@ -119,10 +124,15 @@ func ColoredBranchStatus(branch *models.Branch, tr *i18n.TranslationSet) string
|
||||
colour = style.FgMagenta
|
||||
}
|
||||
|
||||
return colour.Sprint(BranchStatus(branch, tr))
|
||||
return colour.Sprint(BranchStatus(branch, itemOperation, tr))
|
||||
}
|
||||
|
||||
func BranchStatus(branch *models.Branch, tr *i18n.TranslationSet) string {
|
||||
func BranchStatus(branch *models.Branch, itemOperation types.ItemOperation, tr *i18n.TranslationSet) string {
|
||||
itemOperationStr := itemOperationToString(itemOperation, tr)
|
||||
if itemOperationStr != "" {
|
||||
return itemOperationStr + " " + utils.Loader()
|
||||
}
|
||||
|
||||
if !branch.IsTrackingRemote() {
|
||||
return ""
|
||||
}
|
||||
|
23
pkg/gui/presentation/item_operations.go
Normal file
23
pkg/gui/presentation/item_operations.go
Normal file
@ -0,0 +1,23 @@
|
||||
package presentation
|
||||
|
||||
import (
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||
"github.com/jesseduffield/lazygit/pkg/i18n"
|
||||
)
|
||||
|
||||
func itemOperationToString(itemOperation types.ItemOperation, tr *i18n.TranslationSet) string {
|
||||
switch itemOperation {
|
||||
case types.ItemOperationNone:
|
||||
return ""
|
||||
case types.ItemOperationPushing:
|
||||
return tr.PushingStatus
|
||||
case types.ItemOperationPulling:
|
||||
return tr.PullingStatus
|
||||
case types.ItemOperationFastForwarding:
|
||||
return tr.FastForwarding
|
||||
case types.ItemOperationDeleting:
|
||||
return tr.DeletingStatus
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
@ -7,14 +7,15 @@ import (
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/types/enums"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/presentation/icons"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/style"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||
"github.com/jesseduffield/lazygit/pkg/i18n"
|
||||
)
|
||||
|
||||
func FormatStatus(repoName string, currentBranch *models.Branch, linkedWorktreeName string, workingTreeState enums.RebaseMode, tr *i18n.TranslationSet) string {
|
||||
func FormatStatus(repoName string, currentBranch *models.Branch, itemOperation types.ItemOperation, linkedWorktreeName string, workingTreeState enums.RebaseMode, tr *i18n.TranslationSet) string {
|
||||
status := ""
|
||||
|
||||
if currentBranch.IsRealBranch() {
|
||||
status += ColoredBranchStatus(currentBranch, tr) + " "
|
||||
status += ColoredBranchStatus(currentBranch, itemOperation, tr) + " "
|
||||
}
|
||||
|
||||
if workingTreeState != enums.REBASE_MODE_NONE {
|
||||
|
@ -169,7 +169,7 @@ func chineseTranslationSet() TranslationSet {
|
||||
ToggleStagingPanel: `切换到其他面板`,
|
||||
ReturnToFilesPanel: `返回文件面板`,
|
||||
FastForward: `从上游快进此分支`,
|
||||
FastForwarding: "抓取并快进 {{.branch}} ...",
|
||||
FastForwarding: "抓取并快进",
|
||||
FoundConflictsTitle: "自动合并失败",
|
||||
ViewMergeRebaseOptions: "查看 合并/变基 选项",
|
||||
NotMergingOrRebasing: "您目前既不进行变基也不进行合并",
|
||||
|
@ -134,7 +134,7 @@ func dutchTranslationSet() TranslationSet {
|
||||
ToggleStagingPanel: `Ga naar een ander paneel`,
|
||||
ReturnToFilesPanel: `Ga terug naar het bestanden paneel`,
|
||||
FastForward: `Fast-forward deze branch vanaf zijn upstream`,
|
||||
FastForwarding: "Fast-forwarding {{.branch}} ...",
|
||||
FastForwarding: "Fast-forwarding",
|
||||
FoundConflictsTitle: "Conflicten!",
|
||||
ViewMergeRebaseOptions: "Bekijk merge/rebase opties",
|
||||
NotMergingOrRebasing: "Je bent momenteel niet aan het rebasen of mergen",
|
||||
|
@ -980,7 +980,7 @@ func EnglishTranslationSet() TranslationSet {
|
||||
ToggleStagingPanel: `Switch to other panel (staged/unstaged changes)`,
|
||||
ReturnToFilesPanel: `Return to files panel`,
|
||||
FastForward: `Fast-forward this branch from its upstream`,
|
||||
FastForwarding: "Fast-forwarding {{.branch}}",
|
||||
FastForwarding: "Fast-forwarding",
|
||||
FoundConflictsTitle: "Conflicts!",
|
||||
ViewConflictsMenuItem: "View conflicts",
|
||||
AbortMenuItem: "Abort the %s",
|
||||
|
@ -170,7 +170,7 @@ func koreanTranslationSet() TranslationSet {
|
||||
ToggleStagingPanel: `패널 전환`,
|
||||
ReturnToFilesPanel: `파일 목록으로 돌아가기`,
|
||||
FastForward: `Fast-forward this branch from its upstream`,
|
||||
FastForwarding: "Fast-forwarding {{.branch}} ...",
|
||||
FastForwarding: "Fast-forwarding",
|
||||
FoundConflictsTitle: "Auto-merge failed",
|
||||
ViewMergeRebaseOptions: "View merge/rebase options",
|
||||
NotMergingOrRebasing: "You are currently neither rebasing nor merging",
|
||||
|
@ -201,7 +201,7 @@ func RussianTranslationSet() TranslationSet {
|
||||
ToggleStagingPanel: `Переключиться на другую панель (проиндексированные/непроиндексированные изменения)`,
|
||||
ReturnToFilesPanel: `Вернуться к панели файлов`,
|
||||
FastForward: `Перемотать эту ветку вперёд из её upstream-ветки`,
|
||||
FastForwarding: "Получить изменения и перемотать вперёд {{.branch}} ...",
|
||||
FastForwarding: "Получить изменения и перемотать вперёд",
|
||||
FoundConflictsTitle: "Конфликты!",
|
||||
ViewConflictsMenuItem: "Просмотр конфликтов",
|
||||
AbortMenuItem: "Прервать %s",
|
||||
|
@ -234,7 +234,7 @@ func traditionalChineseTranslationSet() TranslationSet {
|
||||
ToggleStagingPanel: `切換至另一個面板 (已預存/未預存更改)`,
|
||||
ReturnToFilesPanel: `返回檔案面板`,
|
||||
FastForward: `從上游快進此分支`,
|
||||
FastForwarding: "{{.branch}} 的擷取和快進中...",
|
||||
FastForwarding: "的擷取和快進中",
|
||||
FoundConflictsTitle: "自動合併失敗",
|
||||
ViewMergeRebaseOptions: "查看合併/變基選項",
|
||||
NotMergingOrRebasing: "你當前既不在變基也不在合併中",
|
||||
|
Loading…
Reference in New Issue
Block a user