1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-06-25 00:46:54 +02:00

Add "Show divergence from upstream" entry to Upstream menu in branches panel

This commit is contained in:
Stefan Haller
2023-08-05 12:06:37 +02:00
parent e8fac6ca73
commit 572d1b5920
8 changed files with 116 additions and 17 deletions

View File

@ -1,5 +1,7 @@
package models package models
import "fmt"
// Branch : A git branch // Branch : A git branch
// duplicating this for now // duplicating this for now
type Branch struct { type Branch struct {
@ -43,6 +45,22 @@ func (b *Branch) ParentRefName() string {
return b.RefName() + "^" return b.RefName() + "^"
} }
func (b *Branch) FullUpstreamRefName() string {
if b.UpstreamRemote == "" || b.UpstreamBranch == "" {
return ""
}
return fmt.Sprintf("refs/remotes/%s/%s", b.UpstreamRemote, b.UpstreamBranch)
}
func (b *Branch) ShortUpstreamRefName() string {
if b.UpstreamRemote == "" || b.UpstreamBranch == "" {
return ""
}
return fmt.Sprintf("%s/%s", b.UpstreamRemote, b.UpstreamBranch)
}
func (b *Branch) ID() string { func (b *Branch) ID() string {
return b.RefName() return b.RefName()
} }

View File

@ -1,12 +1,14 @@
package context package context
import ( import (
"fmt"
"time" "time"
"github.com/jesseduffield/lazygit/pkg/commands/git_commands" "github.com/jesseduffield/lazygit/pkg/commands/git_commands"
"github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/gui/presentation" "github.com/jesseduffield/lazygit/pkg/gui/presentation"
"github.com/jesseduffield/lazygit/pkg/gui/types" "github.com/jesseduffield/lazygit/pkg/gui/types"
"github.com/samber/lo"
) )
type SubCommitsContext struct { type SubCommitsContext struct {
@ -71,12 +73,41 @@ func NewSubCommitsContext(
selectedCommitSha, selectedCommitSha,
startIdx, startIdx,
endIdx, endIdx,
shouldShowGraph(c), // Don't show the graph in the left/right view; we'd like to, but
// it's too complicated:
shouldShowGraph(c) && viewModel.GetRefToShowDivergenceFrom() == "",
git_commands.NewNullBisectInfo(), git_commands.NewNullBisectInfo(),
false, false,
) )
} }
getNonModelItems := func() []*NonModelItem {
result := []*NonModelItem{}
if viewModel.GetRefToShowDivergenceFrom() != "" {
_, upstreamIdx, found := lo.FindIndexOf(
c.Model().SubCommits, func(c *models.Commit) bool { return c.Divergence == models.DivergenceRight })
if !found {
upstreamIdx = 0
}
result = append(result, &NonModelItem{
Index: upstreamIdx,
Content: fmt.Sprintf("--- %s ---", c.Tr.DivergenceSectionHeaderRemote),
})
_, localIdx, found := lo.FindIndexOf(
c.Model().SubCommits, func(c *models.Commit) bool { return c.Divergence == models.DivergenceLeft })
if !found {
localIdx = len(c.Model().SubCommits)
}
result = append(result, &NonModelItem{
Index: localIdx,
Content: fmt.Sprintf("--- %s ---", c.Tr.DivergenceSectionHeaderLocal),
})
}
return result
}
ctx := &SubCommitsContext{ ctx := &SubCommitsContext{
c: c, c: c,
SubCommitsViewModel: viewModel, SubCommitsViewModel: viewModel,
@ -94,6 +125,7 @@ func NewSubCommitsContext(
ListRenderer: ListRenderer{ ListRenderer: ListRenderer{
list: viewModel, list: viewModel,
getDisplayStrings: getDisplayStrings, getDisplayStrings: getDisplayStrings,
getNonModelItems: getNonModelItems,
}, },
c: c, c: c,
refreshViewportOnChange: true, refreshViewportOnChange: true,
@ -111,6 +143,7 @@ func NewSubCommitsContext(
type SubCommitsViewModel struct { type SubCommitsViewModel struct {
// name of the ref that the sub-commits are shown for // name of the ref that the sub-commits are shown for
ref types.Ref ref types.Ref
refToShowDivergenceFrom string
*ListViewModel[*models.Commit] *ListViewModel[*models.Commit]
limitCommits bool limitCommits bool
@ -125,6 +158,14 @@ func (self *SubCommitsViewModel) GetRef() types.Ref {
return self.ref return self.ref
} }
func (self *SubCommitsViewModel) SetRefToShowDivergenceFrom(ref string) {
self.refToShowDivergenceFrom = ref
}
func (self *SubCommitsViewModel) GetRefToShowDivergenceFrom() string {
return self.refToShowDivergenceFrom
}
func (self *SubCommitsViewModel) SetShowBranchHeads(value bool) { func (self *SubCommitsViewModel) SetShowBranchHeads(value bool) {
self.showBranchHeads = value self.showBranchHeads = value
} }

View File

@ -9,6 +9,7 @@ import (
"github.com/jesseduffield/lazygit/pkg/commands/git_commands" "github.com/jesseduffield/lazygit/pkg/commands/git_commands"
"github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/gui/context" "github.com/jesseduffield/lazygit/pkg/gui/context"
"github.com/jesseduffield/lazygit/pkg/gui/controllers/helpers"
"github.com/jesseduffield/lazygit/pkg/gui/types" "github.com/jesseduffield/lazygit/pkg/gui/types"
"github.com/jesseduffield/lazygit/pkg/utils" "github.com/jesseduffield/lazygit/pkg/utils"
) )
@ -141,6 +142,27 @@ func (self *BranchesController) setUpstream(selectedBranch *models.Branch) error
return self.c.Menu(types.CreateMenuOptions{ return self.c.Menu(types.CreateMenuOptions{
Title: self.c.Tr.Actions.SetUnsetUpstream, Title: self.c.Tr.Actions.SetUnsetUpstream,
Items: []*types.MenuItem{ Items: []*types.MenuItem{
{
LabelColumns: []string{self.c.Tr.ViewDivergenceFromUpstream},
OnPress: func() error {
branch := self.context().GetSelected()
if branch == nil {
return nil
}
if !branch.RemoteBranchStoredLocally() {
return self.c.ErrorMsg(self.c.Tr.DivergenceNoUpstream)
}
return self.c.Helpers().SubCommits.ViewSubCommits(helpers.ViewSubCommitsOpts{
Ref: branch,
TitleRef: fmt.Sprintf("%s <-> %s", branch.RefName(), branch.ShortUpstreamRefName()),
RefToShowDivergenceFrom: branch.FullUpstreamRefName(),
Context: self.context(),
ShowBranchHeads: false,
})
},
Key: 'v',
},
{ {
LabelColumns: []string{self.c.Tr.UnsetUpstream}, LabelColumns: []string{self.c.Tr.UnsetUpstream},
OnPress: func() error { OnPress: func() error {

View File

@ -338,6 +338,7 @@ func (self *RefreshHelper) refreshSubCommitsWithLimit() error {
FilterPath: self.c.Modes().Filtering.GetPath(), FilterPath: self.c.Modes().Filtering.GetPath(),
IncludeRebaseCommits: false, IncludeRebaseCommits: false,
RefName: self.c.Contexts().SubCommits.GetRef().FullRefName(), RefName: self.c.Contexts().SubCommits.GetRef().FullRefName(),
RefToShowDivergenceFrom: self.c.Contexts().SubCommits.GetRefToShowDivergenceFrom(),
RefForPushedStatus: self.c.Contexts().SubCommits.GetRef().FullRefName(), RefForPushedStatus: self.c.Contexts().SubCommits.GetRef().FullRefName(),
}, },
) )

View File

@ -28,6 +28,8 @@ func NewSubCommitsHelper(
type ViewSubCommitsOpts struct { type ViewSubCommitsOpts struct {
Ref types.Ref Ref types.Ref
RefToShowDivergenceFrom string
TitleRef string
Context types.Context Context types.Context
ShowBranchHeads bool ShowBranchHeads bool
} }
@ -40,6 +42,7 @@ func (self *SubCommitsHelper) ViewSubCommits(opts ViewSubCommitsOpts) error {
IncludeRebaseCommits: false, IncludeRebaseCommits: false,
RefName: opts.Ref.FullRefName(), RefName: opts.Ref.FullRefName(),
RefForPushedStatus: opts.Ref.FullRefName(), RefForPushedStatus: opts.Ref.FullRefName(),
RefToShowDivergenceFrom: opts.RefToShowDivergenceFrom,
}, },
) )
if err != nil { if err != nil {
@ -53,8 +56,9 @@ func (self *SubCommitsHelper) ViewSubCommits(opts ViewSubCommitsOpts) error {
subCommitsContext.SetSelectedLineIdx(0) subCommitsContext.SetSelectedLineIdx(0)
subCommitsContext.SetParentContext(opts.Context) subCommitsContext.SetParentContext(opts.Context)
subCommitsContext.SetWindowName(opts.Context.GetWindowName()) subCommitsContext.SetWindowName(opts.Context.GetWindowName())
subCommitsContext.SetTitleRef(utils.TruncateWithEllipsis(opts.Ref.RefName(), 50)) subCommitsContext.SetTitleRef(utils.TruncateWithEllipsis(opts.TitleRef, 50))
subCommitsContext.SetRef(opts.Ref) subCommitsContext.SetRef(opts.Ref)
subCommitsContext.SetRefToShowDivergenceFrom(opts.RefToShowDivergenceFrom)
subCommitsContext.SetLimitCommits(true) subCommitsContext.SetLimitCommits(true)
subCommitsContext.SetShowBranchHeads(opts.ShowBranchHeads) subCommitsContext.SetShowBranchHeads(opts.ShowBranchHeads)
subCommitsContext.ClearSearchString() subCommitsContext.ClearSearchString()

View File

@ -54,6 +54,7 @@ func (self *SwitchToSubCommitsController) viewCommits() error {
return self.c.Helpers().SubCommits.ViewSubCommits(helpers.ViewSubCommitsOpts{ return self.c.Helpers().SubCommits.ViewSubCommits(helpers.ViewSubCommitsOpts{
Ref: ref, Ref: ref,
TitleRef: ref.RefName(),
Context: self.context, Context: self.context,
ShowBranchHeads: self.context.ShowBranchHeadsInSubCommits(), ShowBranchHeads: self.context.ShowBranchHeadsInSubCommits(),
}) })

View File

@ -359,7 +359,9 @@ func displayCommit(
} }
cols := make([]string, 0, 7) cols := make([]string, 0, 7)
if icons.IsIconEnabled() { if commit.Divergence != models.DivergenceNone {
cols = append(cols, shaColor.Sprint(lo.Ternary(commit.Divergence == models.DivergenceLeft, "↑", "↓")))
} else if icons.IsIconEnabled() {
cols = append(cols, shaColor.Sprint(icons.IconForCommit(commit))) cols = append(cols, shaColor.Sprint(icons.IconForCommit(commit)))
} }
cols = append(cols, shaColor.Sprint(commit.ShortSha())) cols = append(cols, shaColor.Sprint(commit.ShortSha()))
@ -430,6 +432,8 @@ func getShaColor(
shaColor = theme.DiffTerminalColor shaColor = theme.DiffTerminalColor
} else if cherryPickedCommitShaSet.Includes(commit.Sha) { } else if cherryPickedCommitShaSet.Includes(commit.Sha) {
shaColor = theme.CherryPickedCommitTextStyle shaColor = theme.CherryPickedCommitTextStyle
} else if commit.Divergence == models.DivergenceRight && commit.Status != models.StatusMerged {
shaColor = style.FgBlue
} }
return shaColor return shaColor

View File

@ -348,6 +348,10 @@ type TranslationSet struct {
SetAsUpstream string SetAsUpstream string
SetUpstream string SetUpstream string
UnsetUpstream string UnsetUpstream string
ViewDivergenceFromUpstream string
DivergenceNoUpstream string
DivergenceSectionHeaderLocal string
DivergenceSectionHeaderRemote string
SetUpstreamTitle string SetUpstreamTitle string
SetUpstreamMessage string SetUpstreamMessage string
EditRemote string EditRemote string
@ -1128,6 +1132,10 @@ func EnglishTranslationSet() TranslationSet {
SetAsUpstream: "Set as upstream of checked-out branch", SetAsUpstream: "Set as upstream of checked-out branch",
SetUpstream: "Set upstream of selected branch", SetUpstream: "Set upstream of selected branch",
UnsetUpstream: "Unset upstream of selected branch", UnsetUpstream: "Unset upstream of selected branch",
ViewDivergenceFromUpstream: "View divergence from upstream",
DivergenceNoUpstream: "Cannot show divergence of a branch that has no (locally tracked) upstream",
DivergenceSectionHeaderLocal: "Local",
DivergenceSectionHeaderRemote: "Remote",
SetUpstreamTitle: "Set upstream branch", SetUpstreamTitle: "Set upstream branch",
SetUpstreamMessage: "Are you sure you want to set the upstream branch of '{{.checkedOut}}' to '{{.selected}}'", SetUpstreamMessage: "Are you sure you want to set the upstream branch of '{{.checkedOut}}' to '{{.selected}}'",
EditRemote: "Edit remote", EditRemote: "Edit remote",