Skip to content

Commit 4eb707e

Browse files
peffgitster
authored andcommitted
rev-list: allow commit-only bitmap traversals
Ever since we added reachability bitmap support, we've been able to use it with rev-list to get the full list of objects, like: git rev-list --objects --use-bitmap-index --all But you can't do so without --objects, since we weren't ready to just show the commits. However, the internals of the bitmap code are mostly ready for this: they avoid opening up trees when walking to fill in the bitmaps. We just need to actually pass in the rev_info to traverse_bitmap_commit_list() so it knows which types to bother triggering our callback for. For completeness, the perf test now covers both the existing --objects case, as well as the new commits-only behavior (the objects one got way faster when we introduced bitmaps, but obviously isn't improved now). Here are numbers for linux.git: Test HEAD^ HEAD ------------------------------------------------------------------------ 5310.7: rev-list (commits) 8.29(8.10+0.19) 1.76(1.72+0.04) -78.8% 5310.8: rev-list (objects) 8.06(7.94+0.12) 8.14(7.94+0.13) +1.0% That run was cheating a little, as I didn't have any commit-graph in the repository, and we'd built it by default these days when running git-gc. Here are numbers with a commit-graph: Test HEAD^ HEAD ------------------------------------------------------------------------ 5310.7: rev-list (commits) 0.70(0.58+0.12) 0.51(0.46+0.04) -27.1% 5310.8: rev-list (objects) 6.20(6.09+0.10) 6.27(6.16+0.11) +1.1% Still an improvement, but a lot less impressive. We could have the perf script remove any commit-graph to show the out-sized effect, but it probably makes sense to leave it in what would be a more typical setup. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent ea047a8 commit 4eb707e

File tree

7 files changed

+34
-15
lines changed

7 files changed

+34
-15
lines changed

builtin/pack-objects.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -3054,7 +3054,8 @@ static int get_object_list_from_bitmap(struct rev_info *revs)
30543054
display_progress(progress_state, nr_result);
30553055
}
30563056

3057-
traverse_bitmap_commit_list(bitmap_git, &add_object_entry_from_bitmap);
3057+
traverse_bitmap_commit_list(bitmap_git, revs,
3058+
&add_object_entry_from_bitmap);
30583059
return 0;
30593060
}
30603061

builtin/rev-list.c

+1-8
Original file line numberDiff line numberDiff line change
@@ -434,18 +434,11 @@ static int try_bitmap_traversal(struct rev_info *revs)
434434
if (revs->max_count >= 0)
435435
return -1;
436436

437-
/*
438-
* Our bitmap result will return all objects, and we're not
439-
* yet prepared to show only particular types.
440-
*/
441-
if (!revs->tag_objects || !revs->tree_objects || !revs->blob_objects)
442-
return -1;
443-
444437
bitmap_git = prepare_bitmap_walk(revs);
445438
if (!bitmap_git)
446439
return -1;
447440

448-
traverse_bitmap_commit_list(bitmap_git, &show_object_fast);
441+
traverse_bitmap_commit_list(bitmap_git, revs, &show_object_fast);
449442
free_bitmap_index(bitmap_git);
450443
return 0;
451444
}

pack-bitmap.c

+15-5
Original file line numberDiff line numberDiff line change
@@ -599,6 +599,7 @@ static struct bitmap *find_objects(struct bitmap_index *bitmap_git,
599599
}
600600

601601
static void show_extended_objects(struct bitmap_index *bitmap_git,
602+
struct rev_info *revs,
602603
show_reachable_fn show_reach)
603604
{
604605
struct bitmap *objects = bitmap_git->result;
@@ -612,6 +613,11 @@ static void show_extended_objects(struct bitmap_index *bitmap_git,
612613
continue;
613614

614615
obj = eindex->objects[i];
616+
if ((obj->type == OBJ_BLOB && !revs->blob_objects) ||
617+
(obj->type == OBJ_TREE && !revs->tree_objects) ||
618+
(obj->type == OBJ_TAG && !revs->tag_objects))
619+
continue;
620+
615621
show_reach(&obj->oid, obj->type, 0, eindex->hashes[i], NULL, 0);
616622
}
617623
}
@@ -872,16 +878,20 @@ int reuse_partial_packfile_from_bitmap(struct bitmap_index *bitmap_git,
872878
}
873879

