Re: Git gc removes all packs
From: Jeff King <hidden>
Date: 2016-06-15 23:03:50
On Tue, Feb 17, 2015 at 05:39:27PM +0100, Michael Haggerty wrote:
quoted
You can't symlink refs like this. The loose refs in the filesystem may be migrated into the "packed-refs" file, at which point your symlink will be broken. That is a likely reason why git would not find any refs. So your setup will not ever work reliably. But IMHO, it is a bug that git does not notice the broken symlink and abort an operation which is computing reachability in order to drop objects. As you noticed, it means a misconfiguration or filesystem error results in data loss.There's a bunch of code in refs.c that is there explicitly for reading loose references that are symlinks. If the link contents literally start with "refs/", then they are read and treated as a symbolic ref. Otherwise, the symlink is just followed.
Right, but we should be able to notice that: 1. We found a symlink. 2. We couldn't read it its ref value (because it's a broken link). I think we _do_ notice that at the lowest level, and set REF_ISBROKEN. But the problem is that the reachability code in prune and in pack-objects (triggered by "repack -ad") uses for_each_ref, and not for_each_rawref. So they ignore "broken" refs rather than complaining, even though failing to read a ref may mean we could drop objects which were only mentioned by that ref.
It is still possible to write symbolic refs that are represented as symlinks (see core.preferSymlinkRefs), but that backwards-compatibility code was added in 2006(!) Maybe it's time to deprecate it. And maybe we should start working towards a future where any symlinks under "refs" cause git to complain.
I wouldn't mind seeing all of the symlink code go away, but I think it is orthogonal to the problem I mentioned. -Peff