Skip to content

Commit 55a8e12

Browse files
saitholafriks
authored andcommitted
Number of commits ahead/behind in branch overview (#6695)
* Call Git API to determine divergence of a branch and its base branch Signed-off-by: Mario Lubenka <[email protected]> * Show commit divergance in branch list Signed-off-by: Mario Lubenka <[email protected]> * Adds missing comment Signed-off-by: Mario Lubenka <[email protected]> * Adds test for diverging commits Signed-off-by: Mario Lubenka <[email protected]> * Try comparing commits instead of branches Signed-off-by: Mario Lubenka <[email protected]> * Removes test as CI can't run it Signed-off-by: Mario Lubenka <[email protected]> * Adjusts signature of percentage function to allow providing multiple integers as numerator Signed-off-by: Mario Lubenka <[email protected]> * Moves CountDivergingCommits function into repofiles module Signed-off-by: Mario Lubenka <[email protected]>
1 parent c1da790 commit 55a8e12

File tree

7 files changed

+132
-6
lines changed

7 files changed

+132
-6
lines changed

modules/git/repo.go

+39
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,11 @@ import (
99
"bytes"
1010
"container/list"
1111
"errors"
12+
"fmt"
1213
"os"
1314
"path"
1415
"path/filepath"
16+
"strconv"
1517
"strings"
1618
"time"
1719

@@ -306,3 +308,40 @@ func GetLatestCommitTime(repoPath string) (time.Time, error) {
306308
commitTime := strings.TrimSpace(stdout)
307309
return time.Parse(GitTimeLayout, commitTime)
308310
}
311+
312+
// DivergeObject represents commit count diverging commits
313+
type DivergeObject struct {
314+
Ahead int
315+
Behind int
316+
}
317+
318+
func checkDivergence(repoPath string, baseBranch string, targetBranch string) (int, error) {
319+
branches := fmt.Sprintf("%s..%s", baseBranch, targetBranch)
320+
cmd := NewCommand("rev-list", "--count", branches)
321+
stdout, err := cmd.RunInDir(repoPath)
322+
if err != nil {
323+
return -1, err
324+
}
325+
outInteger, errInteger := strconv.Atoi(strings.Trim(stdout, "\n"))
326+
if errInteger != nil {
327+
return -1, errInteger
328+
}
329+
return outInteger, nil
330+
}
331+
332+
// GetDivergingCommits returns the number of commits a targetBranch is ahead or behind a baseBranch
333+
func GetDivergingCommits(repoPath string, baseBranch string, targetBranch string) (DivergeObject, error) {
334+
// $(git rev-list --count master..feature) commits ahead of master
335+
ahead, errorAhead := checkDivergence(repoPath, baseBranch, targetBranch)
336+
if errorAhead != nil {
337+
return DivergeObject{}, errorAhead
338+
}
339+
340+
// $(git rev-list --count feature..master) commits behind master
341+
behind, errorBehind := checkDivergence(repoPath, targetBranch, baseBranch)
342+
if errorBehind != nil {
343+
return DivergeObject{}, errorBehind
344+
}
345+
346+
return DivergeObject{ahead, behind}, nil
347+
}

modules/repofiles/commit.go

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Copyright 2019 The Gitea Authors. All rights reserved.
2+
// Use of this source code is governed by a MIT-style
3+
// license that can be found in the LICENSE file.
4+
5+
package repofiles
6+
7+
import (
8+
"code.gitea.io/gitea/models"
9+
"code.gitea.io/gitea/modules/git"
10+
)
11+
12+
// CountDivergingCommits determines how many commits a branch is ahead or behind the repository's base branch
13+
func CountDivergingCommits(repo *models.Repository, branch string) (*git.DivergeObject, error) {
14+
divergence, err := git.GetDivergingCommits(repo.RepoPath(), repo.DefaultBranch, branch)
15+
if err != nil {
16+
return nil, err
17+
}
18+
return &divergence, nil
19+
}

modules/templates/helper.go

+7
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,13 @@ func NewFuncMap() []template.FuncMap {
223223
}
224224
return dict, nil
225225
},
226+
"percentage": func(n int, values ...int) float32 {
227+
var sum = 0
228+
for i := 0; i < len(values); i++ {
229+
sum += values[i]
230+
}
231+
return float32(n) * 100 / float32(sum)
232+
},
226233
}}
227234
}
228235

public/css/index.css

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

public/less/_repository.less