874880
void traverse_bitmap_commit_list(struct bitmap_index *bitmap_git,
881+
struct rev_info *revs,
875882
show_reachable_fn show_reachable)
876883
{
877884
assert(bitmap_git->result);
878885

879886
show_objects_for_type(bitmap_git, OBJ_COMMIT, show_reachable);
880-
show_objects_for_type(bitmap_git, OBJ_TREE, show_reachable);
881-
show_objects_for_type(bitmap_git, OBJ_BLOB, show_reachable);
882-
show_objects_for_type(bitmap_git, OBJ_TAG, show_reachable);
883-
884-
show_extended_objects(bitmap_git, show_reachable);
887+
if (revs->tree_objects)
888+
show_objects_for_type(bitmap_git, OBJ_TREE, show_reachable);
889+
if (revs->blob_objects)
890+
show_objects_for_type(bitmap_git, OBJ_BLOB, show_reachable);
891+
if (revs->tag_objects)
892+
show_objects_for_type(bitmap_git, OBJ_TAG, show_reachable);
893+
894+
show_extended_objects(bitmap_git, revs, show_reachable);
885895
}
886896

887897
static uint32_t count_object_type(struct bitmap_index *bitmap_git,

pack-bitmap.h

+1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ struct bitmap_index *prepare_bitmap_git(struct repository *r);
4444
void count_bitmap_commit_list(struct bitmap_index *, uint32_t *commits,
4545
uint32_t *trees, uint32_t *blobs, uint32_t *tags);
4646
void traverse_bitmap_commit_list(struct bitmap_index *,
47+
struct rev_info *revs,
4748
show_reachable_fn show_reachable);
4849
void test_bitmap_walk(struct rev_info *revs);
4950
struct bitmap_index *prepare_bitmap_walk(struct rev_info *revs);

reachable.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ void mark_reachable_objects(struct rev_info *revs, int mark_reflog,
225225

226226
bitmap_git = prepare_bitmap_walk(revs);
227227
if (bitmap_git) {
228-
traverse_bitmap_commit_list(bitmap_git, mark_object_seen);
228+
traverse_bitmap_commit_list(bitmap_git, revs, mark_object_seen);
229229
free_bitmap_index(bitmap_git);
230230
return;
231231
}

t/perf/p5310-pack-bitmaps.sh

+8
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,14 @@ test_perf 'pack to file (bitmap)' '
3939
git pack-objects --use-bitmap-index --all pack1b </dev/null >/dev/null
4040
'
4141

42+
test_perf 'rev-list (commits)' '
43+
git rev-list --all --use-bitmap-index >/dev/null
44+
'
45+
46+
test_perf 'rev-list (objects)' '
47+
git rev-list --all --use-bitmap-index --objects >/dev/null
48+
'
49+
4250
test_expect_success 'create partial bitmap state' '
4351
# pick a commit to represent the repo tip in the past
4452
cutoff=$(git rev-list HEAD~100 -1) &&

t/t5310-pack-bitmaps.sh

+6
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,12 @@ rev_list_tests() {
8080
test_cmp expect actual
8181
'
8282

83+
test_expect_success "enumerate commits ($state)" '
84+
git rev-list --use-bitmap-index HEAD >actual &&
85+
git rev-list HEAD >expect &&
86+
test_bitmap_traversal --no-confirm-bitmaps expect actual
87+
'
88+
8389
test_expect_success "enumerate --objects ($state)" '
8490
git rev-list --objects --use-bitmap-index HEAD >actual &&
8591
git rev-list --objects HEAD >expect &&

0 commit comments

Comments
 (0)