Skip to content

Commit 1e06a72

Browse files
ttaylorrgitster
authored andcommitted
midx: enable reachability bitmaps during MIDX compaction
Enable callers to generate reachability bitmaps when performing MIDX layer compaction by combining all existing bitmaps from the compacted layers. Note that the because of the object/pack ordering described by the previous commit, the pseudo-pack order for the compacted MIDX is the same as concatenating the individual pseudo-pack orderings for each layer in the compaction range. As a result, the only non-test or documentation change necessary is to treat all objects as non-preferred during compaction so as not to disturb the object ordering. In the future, we may want to adjust which commit(s) receive reachability bitmaps when compacting multiple .bitmap files into one, or even generate new bitmaps (e.g., if the references have moved significantly since the .bitmap was generated). This commit only implements combining all existing bitmaps in range together in order to demonstrate and lay the groundwork for more exotic strategies. Signed-off-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent 98ce832 commit 1e06a72

File tree

4 files changed

+123
-5
lines changed

4 files changed

+123
-5
lines changed

Documentation/git-multi-pack-index.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ SYNOPSIS
1313
[--[no-]bitmap] [--[no-]incremental] [--[no-]stdin-packs]
1414
[--refs-snapshot=<path>]
1515
'git multi-pack-index' [<options>] compact [--[no-]incremental]
16-
<from> <to>
16+
[--[no-]bitmap] <from> <to>
1717
'git multi-pack-index' [<options>] verify
1818
'git multi-pack-index' [<options>] expire
1919
'git multi-pack-index' [<options>] repack [--batch-size=<size>]

builtin/multi-pack-index.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
#define BUILTIN_MIDX_COMPACT_USAGE \
2121
N_("git multi-pack-index [<options>] compact [--[no-]incremental]\n" \
22-
" <from> <to>")
22+
" [--[no-]bitmap] <from> <to>")
2323

2424
#define BUILTIN_MIDX_VERIFY_USAGE \
2525
N_("git multi-pack-index [<options>] verify")
@@ -216,6 +216,8 @@ static int cmd_multi_pack_index_compact(int argc, const char **argv,
216216

217217
struct option *options;
218218
static struct option builtin_multi_pack_index_compact_options[] = {
219+
OPT_BIT(0, "bitmap", &opts.flags, N_("write multi-pack bitmap"),
220+
MIDX_WRITE_BITMAP | MIDX_WRITE_REV_INDEX),
219221
OPT_BIT(0, "incremental", &opts.flags,
220222
N_("write a new incremental MIDX"), MIDX_WRITE_INCREMENTAL),
221223
OPT_END(),

midx-write.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -657,7 +657,7 @@ static uint32_t *midx_pack_order(struct write_midx_context *ctx)
657657
struct pack_midx_entry *e = &ctx->entries[i];
658658
data[i].nr = i;
659659
data[i].pack = midx_pack_perm(ctx, e->pack_int_id);
660-
if (!e->preferred)
660+
if (!e->preferred || ctx->compact)
661661
data[i].pack |= (1U << 31);
662662
data[i].offset = e->offset;
663663
}

t/t5335-compact-multi-pack-index.sh

Lines changed: 118 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ test_expect_success 'MIDX compaction with lex-ordered pack names' '
6565
write_packs A B C D E &&
6666
test_line_count = 5 $midx_chain &&
6767
68-
git multi-pack-index compact --incremental \
68+
git multi-pack-index compact --incremental --bitmap \
6969
"$(nth_line 2 "$midx_chain")" \
7070
"$(nth_line 4 "$midx_chain")" &&
7171
test_line_count = 3 $midx_chain &&
@@ -86,7 +86,7 @@ test_expect_success 'MIDX compaction with non-lex-ordered pack names' '
8686
write_packs D C A B E &&
8787
test_line_count = 5 $midx_chain &&
8888
89-
git multi-pack-index compact --incremental \
89+
git multi-pack-index compact --incremental --bitmap \
9090
"$(nth_line 2 "$midx_chain")" \
9191
"$(nth_line 4 "$midx_chain")" &&
9292
test_line_count = 3 $midx_chain &&
@@ -99,4 +99,120 @@ test_expect_success 'MIDX compaction with non-lex-ordered pack names' '
9999
)
100100
'
101101

