diff options
author | Brandon Casey <drafnel@gmail.com> | 2009-03-21 17:26:11 -0500 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2009-03-21 21:58:44 -0700 |
commit | 094085e3362c592c932b41525ed37152ec171192 (patch) | |
tree | e67eb0f1ca5716848e866c25e4a96464a46ad1a9 /builtin-pack-objects.c | |
parent | t7700: demonstrate repack flaw which may loosen objects unnecessarily (diff) | |
download | tgif-094085e3362c592c932b41525ed37152ec171192.tar.xz |
pack-objects: don't loosen objects available in alternate or kept packs
If pack-objects is called with the --unpack-unreachable option then it
will unpack (i.e. loosen) all unreferenced objects from local not-kept
packs, including those that also exist in packs residing in an alternate
object database or a locally kept pack. The only user of this option is
git-repack.
In this case, repack will follow the call to pack-objects with a call to
prune-packed, which will delete these newly loosened objects, making the
act of loosening a waste of time. The unnecessary loosening can be
avoided by checking whether an object exists in a non-local pack or a
locally kept pack before loosening it.
This fixes the 'local packed unreachable obs that exist in alternate ODB
are not loosened' test in t7700.
Signed-off-by: Brandon Casey <drafnel@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'builtin-pack-objects.c')
-rw-r--r-- | builtin-pack-objects.c | 26 |
1 files changed, 25 insertions, 1 deletions
diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c index 6222f19c78..ad3f8e7751 100644 --- a/builtin-pack-objects.c +++ b/builtin-pack-objects.c @@ -1944,6 +1944,29 @@ static void add_objects_in_unpacked_packs(struct rev_info *revs) free(in_pack.array); } +static int has_sha1_pack_kept_or_nonlocal(const unsigned char *sha1) +{ + static struct packed_git *last_found = (void *)1; + struct packed_git *p; + + p = (last_found != (void *)1) ? last_found : packed_git; + + while (p) { + if ((!p->pack_local || p->pack_keep) && + find_pack_entry_one(sha1, p)) { + last_found = p; + return 1; + } + if (p == last_found) + p = packed_git; + else + p = p->next; + if (p == last_found) + p = p->next; + } + return 0; +} + static void loosen_unused_packed_objects(struct rev_info *revs) { struct packed_git *p; @@ -1959,7 +1982,8 @@ static void loosen_unused_packed_objects(struct rev_info *revs) for (i = 0; i < p->num_objects; i++) { sha1 = nth_packed_object_sha1(p, i); - if (!locate_object_entry(sha1)) + if (!locate_object_entry(sha1) && + !has_sha1_pack_kept_or_nonlocal(sha1)) if (force_object_loose(sha1, p->mtime)) die("unable to force loose object"); } |