repack: pack objects mentioned by the index
commitc90f9e13abae630551ada3e895633bdc2cf4e080
authorJeff King <peff@peff.net>
Fri, 17 Oct 2014 00:44:49 +0000 (16 20:44 -0400)
committerJunio C Hamano <gitster@pobox.com>
Sun, 19 Oct 2014 22:07:07 +0000 (19 15:07 -0700)
tree5f67d239fa22862022aff569f0699c9b79629ba1
parentedfbb2aa538148b38ee0ba6d62c95b7edda5d817
repack: pack objects mentioned by the index

When we pack all objects, we use only the objects reachable
from references and reflogs. This misses any objects which
are reachable from the index, but not yet referenced.

By itself this isn't a big deal; the objects can remain
loose until they are actually used in a commit. However, it
does create a problem when we drop packed but unreachable
objects. We try to optimize out the writing of objects that
we will immediately prune, which means we must follow the
same rules as prune in determining what is reachable. And
prune uses the index for this purpose.

This is rather uncommon in practice, as objects in the index
would not usually have been packed in the first place. But
it could happen in a sequence like:

  1. You make a commit on a branch that references blob X.

  2. You repack, moving X into the pack.

  3. You delete the branch (and its reflog), so that X is
     unreferenced.

  4. You "git add" blob X so that it is now referenced only
     by the index.

  5. You repack again with git-gc. The pack-objects we
     invoke will see that X is neither referenced nor
     recent and not bother loosening it.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/pack-objects.c
builtin/repack.c
t/t7701-repack-unpack-unreachable.sh