102+
midx_objs_by_pack () {
103+
awk '/\.pack$/ { split($3, a, "-"); print a[2], $1 }' | sort
104+
}
105+
106+
tag_objs_from_pack () {
107+
objs="$(git rev-list --objects --no-object-names "$2")" &&
108+
printf "$1 %s\n" $objs | sort
109+
}
110+
111+
test_expect_success 'MIDX compaction preserves pack object selection' '
112+
git init midx-compact-preserve-selection &&
113+
(
114+
cd midx-compact-preserve-selection &&
115+
116+
test_commit A &&
117+
test_commit B &&
118+
119+
# Create two packs, one containing just the objects from
120+
# A, and another containing all objects from the
121+
# repository.
122+
p1="$(echo A | git pack-objects --revs --delta-base-offset \
123+
$packdir/pack-1)" &&
124+
p0="$(echo B | git pack-objects --revs --delta-base-offset \
125+
$packdir/pack-0)" &&
126+
127+
echo "pack-1-$p1.idx" | git multi-pack-index write \
128+
--incremental --bitmap --stdin-packs &&
129+
echo "pack-0-$p0.idx" | git multi-pack-index write \
130+
--incremental --bitmap --stdin-packs &&
131+
132+
write_packs C &&
133+
134+
git multi-pack-index compact --incremental --bitmap \
135+
"$(nth_line 1 "$midx_chain")" \
136+
"$(nth_line 2 "$midx_chain")" &&
137+
138+
139+
test-tool read-midx --show-objects $objdir \
140+
"$(nth_line 1 "$midx_chain")" >AB.info &&
141+
test-tool read-midx --show-objects $objdir \
142+
"$(nth_line 2 "$midx_chain")" >C.info &&
143+
144+
midx_objs_by_pack <AB.info >AB.actual &&
145+
midx_objs_by_pack <C.info >C.actual &&
146+
147+
{
148+
tag_objs_from_pack 1 A &&
149+
tag_objs_from_pack 0 A..B
150+
} | sort >AB.expect &&
151+
tag_objs_from_pack C B..C >C.expect &&
152+
153+
test_cmp AB.expect AB.actual &&
154+
test_cmp C.expect C.actual
155+
)
156+
'
157+
158+
test_expect_success 'MIDX compaction with bitmaps' '
159+
git init midx-compact-with-bitmaps &&
160+
(
161+
cd midx-compact-with-bitmaps &&
162+
163+
write_packs foo bar baz quux woot &&
164+
165+
test-tool read-midx --bitmap $objdir >bitmap.expect &&
166+
git multi-pack-index compact --incremental --bitmap \
167+
"$(nth_line 2 "$midx_chain")" \
168+
"$(nth_line 4 "$midx_chain")" &&
169+
test-tool read-midx --bitmap $objdir >bitmap.actual &&
170+
171+
test_cmp bitmap.expect bitmap.actual &&
172+
173+
true
174+
)
175+
'
176+
177+
test_expect_success 'MIDX compaction with bitmaps (non-trivial)' '
178+
git init midx-compact-with-bitmaps-non-trivial &&
179+
(
180+
cd midx-compact-with-bitmaps-non-trivial &&
181+
182+
git branch -m main &&
183+
184+
# D(4)
185+
# /
186+
# A(1) --- B(2) --- C(3) --- G(7)
187+
# \
188+
# E(5) --- F(6)
189+
write_packs A B C &&
190+
git checkout -b side &&
191+
write_packs D &&
192+
git checkout -b other B &&
193+
write_packs E F &&
194+
git checkout main &&
195+
write_packs G &&
196+
197+
cat $midx_chain &&
198+
199+
# Compact layers 2-4, leaving us with:
200+
#
201+
# [A, [B, C, D], E, F, G]
202+
git multi-pack-index compact --incremental --bitmap \
203+
"$(nth_line 2 "$midx_chain")" \
204+
"$(nth_line 4 "$midx_chain")" &&
205+
206+
# Then compact the top two layers, condensing the above
207+
# such that the new 4th layer contains F and G.
208+
#
209+
# [A, [B, C, D], E, [F, G]]
210+
git multi-pack-index compact --incremental --bitmap \
211+
"$(nth_line 4 "$midx_chain")" \
212+
"$(nth_line 5 "$midx_chain")" &&
213+
214+
cat $midx_chain
215+
)
216+
'
217+
102218
test_done

0 commit comments

Comments
 (0)