LFS objects become invalid if cherry-picked
Everyone can contribute. Help move this issue forward while earning points, leveling up and collecting rewards.
Summary
After completing a Merge Request (via cherry-pick) containing LFS objects, the upstream repository won't properly integrate the LFS objects, corrupting it.
Steps to reproduce
1st: creating the upstream repository
- Create a brand new repository on GitLab
- Clone it locally (I used SSH)
- Add LFS support for a file extension (e.g.,
git lfs track *.txt
) - Commit that
- Create a new file with that extension with some random content (e.g.,
echo "awesome" > test.txt
) - Commit and push all that
2nd: forking
- Fork the upstream repository from GitLab's UI to a private namespace (I haven't tested with publics)
- Clone the fork locally, not re-using the upstream repository (i.e., you need a local copy for each) (still using SSH)
- Edit the LFS-tracked file (e.g.,
echo "really awesome" > test.txt
) - Commit and push all that
3rd: cherry-picking
- On GitLab's UI, go to the fork
- Navigate to the newest commit's URL (
/<proj>/-/commit/<hash>
) - From the top right "Options" button, select "Cherry-pick"
- Select the upstream project as target and proceed
- Proceed with the Merge Request, leaving all defaults, until the Merge Request is complete and successful (everything should be normal here)
4th: the problem
- On the upstream repository local clone, run a
git pull
. This will fail with the following error:
Error downloading object: test.txt (ac57b64): Smudge error: Error downloading test.txt (ac57b647d07cc3a5a43b954cf81237f1bad29ace6afdebdb90497ae4ceb2450c): [ac57b647d07cc3a5a43b954cf81237f1bad29ace6afdebdb90497ae4ceb2450c] Object does not exist on the server or you don't have permissions to access it: [404] Object does not exist on the server or you don't have permissions to access it
Example Project
https://gitlab.com/test-lfs-mr/test-lfs
You can simply try cloning this repository, and it will fail. The fork repository (from which the cherry-pick comes from) isn't public, but it's below:
https://gitlab.com/brifsttar/test-lfs
What is the current bug behavior?
Git LFS cannot download the objects on the upstream repository, rendering the branch unusable and corrupted.
Strangely enough, GitLab's UI displays the correct and valid version of the LFS file on the upstream repository. Only the Git client fails to download it (example here: https://gitlab.com/test-lfs-mr/test-lfs/-/blob/main/awesome.txt)
What is the expected correct behavior?
Git LFS should be able to download the objects, and the branch should be accessible to end-users.
Relevant logs and/or screenshots
$ git clone git@gitlab.com:test-lfs-mr/test-lfs.git test
Cloning into 'test'...
remote: Enumerating objects: 10, done.
Receiving objects: 100% (10/10), done.
Resolving deltas: 100% (2/2), done.
Downloading awesome.txt (16 B)
Error downloading object: awesome.txt (ac57b64): Smudge error: Error downloading awesome.txt (ac57b647d07cc3a5a43b954cf81237f1bad29ace6afdebdb90497ae4ceb2450c): [ac57b647d07cc3a5a43b954cf81237f1bad29ace6afdebdb90497ae4ceb2450c] Object does not exist on the server or you don't have permissions to access it: [404] Object does not exist on the server or you don't have permissions to access it
Errors logged to 'D:\dev\tmp\test\.git\lfs\logs\20250319T084117.9201971.log'. Use `git lfs logs last` to view the log.
error: external filter 'git-lfs filter-process' failed
fatal: awesome.txt: smudge filter lfs failed
warning: Clone succeeded, but checkout failed.
You can inspect what was checked out with 'git status'
and retry with 'git restore --source=HEAD :/'
Output of checks
This bug happens on GitLab.com
Possible fixes
If you have access to the fork repository, there's a workaround (definitely not a fix). Locally, if you add the forked repository as a secondary remote on the upstream repository clone (git remote add fork <...>
), and properly configure LFS URL (git config lfs.searchall 1
, git config remote.<...>.lfsurl
, etc.), it will solve the issue. This leads me to think that the LFS objects aren't properly copied to the upstream repository, but instead only stay on the fork. If the fork isn't accessible locally, it raises the permission error.
Once you manage to get the LFS objects locally, you can push them on the server by rewriting the history (git rebase -i
) from before the cherry-pick and push that, which will force LFS objects to be reuploaded (there may be easier ways to do that). Once this is done, the LFS objects appear valid, and the issue is then solved for all users (even on the original/non-rebased branch).