mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-06-23 00:39:13 +02:00
Add "Show divergence from upstream" entry to Upstream menu in branches panel
This commit is contained in:
@ -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()
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
||||||
|
@ -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(),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
@ -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()
|
||||||
|
@ -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(),
|
||||||
})
|
})
|
||||||
|
@ -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
|
||||||
|
@ -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",
|
||||||
|
Reference in New Issue
Block a user