Hi Jeff, Thank you for the detailed explanation. It explains perfectly why skipping the git-gc for the mirror in the reproducer fixes the problem. But one thing is still confusing and inconsistent IMO - why using local path for clone still works (even with the git-gc in both master and mirror which removes the obsoleted commit object) while it should not (based on your explanation and the "git help clone" snippet you provided) Could you please clarify? Thanks, Oleg. Steps: $ cat doit #!/bin/sh set -xe rm -rf tst mkdir tst cd tst mkdir master git -C master init --bare git clone master local touch local/foo git -C local add . git -C local commit -m init-commit git -C local push echo foo > local/foo git -C local commit -a -m dummy-commit rev=`git -C local log -1 --format=%h` git -C local push origin HEAD:refs/heads/dummy git clone --mirror file://`pwd`/master mirror git clone --reference `pwd`/mirror `pwd`/master local1 git -C local1 log --oneline origin/dummy git -C local commit --amend -m new-dummy-commit git -C local push -f origin HEAD:dummy git -C local log --oneline origin/dummy git -C mirror fetch git -C mirror gc --prune=now git -C mirror log -1 --oneline $rev -- || echo FAIL git -C master gc --prune=now git -C master log -1 --oneline $rev -- || echo FAIL git -C local1 fetch #git -C local1 remote update --prune git -C local1 log --oneline origin/dummy Tail of the script execution output: + git -C mirror fetch remote: Enumerating objects: 5, done. remote: Counting objects: 100% (5/5), done. remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 Unpacking objects: 100% (3/3), 230 bytes | 230.00 KiB/s, done.