Note that a shallow repo (like one with git clone --depth 1
as a way to convert an existing repo to a shallow one) can fail on git repack
.
See commit 5dcfbf5, commit 2588f6e, commit 328a435 (24 Oct 2018) by Johannes Schindelin (dscho
).
(Merged by Junio C Hamano -- gitster
-- in commit ea100b6, 06 Nov 2018)
repack -ad
: prune the list of shallow commits
git repack
can drop unreachable commits without further warning,
making the corresponding entries in .git/shallow
invalid, which causes
serious problems when deepening the branches.
One scenario where unreachable commits are dropped by git repack
is
when a git fetch --prune
(or even a git fetch
when a ref was
force-pushed in the meantime) can make a commit unreachable that was
reachable before.
Therefore it is not safe to assume that a git repack -adlf
will keep unreachable commits alone (under the assumption that they had not been packed in the first place, which is an assumption at least some of Git's code seems to make).
This is particularly important to keep in mind when looking at the
.git/shallow
file: if any commits listed in that file become
unreachable, it is not a problem, but if they go missing, it is a
problem.
One symptom of this problem is that a deepening fetch may now
fail with:
fatal: error in object: unshallow <commit-hash>
To avoid this problem, let's prune the shallow list in git repack
when the -d
option is passed, unless -A
is passed, too (which would force the now-unreachable objects to be turned into loose objects instead of being deleted).
Additionally, we also need to take --keep-reachable
and --unpack-unreachable=<date>
into account.
Note: an alternative solution discussed during the review of this patch
was to teach git fetch
to simply ignore entries in .git/shallow
if the
corresponding commits do not exist locally.
A quick test, however, revealed that the .git/shallow
file is written during a shallow clone, in which case the commits do not exist, either, but the "shallow" line
does need to be sent.
Therefore, this approach would be a lot more finicky than the approach presented by the this patch.
git gc
after your repack? – Miramirabeaugit commit-tree
. – Ji