Skip to content

Commit 094085e

Browse files
drafnelgitster
authored andcommitted
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 869a3d3 commit 094085e

File tree

2 files changed

+26
-2
lines changed

2 files changed

+26
-2
lines changed

builtin-pack-objects.c

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1944,6 +1944,29 @@ static void add_objects_in_unpacked_packs(struct rev_info *revs)
19441944
free(in_pack.array);
19451945
}
19461946

1947+
static int has_sha1_pack_kept_or_nonlocal(const unsigned char *sha1)
1948+
{
1949+
static struct packed_git *last_found = (void *)1;
1950+
struct packed_git *p;
1951+
1952+
p = (last_found != (void *)1) ? last_found : packed_git;
1953+
1954+
while (p) {
1955+
if ((!p->pack_local || p->pack_keep) &&
1956+
find_pack_entry_one(sha1, p)) {
1957+
last_found = p;
1958+
return 1;
1959+
}
1960+
if (p == last_found)
1961+
p = packed_git;
1962+
else
1963+
p = p->next;
1964+
if (p == last_found)
1965+
p = p->next;
1966+
}
1967+
return 0;
1968+
}
1969+
19471970
static void loosen_unused_packed_objects(struct rev_info *revs)
19481971
{
19491972
struct packed_git *p;
@@ -1959,7 +1982,8 @@ static void loosen_unused_packed_objects(struct rev_info *revs)
19591982

19601983
for (i = 0; i < p->num_objects; i++) {
19611984
sha1 = nth_packed_object_sha1(p, i);
1962-
if (!locate_object_entry(sha1))
1985+
if (!locate_object_entry(sha1) &&
1986+
!has_sha1_pack_kept_or_nonlocal(sha1))
19631987
if (force_object_loose(sha1, p->mtime))
19641988
die("unable to force loose object");
19651989
}

t/t7700-repack.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ test_expect_success 'packed unreachable obs in alternate ODB are not loosened' '
113113
test_must_fail git show $csha1
114114
'
115115

116-
test_expect_failure 'local packed unreachable obs that exist in alternate ODB are not loosened' '
116+
test_expect_success 'local packed unreachable obs that exist in alternate ODB are not loosened' '
117117
echo `pwd`/alt_objects > .git/objects/info/alternates &&
118118
echo "$csha1" | git pack-objects --non-empty --all --reflog pack &&
119119
rm -f .git/objects/pack/* &&

0 commit comments

Comments
 (0)