Skip to content

Commit b458300

Browse files
committed
Merge branch 'jk/pack-objects-with-bitmap-fix'
Hotfix of the base topic. * jk/pack-objects-with-bitmap-fix: pack-bitmap: drop "loaded" flag traverse_bitmap_commit_list(): don't free result t5310: test delta reuse with bitmaps bitmap_has_sha1_in_uninteresting(): drop BUG check
2 parents 6b472d9 + 199c86b commit b458300

File tree

3 files changed

+97
-12
lines changed

3 files changed

+97
-12
lines changed

pack-bitmap.c

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,6 @@ struct bitmap_index {
9191

9292
/* Version of the bitmap index */
9393
unsigned int version;
94-
95-
unsigned loaded : 1;
9694
};
9795

9896
static struct ewah_bitmap *lookup_stored_bitmap(struct stored_bitmap *st)
@@ -306,7 +304,7 @@ static int open_pack_bitmap_1(struct bitmap_index *bitmap_git, struct packed_git
306304

307305
static int load_pack_bitmap(struct bitmap_index *bitmap_git)
308306
{
309-
assert(bitmap_git->map && !bitmap_git->loaded);
307+
assert(bitmap_git->map);
310308

311309
bitmap_git->bitmaps = kh_init_sha1();
312310
bitmap_git->ext_index.positions = kh_init_sha1_pos();
@@ -321,7 +319,6 @@ static int load_pack_bitmap(struct bitmap_index *bitmap_git)
321319
if (load_bitmap_entries_v1(bitmap_git) < 0)
322320
goto failed;
323321

324-
bitmap_git->loaded = 1;
325322
return 0;
326323

327324
failed:
@@ -336,7 +333,7 @@ static int open_pack_bitmap(struct bitmap_index *bitmap_git)
336333
struct packed_git *p;
337334
int ret = -1;
338335

339-
assert(!bitmap_git->map && !bitmap_git->loaded);
336+
assert(!bitmap_git->map);
340337

341338
for (p = get_all_packs(the_repository); p; p = p->next) {
342339
if (open_pack_bitmap_1(bitmap_git, p) == 0)
@@ -738,7 +735,7 @@ struct bitmap_index *prepare_bitmap_walk(struct rev_info *revs)
738735
* from disk. this is the point of no return; after this the rev_list
739736
* becomes invalidated and we must perform the revwalk through bitmaps
740737
*/
741-
if (!bitmap_git->loaded && load_pack_bitmap(bitmap_git) < 0)
738+
if (load_pack_bitmap(bitmap_git) < 0)
742739
goto cleanup;
743740

744741
object_array_clear(&revs->pending);
@@ -848,9 +845,6 @@ void traverse_bitmap_commit_list(struct bitmap_index *bitmap_git,
848845
OBJ_TAG, show_reachable);
849846

850847
show_extended_objects(bitmap_git, show_reachable);
851-
852-
bitmap_free(bitmap_git->result);
853-
bitmap_git->result = NULL;
854848
}
855849

856850
static uint32_t count_object_type(struct bitmap_index *bitmap_git,
@@ -1128,8 +1122,6 @@ int bitmap_has_sha1_in_uninteresting(struct bitmap_index *bitmap_git,
11281122

11291123
if (!bitmap_git)
11301124
return 0; /* no bitmap loaded */
1131-
if (!bitmap_git->result)
1132-
BUG("failed to perform bitmap walk before querying");
11331125
if (!bitmap_git->haves)
11341126
return 0; /* walk had no "haves" */
11351127

pack-bitmap.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ int rebuild_existing_bitmaps(struct bitmap_index *, struct packing_data *mapping
5454
void free_bitmap_index(struct bitmap_index *);
5555

5656
/*
57-
* After a traversal has been performed on the bitmap_index, this can be
57+
* After a traversal has been performed by prepare_bitmap_walk(), this can be
5858
* queried to see if a particular object was reachable from any of the
5959
* objects flagged as UNINTERESTING.
6060
*/

t/t5310-pack-bitmaps.sh

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,4 +342,97 @@ test_expect_success 'truncated bitmap fails gracefully' '
342342
test_i18ngrep corrupt stderr
343343
'
344344

345+
# have_delta <obj> <expected_base>
346+
#
347+
# Note that because this relies on cat-file, it might find _any_ copy of an
348+
# object in the repository. The caller is responsible for making sure
349+
# there's only one (e.g., via "repack -ad", or having just fetched a copy).
350+
have_delta () {
351+
echo $2 >expect &&
352+
echo $1 | git cat-file --batch-check="%(deltabase)" >actual &&
353+
test_cmp expect actual
354+
}
355+
356+
# Create a state of history with these properties:
357+
#
358+
# - refs that allow a client to fetch some new history, while sharing some old
359+
# history with the server; we use branches delta-reuse-old and
360+
# delta-reuse-new here
361+
#
362+
# - the new history contains an object that is stored on the server as a delta
363+
# against a base that is in the old history
364+
#
365+
# - the base object is not immediately reachable from the tip of the old
366+
# history; finding it would involve digging down through history we know the
367+
# other side has
368+
#
369+
# This should result in a state where fetching from old->new would not
370+
# traditionally reuse the on-disk delta (because we'd have to dig to realize
371+
# that the client has it), but we will do so if bitmaps can tell us cheaply
372+
# that the other side has it.
373+
test_expect_success 'set up thin delta-reuse parent' '
374+
# This first commit contains the buried base object.
375+
test-tool genrandom delta 16384 >file &&
376+
git add file &&
377+
git commit -m "delta base" &&
378+
base=$(git rev-parse --verify HEAD:file) &&
379+
380+
# These intermediate commits bury the base back in history.
381+
# This becomes the "old" state.
382+
for i in 1 2 3 4 5
383+
do
384+
echo $i >file &&
385+
git commit -am "intermediate $i" || return 1
386+
done &&
387+
git branch delta-reuse-old &&
388+
389+
# And now our new history has a delta against the buried base. Note
390+
# that this must be smaller than the original file, since pack-objects
391+
# prefers to create deltas from smaller objects to larger.
392+
test-tool genrandom delta 16300 >file &&
393+
git commit -am "delta result" &&
394+
delta=$(git rev-parse --verify HEAD:file) &&
395+
git branch delta-reuse-new &&
396+
397+
# Repack with bitmaps and double check that we have the expected delta
398+
# relationship.
399+
git repack -adb &&
400+
have_delta $delta $base
401+
'
402+
403+
# Now we can sanity-check the non-bitmap behavior (that the server is not able
404+
# to reuse the delta). This isn't strictly something we care about, so this
405+
# test could be scrapped in the future. But it makes sure that the next test is
406+
# actually triggering the feature we want.
407+
#
408+
# Note that our tools for working with on-the-wire "thin" packs are limited. So
409+
# we actually perform the fetch, retain the resulting pack, and inspect the
410+
# result.
411+
test_expect_success 'fetch without bitmaps ignores delta against old base' '
412+
test_config pack.usebitmaps false &&
413+
test_when_finished "rm -rf client.git" &&
414+
git init --bare client.git &&
415+
(
416+
cd client.git &&
417+
git config transfer.unpackLimit 1 &&
418+
git fetch .. delta-reuse-old:delta-reuse-old &&
419+
git fetch .. delta-reuse-new:delta-reuse-new &&
420+
have_delta $delta $ZERO_OID
421+
)
422+
'
423+
424+
# And do the same for the bitmap case, where we do expect to find the delta.
425+
test_expect_success 'fetch with bitmaps can reuse old base' '
426+
test_config pack.usebitmaps true &&
427+
test_when_finished "rm -rf client.git" &&
428+
git init --bare client.git &&
429+
(
430+
cd client.git &&
431+
git config transfer.unpackLimit 1 &&
432+
git fetch .. delta-reuse-old:delta-reuse-old &&
433+
git fetch .. delta-reuse-new:delta-reuse-new &&
434+
have_delta $delta $base
435+
)
436+
'
437+
345438
test_done

0 commit comments

Comments
 (0)