aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/config/pack.adoc9
-rw-r--r--pack-bitmap.c13
-rwxr-xr-xt/t5310-pack-bitmaps.sh41
-rwxr-xr-xt/t5319-multi-pack-index.sh43
4 files changed, 101 insertions, 5 deletions
diff --git a/Documentation/config/pack.adoc b/Documentation/config/pack.adoc
index 75402d5579..fa997c8597 100644
--- a/Documentation/config/pack.adoc
+++ b/Documentation/config/pack.adoc
@@ -160,12 +160,13 @@ pack.usePathWalk::
processes. See linkgit:git-pack-objects[1] for full details.
pack.preferBitmapTips::
+ Specifies a ref hierarchy (e.g., "refs/heads/"); can be
+ given multiple times to specify more than one hierarchies.
When selecting which commits will receive bitmaps, prefer a
- commit at the tip of any reference that is a suffix of any value
- of this configuration over any other commits in the "selection
- window".
+ commit at the tip of a reference that is contained in any of
+ the configured hierarchies.
+
-Note that setting this configuration to `refs/foo` does not mean that
+Note that setting this configuration to `refs/foo/` does not mean that
the commits at the tips of `refs/foo/bar` and `refs/foo/baz` will
necessarily be selected. This is because commits are selected for
bitmaps from within a series of windows of variable length.
diff --git a/pack-bitmap.c b/pack-bitmap.c
index 2f5cb34009..1c93871484 100644
--- a/pack-bitmap.c
+++ b/pack-bitmap.c
@@ -3328,15 +3328,26 @@ void for_each_preferred_bitmap_tip(struct repository *repo,
{
struct string_list_item *item;
const struct string_list *preferred_tips;
+ struct strbuf buf = STRBUF_INIT;
preferred_tips = bitmap_preferred_tips(repo);
if (!preferred_tips)
return;
for_each_string_list_item(item, preferred_tips) {
+ const char *pattern = item->string;
+
+ if (!ends_with(pattern, "/")) {
+ strbuf_reset(&buf);
+ strbuf_addf(&buf, "%s/", pattern);
+ pattern = buf.buf;
+ }
+
refs_for_each_ref_in(get_main_ref_store(repo),
- item->string, cb, cb_data);
+ pattern, cb, cb_data);
}
+
+ strbuf_release(&buf);
}
int bitmap_is_preferred_refname(struct repository *r, const char *refname)
diff --git a/t/t5310-pack-bitmaps.sh b/t/t5310-pack-bitmaps.sh
index 6718fb98c0..310b708c5c 100755
--- a/t/t5310-pack-bitmaps.sh
+++ b/t/t5310-pack-bitmaps.sh
@@ -466,6 +466,47 @@ test_bitmap_cases () {
)
'
+ test_expect_success 'pack.preferBitmapTips interprets patterns as hierarchy' '
+ git init repo &&
+ test_when_finished "rm -fr repo" &&
+ (
+ cd repo &&
+
+ # Create enough commits that not all will receive bitmap
+ # coverage even if they are all at the tip of some reference.
+ test_commit_bulk --message="%s" 103 &&
+ git log --format="create refs/tags/%s/tag %H" HEAD >refs &&
+ git update-ref --stdin <refs &&
+
+ # Create the bitmap.
+ git repack -adb &&
+ test-tool bitmap list-commits | sort >commits-with-bitmap &&
+
+ # Verify that we have at least one commit that did not
+ # receive a bitmap.
+ git rev-list HEAD >commits.raw &&
+ sort <commits.raw >commits &&
+ comm -13 commits-with-bitmap commits >commits-wo-bitmap &&
+ test_file_not_empty commits-wo-bitmap &&
+ commit_id=$(head commits-wo-bitmap) &&
+ ref_without_bitmap=$(git for-each-ref --points-at="$commit_id" --format="%(refname)") &&
+
+ # When passing the full refname we do not expect a
+ # bitmap to be generated, as it should be interpreted
+ # as if a slash was appended to the pattern.
+ git -c pack.preferBitmapTips="$ref_without_bitmap" repack -adb &&
+ test-tool bitmap list-commits >after &&
+ test_grep ! "$commit_id" after &&
+
+ # But if we pass the parent directory of the ref we
+ # should see a bitmap.
+ ref_namespace=$(dirname "$ref_without_bitmap") &&
+ git -c pack.preferBitmapTips="$ref_namespace" repack -adb &&
+ test-tool bitmap list-commits >after &&
+ test_grep "$commit_id" after
+ )
+ '
+
test_expect_success 'complains about multiple pack bitmaps' '
rm -fr repo &&
git init repo &&
diff --git a/t/t5319-multi-pack-index.sh b/t/t5319-multi-pack-index.sh
index faae98c7e7..449353416f 100755
--- a/t/t5319-multi-pack-index.sh
+++ b/t/t5319-multi-pack-index.sh
@@ -1345,4 +1345,47 @@ test_expect_success 'bitmapped packs are stored via the BTMP chunk' '
)
'
+test_expect_success 'pack.preferBitmapTips interprets patterns as hierarchy' '
+ git init repo &&
+ test_when_finished "rm -fr repo" &&
+ (
+ cd repo &&
+
+ # Create enough commits that not all will receive bitmap
+ # coverage even if they are all at the tip of some reference.
+ test_commit_bulk --message="%s" 103 &&
+ git log --format="create refs/tags/%s %H" HEAD >refs &&
+ git update-ref --stdin <refs &&
+
+ # Create the bitmap via the MIDX.
+ git repack -adb --write-midx &&
+ test-tool bitmap list-commits | sort >commits-with-bitmap &&
+
+ # Verify that we have at least one commit that did not
+ # receive a bitmap.
+ git rev-list HEAD >commits.raw &&
+ sort <commits.raw >commits &&
+ comm -13 commits-with-bitmap commits >commits-wo-bitmap &&
+ test_file_not_empty commits-wo-bitmap &&
+ commit_id=$(head commits-wo-bitmap) &&
+ ref_without_bitmap=$(git for-each-ref --points-at="$commit_id" --format="%(refname)") &&
+
+ # When passing the full refname we do not expect a bitmap to be
+ # generated, as it should be interpreted as if a slash was
+ # appended to the pattern.
+ rm .git/objects/pack/multi-pack-index* &&
+ git -c pack.preferBitmapTips="$ref_without_bitmap" repack -adb --write-midx &&
+ test-tool bitmap list-commits >after &&
+ test_grep ! "$commit_id" after &&
+
+ # But if we pass the parent directory of the ref we should see
+ # a bitmap.
+ ref_namespace=$(dirname "$ref_without_bitmap") &&
+ rm .git/objects/pack/multi-pack-index* &&
+ git -c pack.preferBitmapTips="$ref_namespace" repack -adb --write-midx &&
+ test-tool bitmap list-commits >after &&
+ test_grep "$commit_id" after
+ )
+'
+
test_done