From 9a6d0d90bf0b1aae423cdd73280f9445b1f0b442 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Sat, 12 Sep 2026 11:16:22 +0000 Subject: [PATCH] docs(lfs): document the sha the contents API expects for LFS files (#542) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes #243. The `sha` of the contents API is compared against the ID of the blob the commit has at that path, and for a file tracked by Git LFS that blob is the pointer file. Sending the `lfs_oid` or a checksum of the file content fails with `sha does not match`, and nothing in the documentation said so. Adds a section to the LFS page: use the `sha` from `GET /repos/{owner}/{repo}/contents/{filepath}`, not `lfs_oid`, and note that the API does turn the content into an LFS object by itself when `.gitattributes` tracks the path (`modifyFile()` stores the object and commits the pointer), so nothing else has to be done differently. The swagger comments upstream are being fixed in https://github.com/go-gitea/gitea/pull/38915, which will reach `/api/next/` through the scheduled job and the released reference with 1.28. The documents of 1.22 – 1.27 are frozen, so the guide is the only place where readers of the current release can find it. Preview: https://pr-542.docs-gitea-com.pages.dev Reviewed-on: https://gitea.com/gitea/docs/pulls/542 Reviewed-by: bircni Co-authored-by: Lunny Xiao --- docs/administration/git-lfs-support.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/docs/administration/git-lfs-support.md b/docs/administration/git-lfs-support.md index 4a390721..c26e9527 100644 --- a/docs/administration/git-lfs-support.md +++ b/docs/administration/git-lfs-support.md @@ -41,3 +41,24 @@ client that causes SSH transfers to hang: https://github.com/git-lfs/git-lfs/pul This can be worked around on all the client machines by setting the git config: `git config --global lfs.ssh.automultiplex false` ::: + +# Changing LFS files through the API + +The [contents API](https://docs.gitea.com/api/operations/repo-change-files/) +works on LFS tracked files as well: send the file content as usual and Gitea +stores it as an LFS object and commits a pointer file, as long as the path is +matched by a `filter=lfs` rule in `.gitattributes`. + +What is easy to get wrong is the `sha` of the file being changed, which +`PUT`/`DELETE /repos/{owner}/{repo}/contents/{filepath}` and +`POST /repos/{owner}/{repo}/contents` require for an existing file. Gitea +compares it with the ID of the blob the commit has at that path, and for an LFS +tracked file that blob is the **pointer file**, not the content: + +- use the `sha` returned by + [`GET /repos/{owner}/{repo}/contents/{filepath}`](https://docs.gitea.com/api/operations/repo-get-contents/) +- do not use `lfs_oid` from the same response, which identifies the LFS object, + and do not use a checksum of the file itself + +Sending anything else fails with `sha does not match`, even though the request +looks correct.