Skip to content

Commit d890c68

Browse files
committed
Add ahead/behind information for @{push}
In a triangular workflow the branch that you're pulling from is not the same as the one that you are pushing to. For example, some people find it useful to set the upstream branch to origin/master so that pulling effectively rebases onto master, and set the push.default git config to "current" so that "feature" pushes to origin/feature. Another example is a fork-based workflow where "feature" has upstream set to upstream/main, and the repo has remote.pushDefault set to "origin", so pushing on "feature" pushes to origin/feature. This commit adds new fields to models.Branch that store the ahead/behind information against the push branch; for the "normal" workflow where you pull and push from/to the upstream branch, AheadForPush/BehindForPush will be the same as AheadForPull/BehindForPull.
1 parent 0aba686 commit d890c68

File tree

6 files changed

+48
-15
lines changed

6 files changed

+48
-15
lines changed

pkg/commands/git.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ func NewGitCommandAux(
134134
worktreeCommands := git_commands.NewWorktreeCommands(gitCommon)
135135
blameCommands := git_commands.NewBlameCommands(gitCommon)
136136

137-
branchLoader := git_commands.NewBranchLoader(cmn, cmd, branchCommands.CurrentBranchInfo, configCommands)
137+
branchLoader := git_commands.NewBranchLoader(cmn, gitCommon, cmd, branchCommands.CurrentBranchInfo, configCommands)
138138
commitFileLoader := git_commands.NewCommitFileLoader(cmn, cmd)
139139
commitLoader := git_commands.NewCommitLoader(cmn, cmd, statusCommands.RebaseMode, gitCommon)
140140
reflogCommitLoader := git_commands.NewReflogCommitLoader(cmn, cmd)

pkg/commands/git_commands/branch_loader.go

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,19 +40,22 @@ type BranchInfo struct {
4040
// BranchLoader returns a list of Branch objects for the current repo
4141
type BranchLoader struct {
4242
*common.Common
43+
*GitCommon
4344
cmd oscommands.ICmdObjBuilder
4445
getCurrentBranchInfo func() (BranchInfo, error)
4546
config BranchLoaderConfigCommands
4647
}
4748

4849
func NewBranchLoader(
4950
cmn *common.Common,
51+
gitCommon *GitCommon,
5052
cmd oscommands.ICmdObjBuilder,
5153
getCurrentBranchInfo func() (BranchInfo, error),
5254
config BranchLoaderConfigCommands,
5355
) *BranchLoader {
5456
return &BranchLoader{
5557
Common: cmn,
58+
GitCommon: gitCommon,
5659
cmd: cmd,
5760
getCurrentBranchInfo: getCurrentBranchInfo,
5861
config: config,
@@ -61,7 +64,7 @@ func NewBranchLoader(
6164

6265
// Load the list of branches for the current repo
6366
func (self *BranchLoader) Load(reflogCommits []*models.Commit) ([]*models.Branch, error) {
64-
branches := self.obtainBranches()
67+
branches := self.obtainBranches(self.version.IsAtLeast(2, 22, 0))
6568

6669
if self.AppState.LocalBranchSortOrder == "recency" {
6770
reflogBranches := self.obtainReflogBranches(reflogCommits)
@@ -124,7 +127,7 @@ func (self *BranchLoader) Load(reflogCommits []*models.Commit) ([]*models.Branch
124127
return branches, nil
125128
}
126129

127-
func (self *BranchLoader) obtainBranches() []*models.Branch {
130+
func (self *BranchLoader) obtainBranches(canUsePushTrack bool) []*models.Branch {
128131
output, err := self.getRawBranches()
129132
if err != nil {
130133
panic(err)
@@ -147,7 +150,7 @@ func (self *BranchLoader) obtainBranches() []*models.Branch {
147150
}
148151

149152
storeCommitDateAsRecency := self.AppState.LocalBranchSortOrder != "recency"
150-
return obtainBranch(split, storeCommitDateAsRecency), true
153+
return obtainBranch(split, storeCommitDateAsRecency, canUsePushTrack), true
151154
})
152155
}
153156

@@ -183,23 +186,31 @@ var branchFields = []string{
183186
"refname:short",
184187
"upstream:short",
185188
"upstream:track",
189+
"push:track",
186190
"subject",
187191
"objectname",
188192
"committerdate:unix",
189193
}
190194

191195
// Obtain branch information from parsed line output of getRawBranches()
192-
func obtainBranch(split []string, storeCommitDateAsRecency bool) *models.Branch {
196+
func obtainBranch(split []string, storeCommitDateAsRecency bool, canUsePushTrack bool) *models.Branch {
193197
headMarker := split[0]
194198
fullName := split[1]
195199
upstreamName := split[2]
196200
track := split[3]
197-
subject := split[4]
198-
commitHash := split[5]
199-
commitDate := split[6]
201+
pushTrack := split[4]
202+
subject := split[5]
203+
commitHash := split[6]
204+
commitDate := split[7]
200205

201206
name := strings.TrimPrefix(fullName, "heads/")
202207
aheadForPull, behindForPull, gone := parseUpstreamInfo(upstreamName, track)
208+
var aheadForPush, behindForPush string
209+
if canUsePushTrack {
210+
aheadForPush, behindForPush, _ = parseUpstreamInfo(upstreamName, pushTrack)
211+
} else {
212+
aheadForPush, behindForPush = aheadForPull, behindForPull
213+
}
203214

204215
recency := ""
205216
if storeCommitDateAsRecency {
@@ -213,6 +224,8 @@ func obtainBranch(split []string, storeCommitDateAsRecency bool) *models.Branch
213224
Recency: recency,
214225
AheadForPull: aheadForPull,
215226
BehindForPull: behindForPull,
227+
AheadForPush: aheadForPush,
228+
BehindForPush: behindForPush,
216229
UpstreamGone: gone,
217230
Head: headMarker == "*",
218231
Subject: subject,

pkg/commands/git_commands/branch_loader_test.go

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,79 +25,91 @@ func TestObtainBranch(t *testing.T) {
2525
scenarios := []scenario{
2626
{
2727
testName: "TrimHeads",
28-
input: []string{"", "heads/a_branch", "", "", "subject", "123", timeStamp},
28+
input: []string{"", "heads/a_branch", "", "", "", "subject", "123", timeStamp},
2929
storeCommitDateAsRecency: false,
3030
expectedBranch: &models.Branch{
3131
Name: "a_branch",
3232
AheadForPull: "?",
3333
BehindForPull: "?",
34+
AheadForPush: "?",
35+
BehindForPush: "?",
3436
Head: false,
3537
Subject: "subject",
3638
CommitHash: "123",
3739
},
3840
},
3941
{
4042
testName: "NoUpstream",
41-
input: []string{"", "a_branch", "", "", "subject", "123", timeStamp},
43+
input: []string{"", "a_branch", "", "", "", "subject", "123", timeStamp},
4244
storeCommitDateAsRecency: false,
4345
expectedBranch: &models.Branch{
4446
Name: "a_branch",
4547
AheadForPull: "?",
4648
BehindForPull: "?",
49+
AheadForPush: "?",
50+
BehindForPush: "?",
4751
Head: false,
4852
Subject: "subject",
4953
CommitHash: "123",
5054
},
5155
},
5256
{
5357
testName: "IsHead",
54-
input: []string{"*", "a_branch", "", "", "subject", "123", timeStamp},
58+
input: []string{"*", "a_branch", "", "", "", "subject", "123", timeStamp},
5559
storeCommitDateAsRecency: false,
5660
expectedBranch: &models.Branch{
5761
Name: "a_branch",
5862
AheadForPull: "?",
5963
BehindForPull: "?",
64+
AheadForPush: "?",
65+
BehindForPush: "?",
6066
Head: true,
6167
Subject: "subject",
6268
CommitHash: "123",
6369
},
6470
},
6571
{
6672
testName: "IsBehindAndAhead",
67-
input: []string{"", "a_branch", "a_remote/a_branch", "[behind 2, ahead 3]", "subject", "123", timeStamp},
73+
input: []string{"", "a_branch", "a_remote/a_branch", "[behind 2, ahead 3]", "[behind 2, ahead 3]", "subject", "123", timeStamp},
6874
storeCommitDateAsRecency: false,
6975
expectedBranch: &models.Branch{
7076
Name: "a_branch",
7177
AheadForPull: "3",
7278
BehindForPull: "2",
79+
AheadForPush: "3",
80+
BehindForPush: "2",
7381
Head: false,
7482
Subject: "subject",
7583
CommitHash: "123",
7684
},
7785
},
7886
{
7987
testName: "RemoteBranchIsGone",
80-
input: []string{"", "a_branch", "a_remote/a_branch", "[gone]", "subject", "123", timeStamp},
88+
input: []string{"", "a_branch", "a_remote/a_branch", "[gone]", "[gone]", "subject", "123", timeStamp},
8189
storeCommitDateAsRecency: false,
8290
expectedBranch: &models.Branch{
8391
Name: "a_branch",
8492
UpstreamGone: true,
8593
AheadForPull: "?",
8694
BehindForPull: "?",
95+
AheadForPush: "?",
96+
BehindForPush: "?",
8797
Head: false,
8898
Subject: "subject",
8999
CommitHash: "123",
90100
},
91101
},
92102
{
93103
testName: "WithCommitDateAsRecency",
94-
input: []string{"", "a_branch", "", "", "subject", "123", timeStamp},
104+
input: []string{"", "a_branch", "", "", "", "subject", "123", timeStamp},
95105
storeCommitDateAsRecency: true,
96106
expectedBranch: &models.Branch{
97107
Name: "a_branch",
98108
Recency: "2h",
99109
AheadForPull: "?",
100110
BehindForPull: "?",
111+
AheadForPush: "?",
112+
BehindForPush: "?",
101113
Head: false,
102114
Subject: "subject",
103115
CommitHash: "123",
@@ -107,7 +119,7 @@ func TestObtainBranch(t *testing.T) {
107119

108120
for _, s := range scenarios {
109121
t.Run(s.testName, func(t *testing.T) {
110-
branch := obtainBranch(s.input, s.storeCommitDateAsRecency)
122+
branch := obtainBranch(s.input, s.storeCommitDateAsRecency, true)
111123
assert.EqualValues(t, s.expectedBranch, branch)
112124
})
113125
}

pkg/commands/models/branch.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ type Branch struct {
1414
AheadForPull string
1515
// how many commits behind we are from the remote branch (how many commits we can pull)
1616
BehindForPull string
17+
// how many commits ahead we are from the branch we're pushing to (which might not be the same as our upstream branch in a triangular workflow)
18+
AheadForPush string
19+
// how many commits behind we are from the branch we're pushing to (which might not be the same as our upstream branch in a triangular workflow)
20+
BehindForPush string
1721
// whether the remote branch is 'gone' i.e. we're tracking a remote branch that has been deleted
1822
UpstreamGone bool
1923
// whether this is the current branch. Exactly one branch should have this be true

pkg/gui/services/custom_commands/models.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ type Branch struct {
5151
Pullables string // deprecated: use BehindForPull
5252
AheadForPull string
5353
BehindForPull string
54+
AheadForPush string
55+
BehindForPush string
5456
UpstreamGone bool
5557
Head bool
5658
DetachedHead bool

pkg/gui/services/custom_commands/session_state_loader.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ func branchShimFromModelBranch(branch *models.Branch) *Branch {
7575
Pullables: branch.BehindForPull,
7676
AheadForPull: branch.AheadForPull,
7777
BehindForPull: branch.BehindForPull,
78+
AheadForPush: branch.AheadForPush,
79+
BehindForPush: branch.BehindForPush,
7880
UpstreamGone: branch.UpstreamGone,
7981
Head: branch.Head,
8082
DetachedHead: branch.DetachedHead,

0 commit comments

Comments
 (0)