···12291229 return diff, nil
12301230}
1231123112321232+type PullDiffStats struct {
12331233+ TotalAddition, TotalDeletion int
12341234+}
12351235+12361236+// GetPullDiffStats
12371237+func GetPullDiffStats(gitRepo *git.Repository, opts *DiffOptions) (*PullDiffStats, error) {
12381238+ repoPath := gitRepo.Path
12391239+12401240+ diff := &PullDiffStats{}
12411241+12421242+ separator := "..."
12431243+ if opts.DirectComparison {
12441244+ separator = ".."
12451245+ }
12461246+12471247+ diffPaths := []string{opts.BeforeCommitID + separator + opts.AfterCommitID}
12481248+ if len(opts.BeforeCommitID) == 0 || opts.BeforeCommitID == git.EmptySHA {
12491249+ diffPaths = []string{git.EmptyTreeSHA, opts.AfterCommitID}
12501250+ }
12511251+12521252+ var err error
12531253+12541254+ _, diff.TotalAddition, diff.TotalDeletion, err = git.GetDiffShortStat(gitRepo.Ctx, repoPath, nil, diffPaths...)
12551255+ if err != nil && strings.Contains(err.Error(), "no merge base") {
12561256+ // git >= 2.28 now returns an error if base and head have become unrelated.
12571257+ // previously it would return the results of git diff --shortstat base head so let's try that...
12581258+ diffPaths = []string{opts.BeforeCommitID, opts.AfterCommitID}
12591259+ _, diff.TotalAddition, diff.TotalDeletion, err = git.GetDiffShortStat(gitRepo.Ctx, repoPath, nil, diffPaths...)
12601260+ }
12611261+ if err != nil {
12621262+ return nil, err
12631263+ }
12641264+12651265+ return diff, nil
12661266+}
12671267+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
12341270func SyncAndGetUserSpecificDiff(ctx context.Context, userID int64, pull *issues_model.PullRequest, gitRepo *git.Repository, opts *DiffOptions, files ...string) (*Diff, error) {