Skip to content

Commit 36f1fa7

Browse files
hiifongsilverwind
andauthored
Support displaying diff stats in PR tab bar (#25387)
Fix #25326 --------- Co-authored-by: silverwind <[email protected]>
1 parent eab011d commit 36f1fa7

File tree

4 files changed

+94
-5
lines changed

4 files changed

+94
-5
lines changed

routers/web/repo/pull.go

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -356,12 +356,46 @@ func setMergeTarget(ctx *context.Context, pull *issues_model.PullRequest) {
356356
ctx.Data["BaseBranchLink"] = pull.GetBaseBranchLink()
357357
}
358358

359-
// PrepareMergedViewPullInfo show meta information for a merged pull request view page
360-
func PrepareMergedViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *git.CompareInfo {
359+
// GetPullDiffStats get Pull Requests diff stats
360+
func GetPullDiffStats(ctx *context.Context) {
361+
issue := checkPullInfo(ctx)
361362
pull := issue.PullRequest
362363

363-
setMergeTarget(ctx, pull)
364-
ctx.Data["HasMerged"] = true
364+
mergeBaseCommitID := GetMergedBaseCommitID(ctx, issue)
365+
366+
if ctx.Written() {
367+
return
368+
} else if mergeBaseCommitID == "" {
369+
ctx.NotFound("PullFiles", nil)
370+
return
371+
}
372+
373+
headCommitID, err := ctx.Repo.GitRepo.GetRefCommitID(pull.GetGitRefName())
374+
if err != nil {
375+
ctx.ServerError("GetRefCommitID", err)
376+
return
377+
}
378+
379+
diffOptions := &gitdiff.DiffOptions{
380+
BeforeCommitID: mergeBaseCommitID,
381+
AfterCommitID: headCommitID,
382+
MaxLines: setting.Git.MaxGitDiffLines,
383+
MaxLineCharacters: setting.Git.MaxGitDiffLineCharacters,
384+
MaxFiles: setting.Git.MaxGitDiffFiles,
385+
WhitespaceBehavior: gitdiff.GetWhitespaceFlag(ctx.Data["WhitespaceBehavior"].(string)),
386+
}
387+
388+
diff, err := gitdiff.GetPullDiffStats(ctx.Repo.GitRepo, diffOptions)
389+
if err != nil {
390+
ctx.ServerError("GetPullDiffStats", err)
391+
return
392+
}
393+
394+
ctx.Data["Diff"] = diff
395+
}
396+
397+
func GetMergedBaseCommitID(ctx *context.Context, issue *issues_model.Issue) string {
398+
pull := issue.PullRequest
365399

366400
var baseCommit string
367401
// Some migrated PR won't have any Base SHA and lose history, try to get one
@@ -401,6 +435,18 @@ func PrepareMergedViewPullInfo(ctx *context.Context, issue *issues_model.Issue)
401435
baseCommit = pull.MergeBase
402436
}
403437

438+
return baseCommit
439+
}
440+
441+
// PrepareMergedViewPullInfo show meta information for a merged pull request view page
442+
func PrepareMergedViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *git.CompareInfo {
443+
pull := issue.PullRequest
444+
445+
setMergeTarget(ctx, pull)
446+
ctx.Data["HasMerged"] = true
447+
448+
baseCommit := GetMergedBaseCommitID(ctx, issue)
449+
404450
compareInfo, err := ctx.Repo.GitRepo.GetCompareInfo(ctx.Repo.Repository.RepoPath(),
405451
baseCommit, pull.GetGitRefName(), false, false)
406452
if err != nil {

routers/web/web.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1277,9 +1277,10 @@ func registerRoutes(m *web.Route) {
12771277
})
12781278

12791279
m.Group("/pulls/{index}", func() {
1280+
m.Get("", repo.SetWhitespaceBehavior, repo.GetPullDiffStats, repo.ViewIssue)
12801281
m.Get(".diff", repo.DownloadPullDiff)
12811282
m.Get(".patch", repo.DownloadPullPatch)
1282-
m.Get("/commits", context.RepoRef(), repo.ViewPullCommits)
1283+
m.Get("/commits", context.RepoRef(), repo.SetWhitespaceBehavior, repo.GetPullDiffStats, repo.ViewPullCommits)
12831284
m.Post("/merge", context.RepoMustNotBeArchived(), web.Bind(forms.MergePullRequestForm{}), repo.MergePullRequest)
12841285
m.Post("/cancel_auto_merge", context.RepoMustNotBeArchived(), repo.CancelAutoMergePullRequest)
12851286
m.Post("/update", repo.UpdatePullRequest)

services/gitdiff/gitdiff.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1229,6 +1229,42 @@ func GetDiff(gitRepo *git.Repository, opts *DiffOptions, files ...string) (*Diff
12291229
return diff, nil
12301230
}
12311231

1232+
type PullDiffStats struct {
1233+
TotalAddition, TotalDeletion int
1234+
}
1235+
1236+
// GetPullDiffStats
1237+
func GetPullDiffStats(gitRepo *git.Repository, opts *DiffOptions) (*PullDiffStats, error) {
1238+
repoPath := gitRepo.Path
1239+
1240+
diff := &PullDiffStats{}
1241+
1242+
separator := "..."
1243+
if opts.DirectComparison {
1244+
separator = ".."
1245+
}
1246+
1247+
diffPaths := []string{opts.BeforeCommitID + separator + opts.AfterCommitID}
1248+
if len(opts.BeforeCommitID) == 0 || opts.BeforeCommitID == git.EmptySHA {
1249+
diffPaths = []string{git.EmptyTreeSHA, opts.AfterCommitID}
1250+
}
1251+
1252+
var err error
1253+
1254+
_, diff.TotalAddition, diff.TotalDeletion, err = git.GetDiffShortStat(gitRepo.Ctx, repoPath, nil, diffPaths...)
1255+
if err != nil && strings.Contains(err.Error(), "no merge base") {
1256+
// git >= 2.28 now returns an error if base and head have become unrelated.
1257+
// previously it would return the results of git diff --shortstat base head so let's try that...
1258+
diffPaths = []string{opts.BeforeCommitID, opts.AfterCommitID}
1259+
_, diff.TotalAddition, diff.TotalDeletion, err = git.GetDiffShortStat(gitRepo.Ctx, repoPath, nil, diffPaths...)
1260+
}
1261+
if err != nil {
1262+
return nil, err
1263+
}
1264+
1265+
return diff, nil
1266+
}
1267+
12321268
// SyncAndGetUserSpecificDiff is like GetDiff, except that user specific data such as which files the given user has already viewed on the given PR will also be set
12331269
// Additionally, the database asynchronously is updated if files have changed since the last review
12341270
func SyncAndGetUserSpecificDiff(ctx context.Context, userID int64, pull *issues_model.PullRequest, gitRepo *git.Repository, opts *DiffOptions, files ...string) (*Diff, error) {

templates/repo/pulls/tab_menu.tmpl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,10 @@
1414
{{$.locale.Tr "repo.pulls.tab_files"}}
1515
<span class="ui small label">{{if .NumFiles}}{{.NumFiles}}{{else}}-{{end}}</span>
1616
</a>
17+
<span class="item gt-ml-auto gt-pr-0 gt-font-bold gt-df gt-ac gt-gap-3">
18+
<span><span class="text green">{{if .Diff.TotalAddition}}+{{.Diff.TotalAddition}}{{end}}</span> <span class="text red">{{if .Diff.TotalDeletion}}-{{.Diff.TotalDeletion}}{{end}}</span></span>
19+
<span class="diff-stats-bar">
20+
<div class="diff-stats-add-bar" style="width: {{Eval 100 "*" .Diff.TotalAddition "/" "(" .Diff.TotalAddition "+" .Diff.TotalDeletion "+" 0.0 ")"}}%"></div>
21+
</span>
22+
</span>
1723
</div>

0 commit comments

Comments
 (0)