From d918330db05438598ddf58fec5bf52d05178b0ff Mon Sep 17 00:00:00 2001 From: Andrew Thornton Date: Tue, 10 Aug 2021 19:29:34 +0100 Subject: [PATCH 1/8] 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 --- modules/git/repo_compare.go | 20 ++-- options/locale/locale_en-US.ini | 3 +- routers/api/v1/repo/pull.go | 6 +- routers/web/repo/commit.go | 19 ++-- routers/web/repo/compare.go | 71 +++++++++---- routers/web/repo/pull.go | 8 +- services/gitdiff/gitdiff.go | 32 ++++-- services/gitdiff/gitdiff_test.go | 2 +- services/pull/pull.go | 2 +- templates/repo/diff/box.tmpl | 164 ++++++++++++++++--------------- web_src/js/index.js | 30 ++++++ 11 files changed, 224 insertions(+), 133 deletions(-) diff --git a/modules/git/repo_compare.go b/modules/git/repo_compare.go index 5d1208aab18fe..830911f83e388 100644 --- a/modules/git/repo_compare.go +++ b/modules/git/repo_compare.go @@ -46,7 +46,7 @@ func (repo *Repository) GetMergeBase(tmpRemote string, base, head string) (strin } // GetCompareInfo generates and returns compare information between base and head branches of repositories. -func (repo *Repository) GetCompareInfo(basePath, baseBranch, headBranch string) (_ *CompareInfo, err error) { +func (repo *Repository) GetCompareInfo(basePath, baseBranch, headBranch string, fileOnly bool) (_ *CompareInfo, err error) { var ( remoteBranch string tmpRemote string @@ -80,13 +80,17 @@ func (repo *Repository) GetCompareInfo(basePath, baseBranch, headBranch string) compareInfo.BaseCommitID = remoteBranch } // We have a common base - therefore we know that ... should work - logs, err := NewCommand("log", compareInfo.MergeBase+"..."+headBranch, prettyLogFormat).RunInDirBytes(repo.Path) - if err != nil { - return nil, err - } - compareInfo.Commits, err = repo.parsePrettyFormatLogToList(logs) - if err != nil { - return nil, fmt.Errorf("parsePrettyFormatLogToList: %v", err) + if !fileOnly { + logs, err := NewCommand("log", compareInfo.MergeBase+"..."+headBranch, prettyLogFormat).RunInDirBytes(repo.Path) + if err != nil { + return nil, err + } + compareInfo.Commits, err = repo.parsePrettyFormatLogToList(logs) + if err != nil { + return nil, fmt.Errorf("parsePrettyFormatLogToList: %v", err) + } + } else { + compareInfo.Commits = []*Commit{} } } else { compareInfo.Commits = []*Commit{} diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 76536f2d49752..5441295ef5b1c 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -2009,7 +2009,8 @@ diff.file_image_height = Height diff.file_byte_size = Size diff.file_suppressed = File diff suppressed because it is too large diff.file_suppressed_line_too_long = File diff suppressed because one or more lines are too long -diff.too_many_files = Some files were not shown because too many files changed in this diff +diff.too_many_files = Some files were not shown because too many files have changed in this diff +diff.show_more = Show More diff.comment.placeholder = Leave a comment diff.comment.markdown_info = Styling with markdown is supported. diff.comment.add_single_comment = Add single comment diff --git a/routers/api/v1/repo/pull.go b/routers/api/v1/repo/pull.go index 0a903101c7536..709b9bb852778 100644 --- a/routers/api/v1/repo/pull.go +++ b/routers/api/v1/repo/pull.go @@ -1031,7 +1031,7 @@ func parseCompareInfo(ctx *context.APIContext, form api.CreatePullRequestOption) return nil, nil, nil, nil, "", "" } - compareInfo, err := headGitRepo.GetCompareInfo(models.RepoPath(baseRepo.Owner.Name, baseRepo.Name), baseBranch, headBranch) + compareInfo, err := headGitRepo.GetCompareInfo(models.RepoPath(baseRepo.Owner.Name, baseRepo.Name), baseBranch, headBranch, false) if err != nil { headGitRepo.Close() ctx.Error(http.StatusInternalServerError, "GetCompareInfo", err) @@ -1198,9 +1198,9 @@ func GetPullRequestCommits(ctx *context.APIContext) { } defer baseGitRepo.Close() if pr.HasMerged { - prInfo, err = baseGitRepo.GetCompareInfo(pr.BaseRepo.RepoPath(), pr.MergeBase, pr.GetGitRefName()) + prInfo, err = baseGitRepo.GetCompareInfo(pr.BaseRepo.RepoPath(), pr.MergeBase, pr.GetGitRefName(), false) } else { - prInfo, err = baseGitRepo.GetCompareInfo(pr.BaseRepo.RepoPath(), pr.BaseBranch, pr.GetGitRefName()) + prInfo, err = baseGitRepo.GetCompareInfo(pr.BaseRepo.RepoPath(), pr.BaseBranch, pr.GetGitRefName(), false) } if err != nil { ctx.ServerError("GetCompareInfo", err) diff --git a/routers/web/repo/commit.go b/routers/web/repo/commit.go index 810581640cc27..801810eb12193 100644 --- a/routers/web/repo/commit.go +++ b/routers/web/repo/commit.go @@ -263,6 +263,8 @@ func Diff(ctx *context.Context) { err error ) + fileOnly := ctx.FormBool("file-only") + if ctx.Data["PageIsWiki"] != nil { gitRepo, err = git.OpenRepository(ctx.Repo.Repository.WikiPath()) if err != nil { @@ -287,16 +289,8 @@ func Diff(ctx *context.Context) { commitID = commit.ID.String() } - statuses, err := models.GetLatestCommitStatus(ctx.Repo.Repository.ID, commitID, models.ListOptions{}) - if err != nil { - log.Error("GetLatestCommitStatus: %v", err) - } - - ctx.Data["CommitStatus"] = models.CalcCommitStatus(statuses) - ctx.Data["CommitStatuses"] = statuses - diff, err := gitdiff.GetDiffCommitWithWhitespaceBehavior(gitRepo, - commitID, setting.Git.MaxGitDiffLines, + commitID, ctx.FormString("skip-to"), setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, gitdiff.GetWhitespaceFlag(ctx.Data["WhitespaceBehavior"].(string))) if err != nil { @@ -331,10 +325,15 @@ func Diff(ctx *context.Context) { setCompareContext(ctx, parentCommit, commit, headTarget) ctx.Data["Title"] = commit.Summary() + " ยท " + base.ShortSha(commitID) ctx.Data["Commit"] = commit + ctx.Data["Diff"] = diff + if fileOnly { + ctx.HTML(http.StatusOK, tplDiffBox) + return + } + verification := models.ParseCommitWithSignature(commit) ctx.Data["Verification"] = verification ctx.Data["Author"] = models.ValidateCommitWithEmail(commit) - ctx.Data["Diff"] = diff ctx.Data["Parents"] = parents ctx.Data["DiffNotAvailable"] = diff.NumFiles == 0 diff --git a/routers/web/repo/compare.go b/routers/web/repo/compare.go index eb6c37a1a6363..68160ba9b8efb 100644 --- a/routers/web/repo/compare.go +++ b/routers/web/repo/compare.go @@ -31,6 +31,7 @@ import ( const ( tplCompare base.TplName = "repo/diff/compare" tplBlobExcerpt base.TplName = "repo/diff/blob_excerpt" + tplDiffBox base.TplName = "repo/diff/box" ) // setCompareContext sets context data. @@ -149,6 +150,8 @@ func setCsvCompareContext(ctx *context.Context) { func ParseCompareInfo(ctx *context.Context) (*models.User, *models.Repository, *git.Repository, *git.CompareInfo, string, string) { baseRepo := ctx.Repo.Repository + fileOnly := ctx.FormBool("file-only") + // Get compared branches information // A full compare url is of the form: // @@ -395,15 +398,26 @@ func ParseCompareInfo(ctx *context.Context) (*models.User, *models.Repository, * if rootRepo != nil && rootRepo.ID != headRepo.ID && rootRepo.ID != baseRepo.ID { - perm, branches, tags, err := getBranchesAndTagsForRepo(ctx.User, rootRepo) - if err != nil { - ctx.ServerError("GetBranchesForRepo", err) - return nil, nil, nil, nil, "", "" - } - if perm { - ctx.Data["RootRepo"] = rootRepo - ctx.Data["RootRepoBranches"] = branches - ctx.Data["RootRepoTags"] = tags + if !fileOnly { + perm, branches, tags, err := getBranchesAndTagsForRepo(ctx.User, rootRepo) + if err != nil { + ctx.ServerError("GetBranchesForRepo", err) + return nil, nil, nil, nil, "", "" + } + if perm { + ctx.Data["RootRepo"] = rootRepo + ctx.Data["RootRepoBranches"] = branches + ctx.Data["RootRepoTags"] = tags + } + } else { + perm, err := models.GetUserRepoPermission(rootRepo, ctx.User) + if err != nil { + ctx.ServerError("GetUserRepoPermission", err) + return nil, nil, nil, nil, "", "" + } + if !perm.CanRead(models.UnitTypeCode) { + ctx.Data["RootRepo"] = rootRepo + } } } @@ -416,15 +430,26 @@ func ParseCompareInfo(ctx *context.Context) (*models.User, *models.Repository, * ownForkRepo.ID != headRepo.ID && ownForkRepo.ID != baseRepo.ID && (rootRepo == nil || ownForkRepo.ID != rootRepo.ID) { - perm, branches, tags, err := getBranchesAndTagsForRepo(ctx.User, ownForkRepo) - if err != nil { - ctx.ServerError("GetBranchesForRepo", err) - return nil, nil, nil, nil, "", "" - } - if perm { - ctx.Data["OwnForkRepo"] = ownForkRepo - ctx.Data["OwnForkRepoBranches"] = branches - ctx.Data["OwnForkRepoTags"] = tags + if !fileOnly { + perm, branches, tags, err := getBranchesAndTagsForRepo(ctx.User, ownForkRepo) + if err != nil { + ctx.ServerError("GetBranchesForRepo", err) + return nil, nil, nil, nil, "", "" + } + if perm { + ctx.Data["OwnForkRepo"] = ownForkRepo + ctx.Data["OwnForkRepoBranches"] = branches + ctx.Data["OwnForkRepoTags"] = tags + } + } else { + perm, err := models.GetUserRepoPermission(rootRepo, ctx.User) + if err != nil { + ctx.ServerError("GetUserRepoPermission", err) + return nil, nil, nil, nil, "", "" + } + if !perm.CanRead(models.UnitTypeCode) { + ctx.Data["RootRepo"] = rootRepo + } } } @@ -476,7 +501,7 @@ func ParseCompareInfo(ctx *context.Context) (*models.User, *models.Repository, * headBranchRef = git.TagPrefix + headBranch } - compareInfo, err := headGitRepo.GetCompareInfo(baseRepo.RepoPath(), baseBranchRef, headBranchRef) + compareInfo, err := headGitRepo.GetCompareInfo(baseRepo.RepoPath(), baseBranchRef, headBranchRef, fileOnly) if err != nil { ctx.ServerError("GetCompareInfo", err) return nil, nil, nil, nil, "", "" @@ -527,7 +552,7 @@ func PrepareCompareDiff( } diff, err := gitdiff.GetDiffRangeWithWhitespaceBehavior(headGitRepo, - compareInfo.MergeBase, headCommitID, setting.Git.MaxGitDiffLines, + compareInfo.MergeBase, headCommitID, ctx.FormString("skip-to"), setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, whitespaceBehavior) if err != nil { ctx.ServerError("GetDiffRangeWithWhitespaceBehavior", err) @@ -639,6 +664,12 @@ func CompareDiff(ctx *context.Context) { } ctx.Data["Tags"] = baseTags + fileOnly := ctx.FormBool("file-only") + if fileOnly { + ctx.HTML(http.StatusOK, tplDiffBox) + return + } + headBranches, _, err := headGitRepo.GetBranches(0, 0) if err != nil { ctx.ServerError("GetBranches", err) diff --git a/routers/web/repo/pull.go b/routers/web/repo/pull.go index 8ff2ddf3949d1..d3091e75b6cab 100644 --- a/routers/web/repo/pull.go +++ b/routers/web/repo/pull.go @@ -317,7 +317,7 @@ func PrepareMergedViewPullInfo(ctx *context.Context, issue *models.Issue) *git.C ctx.Data["HasMerged"] = true compareInfo, err := ctx.Repo.GitRepo.GetCompareInfo(ctx.Repo.Repository.RepoPath(), - pull.MergeBase, pull.GetGitRefName()) + pull.MergeBase, pull.GetGitRefName(), false) if err != nil { if strings.Contains(err.Error(), "fatal: Not a valid object name") || strings.Contains(err.Error(), "unknown revision or path not in the working tree") { ctx.Data["IsPullRequestBroken"] = true @@ -400,7 +400,7 @@ func PrepareViewPullInfo(ctx *context.Context, issue *models.Issue) *git.Compare } compareInfo, err := baseGitRepo.GetCompareInfo(pull.BaseRepo.RepoPath(), - pull.MergeBase, pull.GetGitRefName()) + pull.MergeBase, pull.GetGitRefName(), false) if err != nil { if strings.Contains(err.Error(), "fatal: Not a valid object name") { ctx.Data["IsPullRequestBroken"] = true @@ -516,7 +516,7 @@ func PrepareViewPullInfo(ctx *context.Context, issue *models.Issue) *git.Compare } compareInfo, err := baseGitRepo.GetCompareInfo(pull.BaseRepo.RepoPath(), - git.BranchPrefix+pull.BaseBranch, pull.GetGitRefName()) + git.BranchPrefix+pull.BaseBranch, pull.GetGitRefName(), false) if err != nil { if strings.Contains(err.Error(), "fatal: Not a valid object name") { ctx.Data["IsPullRequestBroken"] = true @@ -632,7 +632,7 @@ func ViewPullFiles(ctx *context.Context) { ctx.Data["AfterCommitID"] = endCommitID diff, err := gitdiff.GetDiffRangeWithWhitespaceBehavior(gitRepo, - startCommitID, endCommitID, setting.Git.MaxGitDiffLines, + startCommitID, endCommitID, ctx.FormString("skip-to"), setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, gitdiff.GetWhitespaceFlag(ctx.Data["WhitespaceBehavior"].(string))) if err != nil { diff --git a/services/gitdiff/gitdiff.go b/services/gitdiff/gitdiff.go index c1d1c40d3d800..c9dcef87afac6 100644 --- a/services/gitdiff/gitdiff.go +++ b/services/gitdiff/gitdiff.go @@ -649,6 +649,7 @@ func getCommitFileLineCount(commit *git.Commit, filePath string) int { // Diff represents a difference between two git trees. type Diff struct { + Start, End string NumFiles, TotalAddition, TotalDeletion int Files []*DiffFile IsIncomplete bool @@ -715,6 +716,9 @@ parsingLoop: // TODO: Handle skipping first n files if len(diff.Files) >= maxFiles { + + lastFile := createDiffFile(diff, line) + diff.End = lastFile.Name diff.IsIncomplete = true _, err := io.Copy(ioutil.Discard, reader) if err != nil { @@ -1209,7 +1213,7 @@ func readFileName(rd *strings.Reader) (string, bool) { // GetDiffRangeWithWhitespaceBehavior builds a Diff between two commits of a repository. // Passing the empty string as beforeCommitID returns a diff from the parent commit. // The whitespaceBehavior is either an empty string or a git flag -func GetDiffRangeWithWhitespaceBehavior(gitRepo *git.Repository, beforeCommitID, afterCommitID string, maxLines, maxLineCharacters, maxFiles int, whitespaceBehavior string) (*Diff, error) { +func GetDiffRangeWithWhitespaceBehavior(gitRepo *git.Repository, beforeCommitID, afterCommitID, skipTo string, maxLines, maxLineCharacters, maxFiles int, whitespaceBehavior string) (*Diff, error) { repoPath := gitRepo.Path commit, err := gitRepo.GetCommit(afterCommitID) @@ -1220,31 +1224,42 @@ func GetDiffRangeWithWhitespaceBehavior(gitRepo *git.Repository, beforeCommitID, ctx, cancel := context.WithTimeout(git.DefaultContext, time.Duration(setting.Git.Timeout.Default)*time.Second) defer cancel() - var cmd *exec.Cmd + argsLength := 6 + if len(whitespaceBehavior) > 0 { + argsLength++ + } + if len(skipTo) > 0 { + argsLength++ + } + + diffArgs := make([]string, 0, argsLength) if (len(beforeCommitID) == 0 || beforeCommitID == git.EmptySHA) && commit.ParentCount() == 0 { - diffArgs := []string{"diff", "--src-prefix=\\a/", "--dst-prefix=\\b/", "-M"} + diffArgs = append(diffArgs, "diff", "--src-prefix=\\a/", "--dst-prefix=\\b/", "-M") if len(whitespaceBehavior) != 0 { diffArgs = append(diffArgs, whitespaceBehavior) } // append empty tree ref diffArgs = append(diffArgs, "4b825dc642cb6eb9a060e54bf8d69288fbee4904") diffArgs = append(diffArgs, afterCommitID) - cmd = exec.CommandContext(ctx, git.GitExecutable, diffArgs...) } else { actualBeforeCommitID := beforeCommitID if len(actualBeforeCommitID) == 0 { parentCommit, _ := commit.Parent(0) actualBeforeCommitID = parentCommit.ID.String() } - diffArgs := []string{"diff", "--src-prefix=\\a/", "--dst-prefix=\\b/", "-M"} + diffArgs = append(diffArgs, "diff", "--src-prefix=\\a/", "--dst-prefix=\\b/", "-M") if len(whitespaceBehavior) != 0 { diffArgs = append(diffArgs, whitespaceBehavior) } diffArgs = append(diffArgs, actualBeforeCommitID) diffArgs = append(diffArgs, afterCommitID) - cmd = exec.CommandContext(ctx, git.GitExecutable, diffArgs...) beforeCommitID = actualBeforeCommitID } + if skipTo != "" { + diffArgs = append(diffArgs, "--skip-to="+skipTo) + } + cmd := exec.CommandContext(ctx, git.GitExecutable, diffArgs...) + cmd.Dir = repoPath cmd.Stderr = os.Stderr @@ -1264,6 +1279,7 @@ func GetDiffRangeWithWhitespaceBehavior(gitRepo *git.Repository, beforeCommitID, if err != nil { return nil, fmt.Errorf("ParsePatch: %v", err) } + diff.Start = skipTo for _, diffFile := range diff.Files { tailSection := diffFile.GetTailSection(gitRepo, beforeCommitID, afterCommitID) if tailSection != nil { @@ -1295,8 +1311,8 @@ func GetDiffRangeWithWhitespaceBehavior(gitRepo *git.Repository, beforeCommitID, // GetDiffCommitWithWhitespaceBehavior builds a Diff representing the given commitID. // The whitespaceBehavior is either an empty string or a git flag -func GetDiffCommitWithWhitespaceBehavior(gitRepo *git.Repository, commitID string, maxLines, maxLineCharacters, maxFiles int, whitespaceBehavior string) (*Diff, error) { - return GetDiffRangeWithWhitespaceBehavior(gitRepo, "", commitID, maxLines, maxLineCharacters, maxFiles, whitespaceBehavior) +func GetDiffCommitWithWhitespaceBehavior(gitRepo *git.Repository, commitID, skipTo string, maxLines, maxLineCharacters, maxFiles int, whitespaceBehavior string) (*Diff, error) { + return GetDiffRangeWithWhitespaceBehavior(gitRepo, "", commitID, skipTo, maxLines, maxLineCharacters, maxFiles, whitespaceBehavior) } // CommentAsDiff returns c.Patch as *Diff diff --git a/services/gitdiff/gitdiff_test.go b/services/gitdiff/gitdiff_test.go index 57364ace3e5a8..044b81cef2806 100644 --- a/services/gitdiff/gitdiff_test.go +++ b/services/gitdiff/gitdiff_test.go @@ -521,7 +521,7 @@ func TestGetDiffRangeWithWhitespaceBehavior(t *testing.T) { } defer gitRepo.Close() for _, behavior := range []string{"-w", "--ignore-space-at-eol", "-b", ""} { - diffs, err := GetDiffRangeWithWhitespaceBehavior(gitRepo, "559c156f8e0178b71cb44355428f24001b08fc68", "bd7063cc7c04689c4d082183d32a604ed27a24f9", + diffs, err := GetDiffRangeWithWhitespaceBehavior(gitRepo, "559c156f8e0178b71cb44355428f24001b08fc68", "bd7063cc7c04689c4d082183d32a604ed27a24f9", "", setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffFiles, behavior) assert.NoError(t, err, fmt.Sprintf("Error when diff with %s", behavior)) for _, f := range diffs.Files { diff --git a/services/pull/pull.go b/services/pull/pull.go index 23407ea67bdb2..c34d1960b281e 100644 --- a/services/pull/pull.go +++ b/services/pull/pull.go @@ -79,7 +79,7 @@ func NewPullRequest(repo *models.Repository, pull *models.Issue, labelIDs []int6 defer baseGitRepo.Close() compareInfo, err := baseGitRepo.GetCompareInfo(pr.BaseRepo.RepoPath(), - git.BranchPrefix+pr.BaseBranch, pr.GetGitRefName()) + git.BranchPrefix+pr.BaseBranch, pr.GetGitRefName(), false) if err != nil { return err } diff --git a/templates/repo/diff/box.tmpl b/templates/repo/diff/box.tmpl index 4f8f7260976aa..59a4db1eafb8b 100644 --- a/templates/repo/diff/box.tmpl +++ b/templates/repo/diff/box.tmpl @@ -42,95 +42,105 @@ {{.Name}} {{end}} + {{if .Diff.IsIncomplete}} +
  • + {{$.i18n.Tr "repo.diff.too_many_files"}} + {{.i18n.Tr "repo.diff.show_more"}} + +
  • + {{end}} - {{range $i, $file := .Diff.Files}} - {{$blobBase := call $.GetBlobByPathForCommit $.BaseCommit $file.OldName}} - {{$blobHead := call $.GetBlobByPathForCommit $.HeadCommit $file.Name}} - {{$isImage := or (call $.IsBlobAnImage $blobBase) (call $.IsBlobAnImage $blobHead)}} - {{$isCsv := (call $.IsCsvFile $file)}} - {{$showFileViewToggle := or $isImage (and (not $file.IsIncomplete) $isCsv)}} -
    -

    -
    - - {{svg "octicon-chevron-down" 18}} - -
    - {{if $file.IsBin}} - - {{$.i18n.Tr "repo.diff.bin"}} - - {{else}} - {{template "repo/diff/stats" dict "file" . "root" $}} +
    + {{range $i, $file := .Diff.Files}} + {{$blobBase := call $.GetBlobByPathForCommit $.BaseCommit $file.OldName}} + {{$blobHead := call $.GetBlobByPathForCommit $.HeadCommit $file.Name}} + {{$isImage := or (call $.IsBlobAnImage $blobBase) (call $.IsBlobAnImage $blobHead)}} + {{$isCsv := (call $.IsCsvFile $file)}} + {{$showFileViewToggle := or $isImage (and (not $file.IsIncomplete) $isCsv)}} +
    +

    +
    + + {{svg "octicon-chevron-down" 18}} + +
    + {{if $file.IsBin}} + + {{$.i18n.Tr "repo.diff.bin"}} + + {{else}} + {{template "repo/diff/stats" dict "file" . "root" $}} + {{end}} +
    + {{if $file.IsRenamed}}{{$file.OldName}} → {{end}}{{$file.Name}}{{if .IsLFSFile}} ({{$.i18n.Tr "repo.stored_lfs"}}){{end}} +
    +
    + {{if $showFileViewToggle}} +
    + {{svg "octicon-code"}} + {{svg "octicon-file"}} +
    + {{end}} + {{if $file.IsProtected}} + {{$.i18n.Tr "repo.diff.protected"}} + {{end}} + {{if and (not $file.IsSubmodule) (not $.PageIsWiki)}} + {{if $file.IsDeleted}} + {{$.i18n.Tr "repo.diff.view_file"}} + {{else}} + {{$.i18n.Tr "repo.diff.view_file"}} + {{end}} {{end}}
    - {{if $file.IsRenamed}}{{$file.OldName}} → {{end}}{{$file.Name}}{{if .IsLFSFile}} ({{$.i18n.Tr "repo.stored_lfs"}}){{end}} -

    -
    - {{if $showFileViewToggle}} -
    - {{svg "octicon-code"}} - {{svg "octicon-file"}} -
    - {{end}} - {{if $file.IsProtected}} - {{$.i18n.Tr "repo.diff.protected"}} - {{end}} - {{if and (not $file.IsSubmodule) (not $.PageIsWiki)}} - {{if $file.IsDeleted}} - {{$.i18n.Tr "repo.diff.view_file"}} +

    +
    +
    + {{if or $file.IsIncomplete $file.IsBin}} +
    + {{if $file.IsIncomplete}} + {{if $file.IsIncompleteLineTooLong}} + {{$.i18n.Tr "repo.diff.file_suppressed_line_too_long"}} + {{else}} + {{$.i18n.Tr "repo.diff.file_suppressed"}} + {{end}} + {{else}} + {{$.i18n.Tr "repo.diff.bin_not_shown"}} + {{end}} +
    {{else}} - {{$.i18n.Tr "repo.diff.view_file"}} + + {{if $.IsSplitStyle}} + {{template "repo/diff/section_split" dict "file" . "root" $}} + {{else}} + {{template "repo/diff/section_unified" dict "file" . "root" $}} + {{end}} +
    {{end}} - {{end}} -
    - -
    -
    - {{if or $file.IsIncomplete $file.IsBin}} -
    - {{if $file.IsIncomplete}} - {{if $file.IsIncompleteLineTooLong}} - {{$.i18n.Tr "repo.diff.file_suppressed_line_too_long"}} +
    + {{if $showFileViewToggle}} +
    + + {{if $isImage}} + {{template "repo/diff/image_diff" dict "file" . "root" $ "blobBase" $blobBase "blobHead" $blobHead}} {{else}} - {{$.i18n.Tr "repo.diff.file_suppressed"}} + {{template "repo/diff/csv_diff" dict "file" . "root" $}} {{end}} - {{else}} - {{$.i18n.Tr "repo.diff.bin_not_shown"}} - {{end}} +
    - {{else}} - - {{if $.IsSplitStyle}} - {{template "repo/diff/section_split" dict "file" . "root" $}} - {{else}} - {{template "repo/diff/section_unified" dict "file" . "root" $}} - {{end}} -
    {{end}}
    - {{if $showFileViewToggle}} -
    - - {{if $isImage}} - {{template "repo/diff/image_diff" dict "file" . "root" $ "blobBase" $blobBase "blobHead" $blobHead}} - {{else}} - {{template "repo/diff/csv_diff" dict "file" . "root" $}} - {{end}} -
    -
    - {{end}}
    -
    - {{end}} + {{end}} - {{if .Diff.IsIncomplete}} -
    -

    - {{$.i18n.Tr "repo.diff.too_many_files"}} -

    -
    - {{end}} + {{if .Diff.IsIncomplete}} +
    +

    + {{$.i18n.Tr "repo.diff.too_many_files"}} + {{.i18n.Tr "repo.diff.show_more"}} +

    +
    + {{end}} +
    {{if not $.Repository.IsArchived}}
    diff --git a/web_src/js/index.js b/web_src/js/index.js index 7e4970c3a062b..3aabb2a0a4090 100644 --- a/web_src/js/index.js +++ b/web_src/js/index.js @@ -2839,6 +2839,7 @@ $(document).ready(async () => { initFileViewToggle(); initReleaseEditor(); initRelease(); + initDiffShowMore(); const routes = { 'div.user.settings': initUserSettings, @@ -3658,6 +3659,35 @@ function initFilterBranchTagDropdown(selector) { }); } +function initDiffShowMore() { + $('#diff-show-more-files, #diff-show-more-files-stats').on('click', (e) => { + e.preventDefault(); + + if ($(e.target).hasClass('disabled')) { + return; + } + $('#diff-show-more-files, #diff-show-more-files-stats').addClass('disabled'); + + const url = $('#diff-show-more-files, #diff-show-more-files-stats').data('href'); + $.ajax({ + type: 'GET', + url, + }).done((resp) => { + if (!resp || resp.html === '' || resp.empty) { + $('#diff-show-more-files, #diff-show-more-files-stats').removeClass('disabled'); + return; + } + $('#diff-too-many-files-stats').remove(); + $('#diff-files').append($(resp).find('#diff-files li')); + $('#diff-incomplete').replaceWith($(resp).find('#diff-file-boxes').children()); + + initDiffShowMore(); + }); + }); +} + + + $('.commit-button').on('click', function (e) { e.preventDefault(); $(this).parent().find('.commit-body').toggle(); From 0f4c2b1699b743a465c2f1f870f6fa7198ab5877 Mon Sep 17 00:00:00 2001 From: Andrew Thornton Date: Tue, 7 Sep 2021 21:34:15 +0100 Subject: [PATCH 2/8] as per silverwind Signed-off-by: Andrew Thornton --- templates/repo/diff/box.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/repo/diff/box.tmpl b/templates/repo/diff/box.tmpl index 59a4db1eafb8b..579453a5ab57c 100644 --- a/templates/repo/diff/box.tmpl +++ b/templates/repo/diff/box.tmpl @@ -44,7 +44,7 @@ {{end}} {{if .Diff.IsIncomplete}}
  • - {{$.i18n.Tr "repo.diff.too_many_files"}} + {{$.i18n.Tr "repo.diff.too_many_files"}} {{.i18n.Tr "repo.diff.show_more"}}
  • From 4c53b2f2fd1c76460d01bf9193dfe00566fc16ca Mon Sep 17 00:00:00 2001 From: Andrew Thornton Date: Thu, 9 Sep 2021 18:55:31 +0100 Subject: [PATCH 3/8] use delegated event handler Signed-off-by: Andrew Thornton --- web_src/js/features/diff.js | 24 ++++++++++++++++++++++++ web_src/js/index.js | 29 +---------------------------- 2 files changed, 25 insertions(+), 28 deletions(-) create mode 100644 web_src/js/features/diff.js diff --git a/web_src/js/features/diff.js b/web_src/js/features/diff.js new file mode 100644 index 0000000000000..ef0aaceeeb507 --- /dev/null +++ b/web_src/js/features/diff.js @@ -0,0 +1,24 @@ +export function initDiffShowMore() { + $('#diff-files, #diff-file-boxes').on('click', '#diff-show-more-files, #diff-show-more-files-stats', (e) => { + e.preventDefault(); + + if ($(e.target).hasClass('disabled')) { + return; + } + $('#diff-show-more-files, #diff-show-more-files-stats').addClass('disabled'); + + const url = $('#diff-show-more-files, #diff-show-more-files-stats').data('href'); + $.ajax({ + type: 'GET', + url, + }).done((resp) => { + if (!resp || resp.html === '' || resp.empty) { + $('#diff-show-more-files, #diff-show-more-files-stats').removeClass('disabled'); + return; + } + $('#diff-too-many-files-stats').remove(); + $('#diff-files').append($(resp).find('#diff-files li')); + $('#diff-incomplete').replaceWith($(resp).find('#diff-file-boxes').children()); + }); + }); +} diff --git a/web_src/js/index.js b/web_src/js/index.js index 631a38214a8ee..1a143fb69cd3e 100644 --- a/web_src/js/index.js +++ b/web_src/js/index.js @@ -21,6 +21,7 @@ import {createCodeEditor, createMonaco} from './features/codeeditor.js'; import {initMarkupAnchors} from './markup/anchors.js'; import {initNotificationsTable, initNotificationCount} from './features/notification.js'; import {initStopwatch} from './features/stopwatch.js'; +import {initDiffShowMore} from './features/diff.js'; import {showLineButton} from './code/linebutton.js'; import {initMarkupContent, initCommentContent} from './markup/content.js'; import {stripTags, mqBinarySearch} from './utils.js'; @@ -3680,34 +3681,6 @@ function initFilterBranchTagDropdown(selector) { }); } -function initDiffShowMore() { - $('#diff-show-more-files, #diff-show-more-files-stats').on('click', (e) => { - e.preventDefault(); - - if ($(e.target).hasClass('disabled')) { - return; - } - $('#diff-show-more-files, #diff-show-more-files-stats').addClass('disabled'); - - const url = $('#diff-show-more-files, #diff-show-more-files-stats').data('href'); - $.ajax({ - type: 'GET', - url, - }).done((resp) => { - if (!resp || resp.html === '' || resp.empty) { - $('#diff-show-more-files, #diff-show-more-files-stats').removeClass('disabled'); - return; - } - $('#diff-too-many-files-stats').remove(); - $('#diff-files').append($(resp).find('#diff-files li')); - $('#diff-incomplete').replaceWith($(resp).find('#diff-file-boxes').children()); - - initDiffShowMore(); - }); - }); -} - - $('.commit-button').on('click', function (e) { e.preventDefault(); From 13efa69ed68f183fdd1f46ec3cf845f625e4a5eb Mon Sep 17 00:00:00 2001 From: zeripath Date: Thu, 9 Sep 2021 18:56:24 +0100 Subject: [PATCH 4/8] Update web_src/js/index.js --- web_src/js/index.js | 1 - 1 file changed, 1 deletion(-) diff --git a/web_src/js/index.js b/web_src/js/index.js index 1a143fb69cd3e..6f50576c1c3b6 100644 --- a/web_src/js/index.js +++ b/web_src/js/index.js @@ -3681,7 +3681,6 @@ function initFilterBranchTagDropdown(selector) { }); } - $('.commit-button').on('click', function (e) { e.preventDefault(); $(this).parent().find('.commit-body').toggle(); From bc38da2feffa633cfb55da69c1bf6bdbce235913 Mon Sep 17 00:00:00 2001 From: Andrew Thornton Date: Thu, 9 Sep 2021 21:50:21 +0100 Subject: [PATCH 5/8] Re-add back in statuses which appear to have been removed by mistake Signed-off-by: Andrew Thornton --- routers/web/repo/commit.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/routers/web/repo/commit.go b/routers/web/repo/commit.go index 801810eb12193..91913200e6893 100644 --- a/routers/web/repo/commit.go +++ b/routers/web/repo/commit.go @@ -331,6 +331,14 @@ func Diff(ctx *context.Context) { return } + statuses, err := models.GetLatestCommitStatus(ctx.Repo.Repository.ID, commitID, models.ListOptions{}) + if err != nil { + log.Error("GetLatestCommitStatus: %v", err) + } + + ctx.Data["CommitStatus"] = models.CalcCommitStatus(statuses) + ctx.Data["CommitStatuses"] = statuses + verification := models.ParseCommitWithSignature(commit) ctx.Data["Verification"] = verification ctx.Data["Author"] = models.ValidateCommitWithEmail(commit) From a13c4dc32a97564210b1bb72fa800499b9326b99 Mon Sep 17 00:00:00 2001 From: zeripath Date: Tue, 14 Sep 2021 13:39:38 +0100 Subject: [PATCH 6/8] oops Co-authored-by: Norwin --- routers/web/repo/compare.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routers/web/repo/compare.go b/routers/web/repo/compare.go index c599793239b2b..4e92652220e9c 100644 --- a/routers/web/repo/compare.go +++ b/routers/web/repo/compare.go @@ -415,7 +415,7 @@ func ParseCompareInfo(ctx *context.Context) (*models.User, *models.Repository, * ctx.ServerError("GetUserRepoPermission", err) return nil, nil, nil, nil, "", "" } - if !perm.CanRead(models.UnitTypeCode) { + if perm.CanRead(models.UnitTypeCode) { ctx.Data["RootRepo"] = rootRepo } } From 434d1d34a53ba9ca3d23b9a556d580653f21b18f Mon Sep 17 00:00:00 2001 From: zeripath Date: Tue, 14 Sep 2021 13:40:10 +0100 Subject: [PATCH 7/8] Update routers/web/repo/compare.go --- routers/web/repo/compare.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routers/web/repo/compare.go b/routers/web/repo/compare.go index 4e92652220e9c..5493a7847ac61 100644 --- a/routers/web/repo/compare.go +++ b/routers/web/repo/compare.go @@ -447,7 +447,7 @@ func ParseCompareInfo(ctx *context.Context) (*models.User, *models.Repository, * ctx.ServerError("GetUserRepoPermission", err) return nil, nil, nil, nil, "", "" } - if !perm.CanRead(models.UnitTypeCode) { + if perm.CanRead(models.UnitTypeCode) { ctx.Data["RootRepo"] = rootRepo } } From 0d97cab92e08818537f4fc1b20d55ae2c1505f26 Mon Sep 17 00:00:00 2001 From: Andrew Thornton Date: Mon, 27 Sep 2021 15:46:18 +0100 Subject: [PATCH 8/8] as per wxiaoguang Signed-off-by: Andrew Thornton --- routers/web/repo/compare.go | 74 +++++++++++++------------------------ 1 file changed, 26 insertions(+), 48 deletions(-) diff --git a/routers/web/repo/compare.go b/routers/web/repo/compare.go index 1f1f92b582e11..1ad898df6c8be 100644 --- a/routers/web/repo/compare.go +++ b/routers/web/repo/compare.go @@ -414,26 +414,19 @@ func ParseCompareInfo(ctx *context.Context) *CompareInfo { if rootRepo != nil && rootRepo.ID != ci.HeadRepo.ID && rootRepo.ID != baseRepo.ID { - if !fileOnly { - perm, branches, tags, err := getBranchesAndTagsForRepo(ctx.User, rootRepo) - if err != nil { - ctx.ServerError("GetBranchesForRepo", err) - return nil - } - if perm { - ctx.Data["RootRepo"] = rootRepo + canRead := rootRepo.CheckUnitUser(ctx.User, models.UnitTypeCode) + if canRead { + ctx.Data["RootRepo"] = rootRepo + if !fileOnly { + branches, tags, err := getBranchesAndTagsForRepo(ctx.User, rootRepo) + if err != nil { + ctx.ServerError("GetBranchesForRepo", err) + return nil + } + ctx.Data["RootRepoBranches"] = branches ctx.Data["RootRepoTags"] = tags } - } else { - perm, err := models.GetUserRepoPermission(rootRepo, ctx.User) - if err != nil { - ctx.ServerError("GetUserRepoPermission", err) - return nil - } - if perm.CanRead(models.UnitTypeCode) { - ctx.Data["RootRepo"] = rootRepo - } } } @@ -446,26 +439,18 @@ func ParseCompareInfo(ctx *context.Context) *CompareInfo { ownForkRepo.ID != ci.HeadRepo.ID && ownForkRepo.ID != baseRepo.ID && (rootRepo == nil || ownForkRepo.ID != rootRepo.ID) { - if !fileOnly { - perm, branches, tags, err := getBranchesAndTagsForRepo(ctx.User, ownForkRepo) - if err != nil { - ctx.ServerError("GetBranchesForRepo", err) - return nil - } - if perm { - ctx.Data["OwnForkRepo"] = ownForkRepo + canRead := ownForkRepo.CheckUnitUser(ctx.User, models.UnitTypeCode) + if canRead { + ctx.Data["OwnForkRepo"] = ownForkRepo + if !fileOnly { + branches, tags, err := getBranchesAndTagsForRepo(ctx.User, ownForkRepo) + if err != nil { + ctx.ServerError("GetBranchesForRepo", err) + return nil + } ctx.Data["OwnForkRepoBranches"] = branches ctx.Data["OwnForkRepoTags"] = tags } - } else { - perm, err := models.GetUserRepoPermission(ownForkRepo, ctx.User) - if err != nil { - ctx.ServerError("GetUserRepoPermission", err) - return nil - } - if perm.CanRead(models.UnitTypeCode) { - ctx.Data["OwnForkRepo"] = ownForkRepo - } } } @@ -631,29 +616,22 @@ func PrepareCompareDiff( return false } -func getBranchesAndTagsForRepo(user *models.User, repo *models.Repository) (bool, []string, []string, error) { - perm, err := models.GetUserRepoPermission(repo, user) - if err != nil { - return false, nil, nil, err - } - if !perm.CanRead(models.UnitTypeCode) { - return false, nil, nil, nil - } +func getBranchesAndTagsForRepo(user *models.User, repo *models.Repository) (branches, tags []string, err error) { gitRepo, err := git.OpenRepository(repo.RepoPath()) if err != nil { - return false, nil, nil, err + return nil, nil, err } defer gitRepo.Close() - branches, _, err := gitRepo.GetBranches(0, 0) + branches, _, err = gitRepo.GetBranches(0, 0) if err != nil { - return false, nil, nil, err + return nil, nil, err } - tags, err := gitRepo.GetTags(0, 0) + tags, err = gitRepo.GetTags(0, 0) if err != nil { - return false, nil, nil, err + return nil, nil, err } - return true, branches, tags, nil + return branches, tags, nil } // CompareDiff show different from one commit to another commit