loading up the forgejo repo on tangled to test page performance
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Support displaying diff stats in PR tab bar (#25387)

Fix #25326

---------

Co-authored-by: silverwind <me@silverwind.io>

authored by

hiifong
silverwind
and committed by
GitHub
36f1fa77 eab011db

+94 -5
+50 -4
routers/web/repo/pull.go
··· 356 356 ctx.Data["BaseBranchLink"] = pull.GetBaseBranchLink() 357 357 } 358 358 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) 361 362 pull := issue.PullRequest 362 363 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 365 399 366 400 var baseCommit string 367 401 // Some migrated PR won't have any Base SHA and lose history, try to get one ··· 400 434 // Keep an empty history or original commit 401 435 baseCommit = pull.MergeBase 402 436 } 437 + 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) 403 449 404 450 compareInfo, err := ctx.Repo.GitRepo.GetCompareInfo(ctx.Repo.Repository.RepoPath(), 405 451 baseCommit, pull.GetGitRefName(), false, false)
+2 -1
routers/web/web.go
··· 1277 1277 }) 1278 1278 1279 1279 m.Group("/pulls/{index}", func() { 1280 + m.Get("", repo.SetWhitespaceBehavior, repo.GetPullDiffStats, repo.ViewIssue) 1280 1281 m.Get(".diff", repo.DownloadPullDiff) 1281 1282 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) 1283 1284 m.Post("/merge", context.RepoMustNotBeArchived(), web.Bind(forms.MergePullRequestForm{}), repo.MergePullRequest) 1284 1285 m.Post("/cancel_auto_merge", context.RepoMustNotBeArchived(), repo.CancelAutoMergePullRequest) 1285 1286 m.Post("/update", repo.UpdatePullRequest)
+36
services/gitdiff/gitdiff.go
··· 1229 1229 return diff, nil 1230 1230 } 1231 1231 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 + 1232 1268 // 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 1233 1269 // Additionally, the database asynchronously is updated if files have changed since the last review 1234 1270 func SyncAndGetUserSpecificDiff(ctx context.Context, userID int64, pull *issues_model.PullRequest, gitRepo *git.Repository, opts *DiffOptions, files ...string) (*Diff, error) {
+6
templates/repo/pulls/tab_menu.tmpl
··· 14 14 {{$.locale.Tr "repo.pulls.tab_files"}} 15 15 <span class="ui small label">{{if .NumFiles}}{{.NumFiles}}{{else}}-{{end}}</span> 16 16 </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> 17 23 </div>