I'm working on a git course and wanted to mention that lost refs are not really lost until running git gc
. But verifying this, I found out that this is not the case. Even after running git gc --prune=all --aggressive
the lost refs are still there.
Clearly I misunderstood something. And before saying something incorrect in the course, I want to get my facts straight! Here is an example script illustrates the effect:
#!/bin/bash
git init
# add 10 dummy commits
for i in {1..10}; do
date > foo.txt
git add foo.txt
git commit -m "bump" foo.txt
sleep 1
done;
CURRENT=$(git rev-parse HEAD)
echo HEAD before reset: ${CURRENT}
# rewind
git reset --hard HEAD~5
# add another 10 commits
for i in {1..10}; do
date > foo.txt
git add foo.txt
git commit -m "bump" foo.txt
sleep 1
done;
This script will add 10 dummy commits, reset to 5 commits in the past and add another 10 commits. Just before resetting, it will print the hash of it's current HEAD.
I would expect to lose the object in CURRENT
after running git gc --prune=all
. Yet, I can still run git show
on that hash.
I do understand that after running git reset
and adding new commits, I have essentially created a new branch. But my original branch no longer has any reference, so it does not show up in git log --all
. It also would not be pushed to any remote I suppose.
My understanding of git gc
was that is removes those objects. This does not seem to be the case.
Why? And when exactly does git gc
remove objects?