summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pack-bitmap-write.c14
-rwxr-xr-xt/t5310-pack-bitmaps.sh33
2 files changed, 22 insertions, 25 deletions
diff --git a/pack-bitmap-write.c b/pack-bitmap-write.c
index 76c8236f94..d2af4a974f 100644
--- a/pack-bitmap-write.c
+++ b/pack-bitmap-write.c
@@ -199,7 +199,7 @@ static void bitmap_builder_init(struct bitmap_builder *bb,
{
struct rev_info revs;
struct commit *commit;
- unsigned int i, num_maximal;
+ unsigned int i, num_maximal = 0;
memset(bb, 0, sizeof(*bb));
init_bb_data(&bb->data);
@@ -207,6 +207,7 @@ static void bitmap_builder_init(struct bitmap_builder *bb,
reset_revision_walk();
repo_init_revisions(writer->to_pack->repo, &revs, NULL);
revs.topo_order = 1;
+ revs.first_parent_only = 1;
for (i = 0; i < writer->selected_nr; i++) {
struct commit *c = writer->selected[i].commit;
@@ -221,13 +222,12 @@ static void bitmap_builder_init(struct bitmap_builder *bb,
add_pending_object(&revs, &c->object, "");
}
- num_maximal = writer->selected_nr;
if (prepare_revision_walk(&revs))
die("revision walk setup failed");
while ((commit = get_revision(&revs))) {
- struct commit_list *p;
+ struct commit_list *p = commit->parents;
struct bb_commit *c_ent;
parse_commit_or_die(commit);
@@ -235,16 +235,12 @@ static void bitmap_builder_init(struct bitmap_builder *bb,
c_ent = bb_data_at(&bb->data, commit);
if (c_ent->maximal) {
- if (!c_ent->selected) {
- bitmap_set(c_ent->commit_mask, num_maximal);
- num_maximal++;
- }
-
+ num_maximal++;
ALLOC_GROW(bb->commits, bb->commits_nr + 1, bb->commits_alloc);
bb->commits[bb->commits_nr++] = commit;
}
- for (p = commit->parents; p; p = p->next) {
+ if (p) {
struct bb_commit *p_ent = bb_data_at(&bb->data, p->item);
int c_not_p, p_not_c;
diff --git a/t/t5310-pack-bitmaps.sh b/t/t5310-pack-bitmaps.sh
index 7ba796b2c3..aa2ccdb78b 100755
--- a/t/t5310-pack-bitmaps.sh
+++ b/t/t5310-pack-bitmaps.sh
@@ -23,12 +23,12 @@ has_any () {
# To ensure the logic for "maximal commits" is exercised, make
# the repository a bit more complicated.
#
-# other master
+# other second
# * *
# (99 commits) (99 commits)
# * *
# |\ /|
-# | * octo-other octo-master * |
+# | * octo-other octo-second * |
# |/|\_________ ____________/|\|
# | \ \/ __________/ |
# | | ________/\ / |
@@ -43,23 +43,24 @@ has_any () {
# \|
# * (base)
#
+# We only push bits down the first-parent history, which
+# makes some of these commits unimportant!
+#
# The important part for the maximal commit algorithm is how
# the bitmasks are extended. Assuming starting bit positions
-# for master (bit 0) and other (bit 1), and some flexibility
-# in the order that merge bases are visited, the bitmasks at
-# the end should be:
+# for second (bit 0) and other (bit 1), the bitmasks at the
+# end should be:
#
-# master: 1 (maximal, selected)
+# second: 1 (maximal, selected)
# other: 01 (maximal, selected)
-# octo-master: 1
-# octo-other: 01
-# merge-right: 111 (maximal)
-# (l1): 111
-# (r1): 111
-# merge-left: 1101 (maximal)
-# (l2): 11111 (maximal)
-# (r2): 111101 (maximal)
-# (base): 1111111 (maximal)
+# (base): 11 (maximal)
+#
+# This complicated history was important for a previous
+# version of the walk that guarantees never walking a
+# commit multiple times. That goal might be important
+# again, so preserve this complicated case. For now, this
+# test will guarantee that the bitmaps are computed
+# correctly, even with the repeat calculations.
test_expect_success 'setup repo with moderate-sized history' '
test_commit_bulk --id=file 10 &&
@@ -114,7 +115,7 @@ test_expect_success 'full repack creates bitmaps' '
ls .git/objects/pack/ | grep bitmap >output &&
test_line_count = 1 output &&
grep "\"key\":\"num_selected_commits\",\"value\":\"106\"" trace &&
- grep "\"key\":\"num_maximal_commits\",\"value\":\"111\"" trace
+ grep "\"key\":\"num_maximal_commits\",\"value\":\"107\"" trace
'
test_expect_success 'rev-list --test-bitmap verifies bitmaps' '