mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-26 12:27:06 +00:00 
			
		
		
		
	Support displaying diff stats in PR tab bar (#25387)
Fix #25326 --------- Co-authored-by: silverwind <me@silverwind.io>
This commit is contained in:
		| @@ -356,12 +356,46 @@ func setMergeTarget(ctx *context.Context, pull *issues_model.PullRequest) { | |||||||
| 	ctx.Data["BaseBranchLink"] = pull.GetBaseBranchLink() | 	ctx.Data["BaseBranchLink"] = pull.GetBaseBranchLink() | ||||||
| } | } | ||||||
|  |  | ||||||
| // PrepareMergedViewPullInfo show meta information for a merged pull request view page | // GetPullDiffStats get Pull Requests diff stats | ||||||
| func PrepareMergedViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *git.CompareInfo { | func GetPullDiffStats(ctx *context.Context) { | ||||||
|  | 	issue := checkPullInfo(ctx) | ||||||
| 	pull := issue.PullRequest | 	pull := issue.PullRequest | ||||||
|  |  | ||||||
| 	setMergeTarget(ctx, pull) | 	mergeBaseCommitID := GetMergedBaseCommitID(ctx, issue) | ||||||
| 	ctx.Data["HasMerged"] = true |  | ||||||
|  | 	if ctx.Written() { | ||||||
|  | 		return | ||||||
|  | 	} else if mergeBaseCommitID == "" { | ||||||
|  | 		ctx.NotFound("PullFiles", nil) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	headCommitID, err := ctx.Repo.GitRepo.GetRefCommitID(pull.GetGitRefName()) | ||||||
|  | 	if err != nil { | ||||||
|  | 		ctx.ServerError("GetRefCommitID", err) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	diffOptions := &gitdiff.DiffOptions{ | ||||||
|  | 		BeforeCommitID:     mergeBaseCommitID, | ||||||
|  | 		AfterCommitID:      headCommitID, | ||||||
|  | 		MaxLines:           setting.Git.MaxGitDiffLines, | ||||||
|  | 		MaxLineCharacters:  setting.Git.MaxGitDiffLineCharacters, | ||||||
|  | 		MaxFiles:           setting.Git.MaxGitDiffFiles, | ||||||
|  | 		WhitespaceBehavior: gitdiff.GetWhitespaceFlag(ctx.Data["WhitespaceBehavior"].(string)), | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	diff, err := gitdiff.GetPullDiffStats(ctx.Repo.GitRepo, diffOptions) | ||||||
|  | 	if err != nil { | ||||||
|  | 		ctx.ServerError("GetPullDiffStats", err) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	ctx.Data["Diff"] = diff | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func GetMergedBaseCommitID(ctx *context.Context, issue *issues_model.Issue) string { | ||||||
|  | 	pull := issue.PullRequest | ||||||
|  |  | ||||||
| 	var baseCommit string | 	var baseCommit string | ||||||
| 	// Some migrated PR won't have any Base SHA and lose history, try to get one | 	// 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) | |||||||
| 		baseCommit = pull.MergeBase | 		baseCommit = pull.MergeBase | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	return baseCommit | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // PrepareMergedViewPullInfo show meta information for a merged pull request view page | ||||||
|  | func PrepareMergedViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *git.CompareInfo { | ||||||
|  | 	pull := issue.PullRequest | ||||||
|  |  | ||||||
|  | 	setMergeTarget(ctx, pull) | ||||||
|  | 	ctx.Data["HasMerged"] = true | ||||||
|  |  | ||||||
|  | 	baseCommit := GetMergedBaseCommitID(ctx, issue) | ||||||
|  |  | ||||||
| 	compareInfo, err := ctx.Repo.GitRepo.GetCompareInfo(ctx.Repo.Repository.RepoPath(), | 	compareInfo, err := ctx.Repo.GitRepo.GetCompareInfo(ctx.Repo.Repository.RepoPath(), | ||||||
| 		baseCommit, pull.GetGitRefName(), false, false) | 		baseCommit, pull.GetGitRefName(), false, false) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
|   | |||||||
| @@ -1277,9 +1277,10 @@ func registerRoutes(m *web.Route) { | |||||||
| 		}) | 		}) | ||||||
|  |  | ||||||
| 		m.Group("/pulls/{index}", func() { | 		m.Group("/pulls/{index}", func() { | ||||||
|  | 			m.Get("", repo.SetWhitespaceBehavior, repo.GetPullDiffStats, repo.ViewIssue) | ||||||
| 			m.Get(".diff", repo.DownloadPullDiff) | 			m.Get(".diff", repo.DownloadPullDiff) | ||||||
| 			m.Get(".patch", repo.DownloadPullPatch) | 			m.Get(".patch", repo.DownloadPullPatch) | ||||||
| 			m.Get("/commits", context.RepoRef(), repo.ViewPullCommits) | 			m.Get("/commits", context.RepoRef(), repo.SetWhitespaceBehavior, repo.GetPullDiffStats, repo.ViewPullCommits) | ||||||
| 			m.Post("/merge", context.RepoMustNotBeArchived(), web.Bind(forms.MergePullRequestForm{}), repo.MergePullRequest) | 			m.Post("/merge", context.RepoMustNotBeArchived(), web.Bind(forms.MergePullRequestForm{}), repo.MergePullRequest) | ||||||
| 			m.Post("/cancel_auto_merge", context.RepoMustNotBeArchived(), repo.CancelAutoMergePullRequest) | 			m.Post("/cancel_auto_merge", context.RepoMustNotBeArchived(), repo.CancelAutoMergePullRequest) | ||||||
| 			m.Post("/update", repo.UpdatePullRequest) | 			m.Post("/update", repo.UpdatePullRequest) | ||||||
|   | |||||||
| @@ -1229,6 +1229,42 @@ func GetDiff(gitRepo *git.Repository, opts *DiffOptions, files ...string) (*Diff | |||||||
| 	return diff, nil | 	return diff, nil | ||||||
| } | } | ||||||
|  |  | ||||||
|  | type PullDiffStats struct { | ||||||
|  | 	TotalAddition, TotalDeletion int | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetPullDiffStats | ||||||
|  | func GetPullDiffStats(gitRepo *git.Repository, opts *DiffOptions) (*PullDiffStats, error) { | ||||||
|  | 	repoPath := gitRepo.Path | ||||||
|  |  | ||||||
|  | 	diff := &PullDiffStats{} | ||||||
|  |  | ||||||
|  | 	separator := "..." | ||||||
|  | 	if opts.DirectComparison { | ||||||
|  | 		separator = ".." | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	diffPaths := []string{opts.BeforeCommitID + separator + opts.AfterCommitID} | ||||||
|  | 	if len(opts.BeforeCommitID) == 0 || opts.BeforeCommitID == git.EmptySHA { | ||||||
|  | 		diffPaths = []string{git.EmptyTreeSHA, opts.AfterCommitID} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	var err error | ||||||
|  |  | ||||||
|  | 	_, diff.TotalAddition, diff.TotalDeletion, err = git.GetDiffShortStat(gitRepo.Ctx, repoPath, nil, diffPaths...) | ||||||
|  | 	if err != nil && strings.Contains(err.Error(), "no merge base") { | ||||||
|  | 		// git >= 2.28 now returns an error if base and head have become unrelated. | ||||||
|  | 		// previously it would return the results of git diff --shortstat base head so let's try that... | ||||||
|  | 		diffPaths = []string{opts.BeforeCommitID, opts.AfterCommitID} | ||||||
|  | 		_, diff.TotalAddition, diff.TotalDeletion, err = git.GetDiffShortStat(gitRepo.Ctx, repoPath, nil, diffPaths...) | ||||||
|  | 	} | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return diff, nil | ||||||
|  | } | ||||||
|  |  | ||||||
| // 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 | // 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 | ||||||
| // Additionally, the database asynchronously is updated if files have changed since the last review | // Additionally, the database asynchronously is updated if files have changed since the last review | ||||||
| func SyncAndGetUserSpecificDiff(ctx context.Context, userID int64, pull *issues_model.PullRequest, gitRepo *git.Repository, opts *DiffOptions, files ...string) (*Diff, error) { | func SyncAndGetUserSpecificDiff(ctx context.Context, userID int64, pull *issues_model.PullRequest, gitRepo *git.Repository, opts *DiffOptions, files ...string) (*Diff, error) { | ||||||
|   | |||||||
| @@ -14,4 +14,10 @@ | |||||||
| 		{{$.locale.Tr "repo.pulls.tab_files"}} | 		{{$.locale.Tr "repo.pulls.tab_files"}} | ||||||
| 		<span class="ui small label">{{if .NumFiles}}{{.NumFiles}}{{else}}-{{end}}</span> | 		<span class="ui small label">{{if .NumFiles}}{{.NumFiles}}{{else}}-{{end}}</span> | ||||||
| 	</a> | 	</a> | ||||||
|  | 	<span class="item gt-ml-auto gt-pr-0 gt-font-bold gt-df gt-ac gt-gap-3"> | ||||||
|  | 		<span><span class="text green">{{if .Diff.TotalAddition}}+{{.Diff.TotalAddition}}{{end}}</span> <span class="text red">{{if .Diff.TotalDeletion}}-{{.Diff.TotalDeletion}}{{end}}</span></span> | ||||||
|  | 		<span class="diff-stats-bar"> | ||||||
|  | 			<div class="diff-stats-add-bar" style="width: {{Eval 100 "*" .Diff.TotalAddition "/" "(" .Diff.TotalAddition "+" .Diff.TotalDeletion "+" 0.0 ")"}}%"></div> | ||||||
|  | 		</span> | ||||||
|  | 	</span> | ||||||
| </div> | </div> | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 hiifong
					hiifong