Skip to content

Commit d918330

Browse files
committed
Add buttons to allow loading of incomplete diffs
This PR adds two buttons to the stats and the end of the diffs list to load the (some of) the remaining incomplete diff sections. Signed-off-by: Andrew Thornton <[email protected]>
1 parent d217024 commit d918330

File tree

11 files changed

+224
-133
lines changed

11 files changed

+224
-133
lines changed

modules/git/repo_compare.go

+12-8
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ func (repo *Repository) GetMergeBase(tmpRemote string, base, head string) (strin
4646
}
4747

4848
// GetCompareInfo generates and returns compare information between base and head branches of repositories.
49-
func (repo *Repository) GetCompareInfo(basePath, baseBranch, headBranch string) (_ *CompareInfo, err error) {
49+
func (repo *Repository) GetCompareInfo(basePath, baseBranch, headBranch string, fileOnly bool) (_ *CompareInfo, err error) {
5050
var (
5151
remoteBranch string
5252
tmpRemote string
@@ -80,13 +80,17 @@ func (repo *Repository) GetCompareInfo(basePath, baseBranch, headBranch string)
8080
compareInfo.BaseCommitID = remoteBranch
8181
}
8282
// We have a common base - therefore we know that ... should work
83-
logs, err := NewCommand("log", compareInfo.MergeBase+"..."+headBranch, prettyLogFormat).RunInDirBytes(repo.Path)
84-
if err != nil {
85-
return nil, err
86-
}
87-
compareInfo.Commits, err = repo.parsePrettyFormatLogToList(logs)
88-
if err != nil {
89-
return nil, fmt.Errorf("parsePrettyFormatLogToList: %v", err)
83+
if !fileOnly {
84+
logs, err := NewCommand("log", compareInfo.MergeBase+"..."+headBranch, prettyLogFormat).RunInDirBytes(repo.Path)
85+
if err != nil {
86+
return nil, err
87+
}
88+
compareInfo.Commits, err = repo.parsePrettyFormatLogToList(logs)
89+
if err != nil {
90+
return nil, fmt.Errorf("parsePrettyFormatLogToList: %v", err)
91+
}
92+
} else {
93+
compareInfo.Commits = []*Commit{}
9094
}
9195
} else {
9296
compareInfo.Commits = []*Commit{}

options/locale/locale_en-US.ini

+2-1
Original file line numberDiff line numberDiff line change
@@ -2009,7 +2009,8 @@ diff.file_image_height = Height
20092009
diff.file_byte_size = Size
20102010
diff.file_suppressed = File diff suppressed because it is too large
20112011
diff.file_suppressed_line_too_long = File diff suppressed because one or more lines are too long
2012-
diff.too_many_files = Some files were not shown because too many files changed in this diff
2012+
diff.too_many_files = Some files were not shown because too many files have changed in this diff
2013+
diff.show_more = Show More
20132014
diff.comment.placeholder = Leave a comment
20142015
diff.comment.markdown_info = Styling with markdown is supported.
20152016
diff.comment.add_single_comment = Add single comment

routers/api/v1/repo/pull.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -1031,7 +1031,7 @@ func parseCompareInfo(ctx *context.APIContext, form api.CreatePullRequestOption)
10311031
return nil, nil, nil, nil, "", ""
10321032
}
10331033

1034-
compareInfo, err := headGitRepo.GetCompareInfo(models.RepoPath(baseRepo.Owner.Name, baseRepo.Name), baseBranch, headBranch)
1034+
compareInfo, err := headGitRepo.GetCompareInfo(models.RepoPath(baseRepo.Owner.Name, baseRepo.Name), baseBranch, headBranch, false)
10351035
if err != nil {
10361036
headGitRepo.Close()
10371037
ctx.Error(http.StatusInternalServerError, "GetCompareInfo", err)
@@ -1198,9 +1198,9 @@ func GetPullRequestCommits(ctx *context.APIContext) {
11981198
}
11991199
defer baseGitRepo.Close()
12001200
if pr.HasMerged {
1201-
prInfo, err = baseGitRepo.GetCompareInfo(pr.BaseRepo.RepoPath(), pr.MergeBase, pr.GetGitRefName())
1201+
prInfo, err = baseGitRepo.GetCompareInfo(pr.BaseRepo.RepoPath(), pr.MergeBase, pr.GetGitRefName(), false)
12021202
} else {
1203-
prInfo, err = baseGitRepo.GetCompareInfo(pr.BaseRepo.RepoPath(), pr.BaseBranch, pr.GetGitRefName())
1203+
prInfo, err = baseGitRepo.GetCompareInfo(pr.BaseRepo.RepoPath(), pr.BaseBranch, pr.GetGitRefName(), false)
12041204
}
12051205
if err != nil {
12061206
ctx.ServerError("GetCompareInfo", err)

routers/web/repo/commit.go

+9-10
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,8 @@ func Diff(ctx *context.Context) {
263263
err error
264264
)
265265

266+
fileOnly := ctx.FormBool("file-only")
267+
266268
if ctx.Data["PageIsWiki"] != nil {
267269
gitRepo, err = git.OpenRepository(ctx.Repo.Repository.WikiPath())
268270
if err != nil {
@@ -287,16 +289,8 @@ func Diff(ctx *context.Context) {
287289
commitID = commit.ID.String()
288290
}
289291

290-
statuses, err := models.GetLatestCommitStatus(ctx.Repo.Repository.ID, commitID, models.ListOptions{})
291-
if err != nil {
292-
log.Error("GetLatestCommitStatus: %v", err)
293-
}
294-
295-
ctx.Data["CommitStatus"] = models.CalcCommitStatus(statuses)
296-
ctx.Data["CommitStatuses"] = statuses
297-
298292
diff, err := gitdiff.GetDiffCommitWithWhitespaceBehavior(gitRepo,
299-
commitID, setting.Git.MaxGitDiffLines,
293+
commitID, ctx.FormString("skip-to"), setting.Git.MaxGitDiffLines,
300294
setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles,
301295
gitdiff.GetWhitespaceFlag(ctx.Data["WhitespaceBehavior"].(string)))
302296
if err != nil {
@@ -331,10 +325,15 @@ func Diff(ctx *context.Context) {
331325
setCompareContext(ctx, parentCommit, commit, headTarget)
332326
ctx.Data["Title"] = commit.Summary() + " · " + base.ShortSha(commitID)
333327
ctx.Data["Commit"] = commit
328+
ctx.Data["Diff"] = diff
329+
if fileOnly {
330+
ctx.HTML(http.StatusOK, tplDiffBox)
331+
return
332+
}
333+
334334
verification := models.ParseCommitWithSignature(commit)
335335
ctx.Data["Verification"] = verification
336336
ctx.Data["Author"] = models.ValidateCommitWithEmail(commit)
337-
ctx.Data["Diff"] = diff
338337
ctx.Data["Parents"] = parents
339338
ctx.Data["DiffNotAvailable"] = diff.NumFiles == 0
340339

routers/web/repo/compare.go

+51-20
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import (
3131
const (
3232
tplCompare base.TplName = "repo/diff/compare"
3333
tplBlobExcerpt base.TplName = "repo/diff/blob_excerpt"
34+
tplDiffBox base.TplName = "repo/diff/box"
3435
)
3536

3637
// setCompareContext sets context data.
@@ -149,6 +150,8 @@ func setCsvCompareContext(ctx *context.Context) {
149150
func ParseCompareInfo(ctx *context.Context) (*models.User, *models.Repository, *git.Repository, *git.CompareInfo, string, string) {
150151
baseRepo := ctx.Repo.Repository
151152

153+
fileOnly := ctx.FormBool("file-only")
154+
152155
// Get compared branches information
153156
// A full compare url is of the form:
154157
//
@@ -395,15 +398,26 @@ func ParseCompareInfo(ctx *context.Context) (*models.User, *models.Repository, *
395398
if rootRepo != nil &&
396399
rootRepo.ID != headRepo.ID &&
397400
rootRepo.ID != baseRepo.ID {
398-
perm, branches, tags, err := getBranchesAndTagsForRepo(ctx.User, rootRepo)
399-
if err != nil {
400-
ctx.ServerError("GetBranchesForRepo", err)
401-
return nil, nil, nil, nil, "", ""
402-
}
403-
if perm {
404-
ctx.Data["RootRepo"] = rootRepo
405-
ctx.Data["RootRepoBranches"] = branches
406-
ctx.Data["RootRepoTags"] = tags
401+
if !fileOnly {
402+
perm, branches, tags, err := getBranchesAndTagsForRepo(ctx.User, rootRepo)
403+
if err != nil {
404+
ctx.ServerError("GetBranchesForRepo", err)
405+
return nil, nil, nil, nil, "", ""
406+
}
407+
if perm {
408+
ctx.Data["RootRepo"] = rootRepo
409+
ctx.Data["RootRepoBranches"] = branches
410+
ctx.Data["RootRepoTags"] = tags
411+
}
412+
} else {
413+
perm, err := models.GetUserRepoPermission(rootRepo, ctx.User)
414+
if err != nil {
415+
ctx.ServerError("GetUserRepoPermission", err)
416+
return nil, nil, nil, nil, "", ""
417+
}
418+
if !perm.CanRead(models.UnitTypeCode) {
419+
ctx.Data["RootRepo"] = rootRepo
420+
}
407421
}
408422
}
409423

@@ -416,15 +430,26 @@ func ParseCompareInfo(ctx *context.Context) (*models.User, *models.Repository, *
416430
ownForkRepo.ID != headRepo.ID &&
417431
ownForkRepo.ID != baseRepo.ID &&
418432
(rootRepo == nil || ownForkRepo.ID != rootRepo.ID) {
419-
perm, branches, tags, err := getBranchesAndTagsForRepo(ctx.User, ownForkRepo)
420-
if err != nil {
421-
ctx.ServerError("GetBranchesForRepo", err)
422-
return nil, nil, nil, nil, "", ""
423-
}
424-
if perm {
425-
ctx.Data["OwnForkRepo"] = ownForkRepo
426-
ctx.Data["OwnForkRepoBranches"] = branches
427-
ctx.Data["OwnForkRepoTags"] = tags
433+
if !fileOnly {
434+
perm, branches, tags, err := getBranchesAndTagsForRepo(ctx.User, ownForkRepo)
435+
if err != nil {
436+
ctx.ServerError("GetBranchesForRepo", err)
437+
return nil, nil, nil, nil, "", ""
438+
}
439+
if perm {
440+
ctx.Data["OwnForkRepo"] = ownForkRepo
441+
ctx.Data["OwnForkRepoBranches"] = branches
442+
ctx.Data["OwnForkRepoTags"] = tags
443+
}
444+
} else {
445+
perm, err := models.GetUserRepoPermission(rootRepo, ctx.User)
446+
if err != nil {
447+
ctx.ServerError("GetUserRepoPermission", err)
448+
return nil, nil, nil, nil, "", ""
449+
}
450+
if !perm.CanRead(models.UnitTypeCode) {
451+
ctx.Data["RootRepo"] = rootRepo
452+
}
428453
}
429454
}
430455

@@ -476,7 +501,7 @@ func ParseCompareInfo(ctx *context.Context) (*models.User, *models.Repository, *
476501
headBranchRef = git.TagPrefix + headBranch
477502
}
478503

479-
compareInfo, err := headGitRepo.GetCompareInfo(baseRepo.RepoPath(), baseBranchRef, headBranchRef)
504+
compareInfo, err := headGitRepo.GetCompareInfo(baseRepo.RepoPath(), baseBranchRef, headBranchRef, fileOnly)
480505
if err != nil {
481506
ctx.ServerError("GetCompareInfo", err)
482507
return nil, nil, nil, nil, "", ""
@@ -527,7 +552,7 @@ func PrepareCompareDiff(
527552
}
528553

529554
diff, err := gitdiff.GetDiffRangeWithWhitespaceBehavior(headGitRepo,
530-
compareInfo.MergeBase, headCommitID, setting.Git.MaxGitDiffLines,
555+
compareInfo.MergeBase, headCommitID, ctx.FormString("skip-to"), setting.Git.MaxGitDiffLines,
531556
setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, whitespaceBehavior)
532557
if err != nil {
533558
ctx.ServerError("GetDiffRangeWithWhitespaceBehavior", err)
@@ -639,6 +664,12 @@ func CompareDiff(ctx *context.Context) {
639664
}
640665
ctx.Data["Tags"] = baseTags
641666

667+
fileOnly := ctx.FormBool("file-only")
668+
if fileOnly {
669+
ctx.HTML(http.StatusOK, tplDiffBox)
670+
return
671+
}
672+
642673
headBranches, _, err := headGitRepo.GetBranches(0, 0)
643674
if err != nil {
644675
ctx.ServerError("GetBranches", err)

routers/web/repo/pull.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ func PrepareMergedViewPullInfo(ctx *context.Context, issue *models.Issue) *git.C
317317
ctx.Data["HasMerged"] = true
318318

319319
compareInfo, err := ctx.Repo.GitRepo.GetCompareInfo(ctx.Repo.Repository.RepoPath(),
320-
pull.MergeBase, pull.GetGitRefName())
320+
pull.MergeBase, pull.GetGitRefName(), false)
321321
if err != nil {
322322
if strings.Contains(err.Error(), "fatal: Not a valid object name") || strings.Contains(err.Error(), "unknown revision or path not in the working tree") {
323323
ctx.Data["IsPullRequestBroken"] = true
@@ -400,7 +400,7 @@ func PrepareViewPullInfo(ctx *context.Context, issue *models.Issue) *git.Compare
400400
}
401401

402402
compareInfo, err := baseGitRepo.GetCompareInfo(pull.BaseRepo.RepoPath(),
403-
pull.MergeBase, pull.GetGitRefName())
403+
pull.MergeBase, pull.GetGitRefName(), false)
404404
if err != nil {
405405
if strings.Contains(err.Error(), "fatal: Not a valid object name") {
406406
ctx.Data["IsPullRequestBroken"] = true
@@ -516,7 +516,7 @@ func PrepareViewPullInfo(ctx *context.Context, issue *models.Issue) *git.Compare
516516
}
517517

518518
compareInfo, err := baseGitRepo.GetCompareInfo(pull.BaseRepo.RepoPath(),
519-
git.BranchPrefix+pull.BaseBranch, pull.GetGitRefName())
519+
git.BranchPrefix+pull.BaseBranch, pull.GetGitRefName(), false)
520520
if err != nil {
521521
if strings.Contains(err.Error(), "fatal: Not a valid object name") {
522522
ctx.Data["IsPullRequestBroken"] = true
@@ -632,7 +632,7 @@ func ViewPullFiles(ctx *context.Context) {
632632
ctx.Data["AfterCommitID"] = endCommitID
633633

634634
diff, err := gitdiff.GetDiffRangeWithWhitespaceBehavior(gitRepo,
635-
startCommitID, endCommitID, setting.Git.MaxGitDiffLines,
635+
startCommitID, endCommitID, ctx.FormString("skip-to"), setting.Git.MaxGitDiffLines,
636636
setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles,
637637
gitdiff.GetWhitespaceFlag(ctx.Data["WhitespaceBehavior"].(string)))
638638
if err != nil {

services/gitdiff/gitdiff.go

+24-8
Original file line numberDiff line numberDiff line change
@@ -649,6 +649,7 @@ func getCommitFileLineCount(commit *git.Commit, filePath string) int {
649649

650650
// Diff represents a difference between two git trees.
651651
type Diff struct {
652+
Start, End string
652653
NumFiles, TotalAddition, TotalDeletion int
653654
Files []*DiffFile
654655
IsIncomplete bool
@@ -715,6 +716,9 @@ parsingLoop:
715716

716717
// TODO: Handle skipping first n files
717718
if len(diff.Files) >= maxFiles {
719+
720+
lastFile := createDiffFile(diff, line)
721+
diff.End = lastFile.Name
718722
diff.IsIncomplete = true
719723
_, err := io.Copy(ioutil.Discard, reader)
720724
if err != nil {
@@ -1209,7 +1213,7 @@ func readFileName(rd *strings.Reader) (string, bool) {
12091213
// GetDiffRangeWithWhitespaceBehavior builds a Diff between two commits of a repository.
12101214
// Passing the empty string as beforeCommitID returns a diff from the parent commit.
12111215
// The whitespaceBehavior is either an empty string or a git flag
1212-
func GetDiffRangeWithWhitespaceBehavior(gitRepo *git.Repository, beforeCommitID, afterCommitID string, maxLines, maxLineCharacters, maxFiles int, whitespaceBehavior string) (*Diff, error) {
1216+
func GetDiffRangeWithWhitespaceBehavior(gitRepo *git.Repository, beforeCommitID, afterCommitID, skipTo string, maxLines, maxLineCharacters, maxFiles int, whitespaceBehavior string) (*Diff, error) {
12131217
repoPath := gitRepo.Path
12141218

12151219
commit, err := gitRepo.GetCommit(afterCommitID)
@@ -1220,31 +1224,42 @@ func GetDiffRangeWithWhitespaceBehavior(gitRepo *git.Repository, beforeCommitID,
12201224
ctx, cancel := context.WithTimeout(git.DefaultContext, time.Duration(setting.Git.Timeout.Default)*time.Second)
12211225
defer cancel()
12221226

1223-
var cmd *exec.Cmd
1227+
argsLength := 6
1228+
if len(whitespaceBehavior) > 0 {
1229+
argsLength++
1230+
}
1231+
if len(skipTo) > 0 {
1232+
argsLength++
1233+
}
1234+
1235+
diffArgs := make([]string, 0, argsLength)
12241236
if (len(beforeCommitID) == 0 || beforeCommitID == git.EmptySHA) && commit.ParentCount() == 0 {
1225-
diffArgs := []string{"diff", "--src-prefix=\\a/", "--dst-prefix=\\b/", "-M"}
1237+
diffArgs = append(diffArgs, "diff", "--src-prefix=\\a/", "--dst-prefix=\\b/", "-M")
12261238
if len(whitespaceBehavior) != 0 {
12271239
diffArgs = append(diffArgs, whitespaceBehavior)
12281240
}
12291241
// append empty tree ref
12301242
diffArgs = append(diffArgs, "4b825dc642cb6eb9a060e54bf8d69288fbee4904")
12311243
diffArgs = append(diffArgs, afterCommitID)
1232-
cmd = exec.CommandContext(ctx, git.GitExecutable, diffArgs...)
12331244
} else {
12341245
actualBeforeCommitID := beforeCommitID
12351246
if len(actualBeforeCommitID) == 0 {
12361247
parentCommit, _ := commit.Parent(0)
12371248
actualBeforeCommitID = parentCommit.ID.String()
12381249
}
1239-
diffArgs := []string{"diff", "--src-prefix=\\a/", "--dst-prefix=\\b/", "-M"}
1250+
diffArgs = append(diffArgs, "diff", "--src-prefix=\\a/", "--dst-prefix=\\b/", "-M")
12401251
if len(whitespaceBehavior) != 0 {
12411252
diffArgs = append(diffArgs, whitespaceBehavior)
12421253
}
12431254
diffArgs = append(diffArgs, actualBeforeCommitID)
12441255
diffArgs = append(diffArgs, afterCommitID)
1245-
cmd = exec.CommandContext(ctx, git.GitExecutable, diffArgs...)
12461256
beforeCommitID = actualBeforeCommitID
12471257
}
1258+
if skipTo != "" {
1259+
diffArgs = append(diffArgs, "--skip-to="+skipTo)
1260+
}
1261+
cmd := exec.CommandContext(ctx, git.GitExecutable, diffArgs...)
1262+
12481263
cmd.Dir = repoPath
12491264
cmd.Stderr = os.Stderr
12501265

@@ -1264,6 +1279,7 @@ func GetDiffRangeWithWhitespaceBehavior(gitRepo *git.Repository, beforeCommitID,
12641279
if err != nil {
12651280
return nil, fmt.Errorf("ParsePatch: %v", err)
12661281
}
1282+
diff.Start = skipTo
12671283
for _, diffFile := range diff.Files {
12681284
tailSection := diffFile.GetTailSection(gitRepo, beforeCommitID, afterCommitID)
12691285
if tailSection != nil {
@@ -1295,8 +1311,8 @@ func GetDiffRangeWithWhitespaceBehavior(gitRepo *git.Repository, beforeCommitID,
12951311

12961312
// GetDiffCommitWithWhitespaceBehavior builds a Diff representing the given commitID.
12971313
// The whitespaceBehavior is either an empty string or a git flag
1298-
func GetDiffCommitWithWhitespaceBehavior(gitRepo *git.Repository, commitID string, maxLines, maxLineCharacters, maxFiles int, whitespaceBehavior string) (*Diff, error) {
1299-
return GetDiffRangeWithWhitespaceBehavior(gitRepo, "", commitID, maxLines, maxLineCharacters, maxFiles, whitespaceBehavior)
1314+
func GetDiffCommitWithWhitespaceBehavior(gitRepo *git.Repository, commitID, skipTo string, maxLines, maxLineCharacters, maxFiles int, whitespaceBehavior string) (*Diff, error) {
1315+
return GetDiffRangeWithWhitespaceBehavior(gitRepo, "", commitID, skipTo, maxLines, maxLineCharacters, maxFiles, whitespaceBehavior)
13001316
}
13011317

13021318
// CommentAsDiff returns c.Patch as *Diff

services/gitdiff/gitdiff_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -521,7 +521,7 @@ func TestGetDiffRangeWithWhitespaceBehavior(t *testing.T) {
521521
}
522522
defer gitRepo.Close()
523523
for _, behavior := range []string{"-w", "--ignore-space-at-eol", "-b", ""} {
524-
diffs, err := GetDiffRangeWithWhitespaceBehavior(gitRepo, "559c156f8e0178b71cb44355428f24001b08fc68", "bd7063cc7c04689c4d082183d32a604ed27a24f9",
524+
diffs, err := GetDiffRangeWithWhitespaceBehavior(gitRepo, "559c156f8e0178b71cb44355428f24001b08fc68", "bd7063cc7c04689c4d082183d32a604ed27a24f9", "",
525525
setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffFiles, behavior)
526526
assert.NoError(t, err, fmt.Sprintf("Error when diff with %s", behavior))
527527
for _, f := range diffs.Files {

services/pull/pull.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ func NewPullRequest(repo *models.Repository, pull *models.Issue, labelIDs []int6
7979
defer baseGitRepo.Close()
8080

8181
compareInfo, err := baseGitRepo.GetCompareInfo(pr.BaseRepo.RepoPath(),
82-
git.BranchPrefix+pr.BaseBranch, pr.GetGitRefName())
82+
git.BranchPrefix+pr.BaseBranch, pr.GetGitRefName(), false)
8383
if err != nil {
8484
return err
8585
}

0 commit comments

Comments
 (0)