Skip to content

Commit 732194b

Browse files
pks-tgitster
authored andcommitted
pack-objects: fix error when packing same pack twice
When passed the same packfile twice via `--stdin-packs` we return an error that the packfile supposedly was not found. This is because when reading packs into the list of included or excluded packfiles, we will happily re-add packfiles even if they are part of the lists already. And while the list can now contain duplicates, we will only set the `util` pointer of the first list entry to the `packed_git` structure. We notice that at a later point when checking that all list entries have their `util` pointer set and die with an error. While this is kind of a nonsensical request, this scenario can be hit when doing geometric repacks. When a repository is connected to an alternate object directory and both have the exact same packfile then both would get added to the geometric sequence. And when we then decide to perform the repack, we will invoke git-pack-objects(1) with the same packfile twice. Fix this bug by removing any duplicates from both the included and excluded packs. Signed-off-by: Patrick Steinhardt <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent b7b8f04 commit 732194b

File tree

3 files changed

+54
-0
lines changed

3 files changed

+54
-0
lines changed

builtin/pack-objects.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3344,7 +3344,9 @@ static void read_packs_list_from_stdin(void)
33443344
}
33453345

33463346
string_list_sort(&include_packs);
3347+
string_list_remove_duplicates(&include_packs, 0);
33473348
string_list_sort(&exclude_packs);
3349+
string_list_remove_duplicates(&exclude_packs, 0);
33483350

33493351
for (p = get_all_packs(the_repository); p; p = p->next) {
33503352
const char *pack_name = pack_basename(p);

t/t5331-pack-objects-stdin.sh

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
77
TEST_PASSES_SANITIZE_LEAK=true
88
. ./test-lib.sh
99

10+
packed_objects () {
11+
git show-index <"$1" >tmp-object-list &&
12+
cut -d' ' -f2 tmp-object-list | sort &&
13+
rm tmp-object-list
14+
}
15+
1016
test_expect_success 'setup for --stdin-packs tests' '
1117
git init stdin-packs &&
1218
(
@@ -142,4 +148,25 @@ test_expect_success '--stdin-packs with broken links' '
142148
)
143149
'
144150

151+
test_expect_success 'pack-objects --stdin with duplicate packfile' '
152+
test_when_finished "rm -fr repo" &&
153+
154+
git init repo &&
155+
(
156+
cd repo &&
157+
test_commit "commit" &&
158+
git repack -ad &&
159+
160+
{
161+
basename .git/objects/pack/pack-*.pack &&
162+
basename .git/objects/pack/pack-*.pack
163+
} >packfiles &&
164+
165+
git pack-objects --stdin-packs generated-pack <packfiles &&
166+
packed_objects .git/objects/pack/pack-*.idx >expect &&
167+
packed_objects generated-pack-*.idx >actual &&
168+
test_cmp expect actual
169+
)
170+
'
171+
145172
test_done

t/t7703-repack-geometric.sh

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,4 +336,29 @@ test_expect_success '--geometric --with-midx with no local objects' '
336336
test_dir_is_empty member/$packdir
337337
'
338338

339+
test_expect_success '--geometric with same pack in main and alternate ODB' '
340+
test_when_finished "rm -fr shared member" &&
341+
342+
# Create a repository with a single packfile that acts as alternate
343+
# object database.
344+
git init shared &&
345+
test_commit -C shared "shared-objects" &&
346+
git -C shared repack -ad &&
347+
348+
# We create the member repository as an exact copy so that it has the
349+
# same packfile.
350+
cp -r shared member &&
351+
test-tool path-utils real_path shared/.git/objects >member/.git/objects/info/alternates &&
352+
find shared/.git/objects -type f >expected-files &&
353+
354+
# Verify that we can repack objects as expected without observing any
355+
# error. Having the same packfile in both ODBs used to cause an error
356+
# in git-pack-objects(1).
357+
git -C member repack --geometric 2 2>err &&
358+
test_must_be_empty err &&
359+
# Nothing should have changed.
360+
find shared/.git/objects -type f >actual-files &&
361+
test_cmp expected-files actual-files
362+
'
363+
339364
test_done

0 commit comments

Comments
 (0)