-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Description
Describe the bug
Running git lfs migrate import errors when .git/objects is a symlink.
To Reproduce
Steps to reproduce the behavior:
# create a sandbox repo
mkdir -p sandbox/repo
cd sandbox/repo
git init --initial-branch=main
# make a commit
echo abc >> foo
git add .
git commit -m 'initial'
# copy objects folder to sandbox/ and symlink to it inside .git/
cp -r .git/objects ..
rm -rf .git/objects
ln -s ../../objects .git/objects
# try to migrate, observe error
git lfs migrate import --everythingError in `git rev-list --reverse --topo-order --do-walk --stdin --`: exit status 128 fatal: not a git repository (or any parent up to mount point /)
Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).
System environment
Fedora 40
Additional context
The reason that this error occurs is clear: git-rev-list is executed from inside the objects/ directory, but this doesn't work if objects/ is not in .git/:
git-lfs/git/rev_list_scanner.go
Lines 175 to 177 in d5db3c8
| if len(opt.WorkingDir) > 0 { | |
| cmd.Dir = opt.WorkingDir | |
| } |
However, even if you remove this conditional such that rev-list is executed inside the cwd and thus succeeds, git lfs migrate import still doesn't work. No history is rewritten; it appears to be a no-op. You can observe this by doing the following, after hacking out the conditional logic to fix the rev-list error:
rm -rf .git/objects
cp -r ../objects .git/
git lfs migrate import --everything
git reset --hard HEAD@{1}
rm -rf .git/objects
ln -s ../../objects .git/
git lfs migrate import --everythingThe outputs will look something like
Sorting commits: ..., done.
Rewriting commits: 100% (1/1), done.
main da0d9adcb169cc66ebd8f2d82d3c39a80495295d -> da62d0d420c23399dfaadc9ff63687c9926fb59f
Updating refs: ..., done.
Checkout: ..., done.
Sorting commits: ..., done.
Rewriting commits: 100% (1/1), done.
Updating refs: ..., done.
Checkout: ..., done.
The first case (no symlink), the history is rewritten. The second case (with symlink), nothing happens.
If you're wondering what the reason could be for having .git/objects/ symlinked, it's because that's how Google's git-repo tool sets up the working directories for an AOSP checkout. LFS users working on AOSP projects don't have much choice in this matter.