From 8661818123c08925dc16c97684259c004e7058ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Ri=C3=9Fe?= Date: Thu, 16 Jan 2025 18:49:09 +0100 Subject: [PATCH] Use annexed content for comparison in diffs This makes it such that annexed files are treated like plain git files in comparisons (e.g. the diff of a commit). It also changes the image diff viewer to show a more reasonable error message when one of the annexed files under comparison is missing. --- modules/annex/annex.go | 12 ++++++++++++ routers/web/repo/compare.go | 27 +++++++++++++++++++++------ web_src/js/features/imagediff.js | 12 +++++++++++- 3 files changed, 44 insertions(+), 7 deletions(-) diff --git a/modules/annex/annex.go b/modules/annex/annex.go index 9a70612a1e..dee24d21bc 100644 --- a/modules/annex/annex.go +++ b/modules/annex/annex.go @@ -22,6 +22,7 @@ import ( "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/typesniffer" ) // ErrBlobIsNotAnnexed occurs if a blob does not contain a valid annex key @@ -178,3 +179,14 @@ func UUID2RepoPath(uuid string) (string, error) { // Otherwise just return the cached entry return repoPath, nil } + +// GuessContentType guesses the content type of the annexed blob. +func GuessContentType(blob *git.Blob) (typesniffer.SniffedType, error) { + r, err := Content(blob) + if err != nil { + return typesniffer.SniffedType{}, err + } + defer r.Close() + + return typesniffer.DetectContentTypeFromReader(r) +} diff --git a/routers/web/repo/compare.go b/routers/web/repo/compare.go index 03d49fa692..104655e134 100644 --- a/routers/web/repo/compare.go +++ b/routers/web/repo/compare.go @@ -23,6 +23,7 @@ import ( repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" + "code.gitea.io/gitea/modules/annex" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/charset" csv_module "code.gitea.io/gitea/modules/csv" @@ -72,7 +73,21 @@ func setCompareContext(ctx *context.Context, before, head *git.Commit, headOwner return st } - st, err := blob.GuessContentType() + isAnnexed, err := annex.IsAnnexed(blob) + if err != nil { + log.Error("IsAnnexed failed: %v", err) + return st + } + if isAnnexed { + st, err = annex.GuessContentType(blob) + if err != nil { + log.Error("GuessContentType failed: %v", err) + return st + } + return st + } + + st, err = blob.GuessContentType() if err != nil { log.Error("GuessContentType failed: %v", err) return st @@ -90,18 +105,18 @@ func SourceCommitURL(owner, name string, commit *git.Commit) string { return setting.AppSubURL + "/" + url.PathEscape(owner) + "/" + url.PathEscape(name) + "/src/commit/" + url.PathEscape(commit.ID.String()) } -// RawCommitURL creates a relative URL for the raw commit in the given repository -func RawCommitURL(owner, name string, commit *git.Commit) string { - return setting.AppSubURL + "/" + url.PathEscape(owner) + "/" + url.PathEscape(name) + "/raw/commit/" + url.PathEscape(commit.ID.String()) +// MediaCommitURL creates a relative URL for the commit media (plain git, LFS, or annex content) in the given repository +func MediaCommitURL(owner, name string, commit *git.Commit) string { + return setting.AppSubURL + "/" + url.PathEscape(owner) + "/" + url.PathEscape(name) + "/media/commit/" + url.PathEscape(commit.ID.String()) } // setPathsCompareContext sets context data for source and raw paths func setPathsCompareContext(ctx *context.Context, base, head *git.Commit, headOwner, headName string) { ctx.Data["SourcePath"] = SourceCommitURL(headOwner, headName, head) - ctx.Data["RawPath"] = RawCommitURL(headOwner, headName, head) + ctx.Data["RawPath"] = MediaCommitURL(headOwner, headName, head) if base != nil { ctx.Data["BeforeSourcePath"] = SourceCommitURL(headOwner, headName, base) - ctx.Data["BeforeRawPath"] = RawCommitURL(headOwner, headName, base) + ctx.Data["BeforeRawPath"] = MediaCommitURL(headOwner, headName, base) } } diff --git a/web_src/js/features/imagediff.js b/web_src/js/features/imagediff.js index d1b139ffde..52c9017b07 100644 --- a/web_src/js/features/imagediff.js +++ b/web_src/js/features/imagediff.js @@ -92,7 +92,17 @@ export function initImageDiff() { return loadElem(img, info.path); })); // only the first images is associated with $boundsInfo - if (!success) info.$boundsInfo.text('(image error)'); + if (!success) { + const blobContent = await GET(info.path.replace('/media/', '/raw/')).then((response) => response.text()); + if (blobContent.startsWith('.git/annex/objects')) { + for (const item of document.querySelectorAll('.image-diff .overflow-menu-items .item')) { + item.style.display = 'none'; + } + info.$boundsInfo[0].parentElement.textContent = 'annexed file is not present on the server'; + } else { + info.$boundsInfo.text('(image error)'); + } + } if (info.mime === 'image/svg+xml') { const resp = await GET(info.path); const text = await resp.text();