Skip to content

fix: scope LFS diff detection to repository - #39059

Draft
Harsh-128 wants to merge 3 commits into
go-gitea:mainfrom
Harsh-128:fix/lfs-diff-repository-scope
Draft

fix: scope LFS diff detection to repository#39059
Harsh-128 wants to merge 3 commits into
go-gitea:mainfrom
Harsh-128:fix/lfs-diff-repository-scope

Conversation

@Harsh-128

Copy link
Copy Markdown

Fixes #39020.

Git LFS pointers were previously detected by OID without considering the repository they belonged to. This could cause an LFS file in a pull request to be displayed as plaintext when the same OID existed in another repository.

This change passes the repository ID through the pull request diff path and scopes the LFS metadata lookup to that repository.

Added a regression test covering:

  • an LFS OID belonging to another repository
  • an LFS OID belonging to the current repository

Tests:

  • go test ./services/gitdiff
  • go test ./routers/web/repo ./routers/api/v1/repo ./services/gitdiff ./services/repository/files
  • git diff --check

@GiteaBot GiteaBot added the lgtm/need 2 This PR needs two approvals by maintainers to be considered for merging. label Aug 23, 2026

@wxiaoguang wxiaoguang left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see how this PR "fixes" the problem.

The new logic is just stricter than the old one, the root logic is still unclear.


Could you clarify how the bug #39020 happens? Why you need to query the LFS meta by repo ID? No matter whether a LFS object can or can't be accessed by viewer, LFS pointer is LFS pointer.

@GiteaBot GiteaBot added lgtm/blocked A maintainer has reservations with the PR and thus it cannot be merged and removed lgtm/need 2 This PR needs two approvals by maintainers to be considered for merging. labels Aug 23, 2026
@wxiaoguang
wxiaoguang marked this pull request as draft August 23, 2026 13:39
@Harsh-128

Copy link
Copy Markdown
Author

Thanks for pointing that out. I understand your concern. My current change mainly makes the LFS lookup stricter, but I haven't clearly established that this is the actual root cause of #39020.

I'll investigate the difference between the PR diff path and the repository file view to understand why the same LFS pointer is being displayed differently. I'll update the PR once I have a clearer understanding of the root cause.

@Harsh-128

Copy link
Copy Markdown
Author

Thanks, I looked into this more. The issue is not about whether the viewer can access the LFS object. The problem is that the old diff logic only checked whether the OID existed anywhere in the LFS metadata table.

Since the LFS metadata is associated with a repository, an OID belonging to another repository could make a pointer in the current repository's diff get treated as an LFS file.

GetLFSMetaObjectByOid() already checks both the repository ID and OID, and the existing PR LFS handling also uses the repository ID. So this change passes the repository ID through the PR diff path and uses the repository-scoped lookup.

I also added a regression test covering both cases: the OID belonging to another repository and the OID belonging to the current repository.

@wxiaoguang

Copy link
Copy Markdown
Contributor

Since the LFS metadata is associated with a repository, an OID belonging to another repository could make a pointer in the current repository's diff get treated as an LFS file.

Then, why the viewer is viewing "an OID belonging to another repository"? Why current repo doesn't own the LFS object?

@Harsh-128

Copy link
Copy Markdown
Author

You're right. I looked into the PR diff flow more closely. For a fork PR, the diff is generated using the base repository's Git repo, while the head ref points to the PR's head commits. So the diff can contain an LFS pointer whose metadata belongs to the head repository rather than the base repository.

The old lookup only checked whether the OID existed anywhere in lfs_meta_object, so that pointer could incorrectly be classified as an LFS file. The change makes the lookup repository-scoped by checking both repository_id and oid.

I'll add/verify a regression test that specifically covers this fork PR scenario.

@wxiaoguang

This comment was marked as outdated.

@Harsh-128

Copy link
Copy Markdown
Author

I looked into the fork PR flow more closely and found that the diff is generated using the base repository's Git repo, while the PR's head commit comes from the head repository. Because of this, the LFS pointer in the diff can belong to the head repository.
I updated the LFS lookup to use the PR's HeadRepoID instead of the base repository. I also added a regression test for the repository-scoped lookup and verified the relevant tests are passing.

@wxiaoguang

wxiaoguang commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Which approach is right?

  • Only allow one repo to read the LFS object (only either base or head)
  • Allow both repos to read the LFS object (both base and head)

@Harsh-128

Copy link
Copy Markdown
Author

I think allowing both the base and head repositories makes more sense. The LFS lookup should stay scoped to the repositories involved in the PR, while avoiding a global OID lookup. This should cover both same-repository and fork PRs without allowing an unrelated repository to affect the detection.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

lgtm/blocked A maintainer has reservations with the PR and thus it cannot be merged type/bug

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Git LFS files are sometimes shown with their reference file as plaintext

3 participants