+36
Original file line numberDiff line numberDiff line change
@@ -963,6 +963,42 @@
963963
margin-top: 1px!important;
964964
}
965965

966+
&.branches {
967+
.commit-divergence {
968+
.bar-group {
969+
position: relative;
970+
float: left;
971+
padding-bottom: 6px;
972+
width: 90px;
973+
974+
&:last-child {
975+
border-left: 1px solid #b4b4b4;
976+
}
977+
}
978+
.count {
979+
margin: 0 3px;
980+
&.count-ahead {
981+
text-align: left;
982+
}
983+
&.count-behind {
984+
text-align: right;
985+
}
986+
}
987+
.bar {
988+
height: 4px;
989+
position: absolute;
990+
background-color: #d4d4d5;
991+
992+
&.bar-behind {
993+
right: 0;
994+
}
995+
&.bar-ahead {
996+
left: 0;
997+
}
998+
}
999+
}
1000+
}
1001+
9661002
&.commits {
9671003
.header {
9681004
.search {

routers/repo/branch.go

+16-4
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"code.gitea.io/gitea/modules/context"
1515
"code.gitea.io/gitea/modules/git"
1616
"code.gitea.io/gitea/modules/log"
17+
"code.gitea.io/gitea/modules/repofiles"
1718
"code.gitea.io/gitea/modules/util"
1819
)
1920

@@ -28,6 +29,8 @@ type Branch struct {
2829
IsProtected bool
2930
IsDeleted bool
3031
DeletedBranch *models.DeletedBranch
32+
CommitsAhead int
33+
CommitsBehind int
3134
}
3235

3336
// Branches render repository branch page
@@ -168,16 +171,25 @@ func loadBranches(ctx *context.Context) []*Branch {
168171
return nil
169172
}
170173

171-
isProtected, err := ctx.Repo.Repository.IsProtectedBranch(rawBranches[i].Name, ctx.User)
174+
branchName := rawBranches[i].Name
175+
isProtected, err := ctx.Repo.Repository.IsProtectedBranch(branchName, ctx.User)
172176
if err != nil {
173177
ctx.ServerError("IsProtectedBranch", err)
174178
return nil
175179
}
176180

181+
divergence, divergenceError := repofiles.CountDivergingCommits(ctx.Repo.Repository, branchName)
182+
if divergenceError != nil {
183+
ctx.ServerError("CountDivergingCommits", divergenceError)
184+
return nil
185+
}
186+
177187
branches[i] = &Branch{
178-
Name: rawBranches[i].Name,
179-
Commit: commit,
180-
IsProtected: isProtected,
188+
Name: branchName,
189+
Commit: commit,
190+
IsProtected: isProtected,
191+
CommitsAhead: divergence.Ahead,
192+
CommitsBehind: divergence.Behind,
181193
}
182194
}
183195

templates/repo/branch/list.tmpl

+14-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@
2626
<table class="ui very basic striped fixed table single line">
2727
<thead>
2828
<tr>
29-
<th class="nine wide">{{.i18n.Tr "repo.branch.name"}}</th>
29+
<th class="seven wide">{{.i18n.Tr "repo.branch.name"}}</th>
30+
<th class="two wide"></th>
3031
{{if and $.IsWriter (not $.IsMirror)}}
3132
<th class="one wide right aligned">{{.i18n.Tr "repo.branch.delete_head"}}</th>
3233
{{end}}
@@ -45,6 +46,18 @@
4546
<p class="time">{{$.i18n.Tr "org.repo_updated"}} {{TimeSince .Commit.Committer.When $.i18n.Lang}}</p>
4647
</td>
4748
{{end}}
49+
<td class="ui">
50+
<div class="commit-divergence">
51+
<div class="bar-group">
52+
<div class="count count-behind">{{.CommitsBehind}}</div>
53+
<div class="bar bar-behind" style="width: {{percentage .CommitsBehind .CommitsBehind .CommitsAhead}}%"></div>
54+
</div>
55+
<div class="bar-group">
56+
<div class="count count-ahead">{{.CommitsAhead}}</div>
57+
<div class="bar bar-ahead" style="width: {{percentage .CommitsAhead .CommitsBehind .CommitsAhead}}%"></div>
58+
</div>
59+
</div>
60+
</td>
4861
{{if and $.IsWriter (not $.IsMirror)}}
4962
<td class="right aligned">
5063
{{if .IsProtected}}

0 commit comments

Comments
 (0)