mirror of
https://github.com/git-for-windows/git.git
synced 2026-06-13 19:31:09 -05:00
When 'pack-objects' is invoked with '--path-walk', it prevents us from using reachability bitmaps. This behavior dates back to70664d2865(pack-objects: add --path-walk option, 2025-05-16), which included a comment in the relevant portion of the command-line arguments handling that read as follows: /* * We must disable the bitmaps because we are removing * the --objects / --objects-edge[-aggressive] options. */ Infb2c309b7d(pack-objects: pass --objects with --path-walk, 2026-05-02), path-walk learned to pass '--objects' again, but still kept bitmap traversal disabled. That leaves two useful cases unsupported: * A path-walk repack that writes bitmaps does not give the bitmap selector any commits, because path-walk reveals commits through `add_objects_by_path()` rather than through `show_commit()`, where `index_commit_for_bitmap()` is normally called. * An invocation like "git pack-objects --use-bitmap-index --path-walk" never tries an existing bitmap, even when one is available and could answer the request. Fortunately for us, neither restriction is required. * On the writing side: teach the path-walk object callback to call `index_commit_for_bitmap()` for commits that it adds to the pack. That gives the bitmap selector the commit candidates it would have seen from the regular traversal. * For bitmap reading, keep passing '--objects' to the internal rev_list machinery, but stop clearing `use_bitmap_index`. If an existing bitmap can answer the request, use it; otherwise fall back to path-walk's own enumeration. As a result, we can see significantly reduced pack sizes from p5311 before this commit: Test HEAD^ HEAD ---------------------------------------------------------------------------------- 5311.38: server (1 days, --path-walk) 2.56(2.52+0.03) 0.01(0.01+0.00) -99.6% 5311.39: size (1 days, --path-walk) 123.9K 123.9K +0.0% 5311.40: client (1 days, --path-walk) 0.00(0.01+0.00) 0.00(0.00+0.00) = 5311.42: server (2 days, --path-walk) 2.57(2.52+0.05) 0.01(0.01+0.00) -99.6% 5311.43: size (2 days, --path-walk) 123.9K 123.9K +0.0% 5311.44: client (2 days, --path-walk) 0.00(0.00+0.00) 0.00(0.00+0.00) = 5311.46: server (4 days, --path-walk) 2.58(2.51+0.07) 0.01(0.01+0.00) -99.6% 5311.47: size (4 days, --path-walk) 123.9K 123.9K +0.0% 5311.48: client (4 days, --path-walk) 0.00(0.00+0.00) 0.00(0.00+0.00) = 5311.50: server (8 days, --path-walk) 2.58(2.53+0.04) 0.02(0.02+0.00) -99.2% 5311.51: size (8 days, --path-walk) 152.4K 152.4K +0.0% 5311.52: client (8 days, --path-walk) 0.00(0.01+0.00) 0.00(0.01+0.00) = 5311.54: server (16 days, --path-walk) 2.58(2.52+0.05) 0.03(0.02+0.00) -98.8% 5311.55: size (16 days, --path-walk) 205.3K 205.3K +0.0% 5311.56: client (16 days, --path-walk) 0.01(0.01+0.00) 0.01(0.01+0.00) +0.0% 5311.58: server (32 days, --path-walk) 2.59(2.53+0.06) 0.03(0.03+0.00) -98.8% 5311.59: size (32 days, --path-walk) 209.3K 209.3K +0.0% 5311.60: client (32 days, --path-walk) 0.01(0.02+0.00) 0.01(0.02+0.00) +0.0% 5311.62: server (64 days, --path-walk) 2.70(2.76+0.06) 0.16(0.24+0.04) -94.1% 5311.63: size (64 days, --path-walk) 4.1M 4.1M +0.0% 5311.64: client (64 days, --path-walk) 0.44(0.50+0.02) 0.44(0.51+0.02) +0.0% 5311.66: server (128 days, --path-walk) 2.88(3.20+0.05) 0.34(0.65+0.05) -88.2% 5311.67: size (128 days, --path-walk) 9.0M 9.0M -0.0% 5311.68: client (128 days, --path-walk) 0.93(1.22+0.07) 0.93(1.20+0.08) +0.0% We get the same size of output pack, but this commit allows us to do so in a significantly shorter amount of time. Intuitively, we're generating the same pack (hence the unchanged 'test_size' output from run to run), but varying how we get there. Before this commit, pack-objects prefers '--path-walk' to '--use-bitmap-index', so we generate the output pack by performing a normal '--path-walk' traversal. With this commit, we are operating over a *repacked* state (that itself was done with a '--path-walk' traversal), but are able to perform pack-reuse on that repacked state via bitmaps. There is one wrinkle when it comes to '--boundary', which we must not pass into the bitmap walk in the presence of both '--path-walk' and '--use-bitmap-index'. Path-walk needs boundary commits when it performs its own traversal, in order to discover bases for thin packs, but the bitmap traversal does not expect this. Work around this by setting `revs->boundary` as late as possible within the '--path-walk' traversal, after any bitmap attempt has either succeeded or declined to answer the request. Signed-off-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>