summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/config/pack.txt15
-rw-r--r--Makefile1
-rw-r--r--builtin/pack-objects.c34
-rw-r--r--pack-bitmap.c24
-rw-r--r--pack-bitmap.h4
-rw-r--r--t/helper/test-bitmap.c24
-rw-r--r--t/helper/test-tool.c1
-rw-r--r--t/helper/test-tool.h1
-rwxr-xr-xt/t5310-pack-bitmaps.sh38
9 files changed, 142 insertions, 0 deletions
diff --git a/Documentation/config/pack.txt b/Documentation/config/pack.txt
index 3da4ea9..c0844d8 100644
--- a/Documentation/config/pack.txt
+++ b/Documentation/config/pack.txt
@@ -122,6 +122,21 @@ pack.useSparse::
commits contain certain types of direct renames. Default is
`true`.
+pack.preferBitmapTips::
+ 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".
++
+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.
++
+If a commit at the tip of any reference which is a suffix of any value
+of this configuration is seen in a window, it is immediately given
+preference over any other commit in that window.
+
pack.writeBitmaps (deprecated)::
This is a deprecated synonym for `repack.writeBitmaps`.
diff --git a/Makefile b/Makefile
index ffc2ddf..21c0bf1 100644
--- a/Makefile
+++ b/Makefile
@@ -693,6 +693,7 @@ X =
PROGRAMS += $(patsubst %.o,git-%$X,$(PROGRAM_OBJS))
TEST_BUILTINS_OBJS += test-advise.o
+TEST_BUILTINS_OBJS += test-bitmap.o
TEST_BUILTINS_OBJS += test-bloom.o
TEST_BUILTINS_OBJS += test-chmtime.o
TEST_BUILTINS_OBJS += test-config.o
diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index 525c2d8..a1e33d7 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -3547,6 +3547,37 @@ static void record_recent_commit(struct commit *commit, void *data)
oid_array_append(&recent_objects, &commit->object.oid);
}
+static int mark_bitmap_preferred_tip(const char *refname,
+ const struct object_id *oid, int flags,
+ void *_data)
+{
+ struct object_id peeled;
+ struct object *object;
+
+ if (!peel_iterated_oid(oid, &peeled))
+ oid = &peeled;
+
+ object = parse_object_or_die(oid, refname);
+ if (object->type == OBJ_COMMIT)
+ object->flags |= NEEDS_BITMAP;
+
+ return 0;
+}
+
+static void mark_bitmap_preferred_tips(void)
+{
+ struct string_list_item *item;
+ const struct string_list *preferred_tips;
+
+ preferred_tips = bitmap_preferred_tips(the_repository);
+ if (!preferred_tips)
+ return;
+
+ for_each_string_list_item(item, preferred_tips) {
+ for_each_ref_in(item->string, mark_bitmap_preferred_tip, NULL);
+ }
+}
+
static void get_object_list(int ac, const char **av)
{
struct rev_info revs;
@@ -3601,6 +3632,9 @@ static void get_object_list(int ac, const char **av)
if (use_delta_islands)
load_delta_islands(the_repository, progress);
+ if (write_bitmap_index)
+ mark_bitmap_preferred_tips();
+
if (prepare_revision_walk(&revs))
die(_("revision walk setup failed"));
mark_edges_uninteresting(&revs, show_edge, sparse);
diff --git a/pack-bitmap.c b/pack-bitmap.c
index b4513f8..3ed1543 100644
--- a/pack-bitmap.c
+++ b/pack-bitmap.c
@@ -13,6 +13,7 @@
#include "repository.h"
#include "object-store.h"
#include "list-objects-filter-options.h"
+#include "config.h"
/*
* An entry on the bitmap index, representing the bitmap for a given
@@ -1351,6 +1352,24 @@ void test_bitmap_walk(struct rev_info *revs)
free_bitmap_index(bitmap_git);
}
+int test_bitmap_commits(struct repository *r)
+{
+ struct bitmap_index *bitmap_git = prepare_bitmap_git(r);
+ struct object_id oid;
+ MAYBE_UNUSED void *value;
+
+ if (!bitmap_git)
+ die("failed to load bitmap indexes");
+
+ kh_foreach(bitmap_git->bitmaps, oid, value, {
+ printf("%s\n", oid_to_hex(&oid));
+ });
+
+ free_bitmap_index(bitmap_git);
+
+ return 0;
+}
+
int rebuild_bitmap(const uint32_t *reposition,
struct ewah_bitmap *source,
struct bitmap *dest)
@@ -1512,3 +1531,8 @@ off_t get_disk_usage_from_bitmap(struct bitmap_index *bitmap_git,
return total;
}
+
+const struct string_list *bitmap_preferred_tips(struct repository *r)
+{
+ return repo_config_get_value_multi(r, "pack.preferbitmaptips");
+}
diff --git a/pack-bitmap.h b/pack-bitmap.h
index 36d9993..78f2b3f 100644
--- a/pack-bitmap.h
+++ b/pack-bitmap.h
@@ -5,6 +5,7 @@
#include "khash.h"
#include "pack.h"
#include "pack-objects.h"
+#include "string-list.h"
struct commit;
struct repository;
@@ -49,6 +50,7 @@ void traverse_bitmap_commit_list(struct bitmap_index *,
struct rev_info *revs,
show_reachable_fn show_reachable);
void test_bitmap_walk(struct rev_info *revs);
+int test_bitmap_commits(struct repository *r);
struct bitmap_index *prepare_bitmap_walk(struct rev_info *revs,
struct list_objects_filter_options *filter);
int reuse_partial_packfile_from_bitmap(struct bitmap_index *,
@@ -90,4 +92,6 @@ void bitmap_writer_finish(struct pack_idx_entry **index,
const char *filename,
uint16_t options);
+const struct string_list *bitmap_preferred_tips(struct repository *r);
+
#endif
diff --git a/t/helper/test-bitmap.c b/t/helper/test-bitmap.c
new file mode 100644
index 0000000..134a1e9
--- /dev/null
+++ b/t/helper/test-bitmap.c
@@ -0,0 +1,24 @@
+#include "test-tool.h"
+#include "cache.h"
+#include "pack-bitmap.h"
+
+static int bitmap_list_commits(void)
+{
+ return test_bitmap_commits(the_repository);
+}
+
+int cmd__bitmap(int argc, const char **argv)
+{
+ setup_git_directory();
+
+ if (argc != 2)
+ goto usage;
+
+ if (!strcmp(argv[1], "list-commits"))
+ return bitmap_list_commits();
+
+usage:
+ usage("\ttest-tool bitmap list-commits");
+
+ return -1;
+}
diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c
index 287aa60..25c6a37 100644
--- a/t/helper/test-tool.c
+++ b/t/helper/test-tool.c
@@ -15,6 +15,7 @@ struct test_cmd {
static struct test_cmd cmds[] = {
{ "advise", cmd__advise_if_enabled },
+ { "bitmap", cmd__bitmap },
{ "bloom", cmd__bloom },
{ "chmtime", cmd__chmtime },
{ "config", cmd__config },
diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h
index 9ea4b31..f03c598 100644
--- a/t/helper/test-tool.h
+++ b/t/helper/test-tool.h
@@ -5,6 +5,7 @@
#include "git-compat-util.h"
int cmd__advise_if_enabled(int argc, const char **argv);
+int cmd__bitmap(int argc, const char **argv);
int cmd__bloom(int argc, const char **argv);
int cmd__chmtime(int argc, const char **argv);
int cmd__config(int argc, const char **argv);
diff --git a/t/t5310-pack-bitmaps.sh b/t/t5310-pack-bitmaps.sh
index 40b9f63..f53efc8 100755
--- a/t/t5310-pack-bitmaps.sh
+++ b/t/t5310-pack-bitmaps.sh
@@ -554,4 +554,42 @@ test_expect_success 'fetch with bitmaps can reuse old base' '
)
'
+test_expect_success 'pack.preferBitmapTips' '
+ git init repo &&
+ test_when_finished "rm -fr repo" &&
+ (
+ cd repo &&
+
+ # create enough commits that not all are receive bitmap
+ # coverage even if they are all at the tip of some reference.
+ test_commit_bulk --message="%s" 103 &&
+
+ git rev-list HEAD >commits.raw &&
+ sort <commits.raw >commits &&
+
+ git log --format="create refs/tags/%s %H" HEAD >refs &&
+ git update-ref --stdin <refs &&
+
+ git repack -adb &&
+ test-tool bitmap list-commits | sort >bitmaps &&
+
+ # remember which commits did not receive bitmaps
+ comm -13 bitmaps commits >before &&
+ test_file_not_empty before &&
+
+ # mark the commits which did not receive bitmaps as preferred,
+ # and generate the bitmap again
+ perl -pe "s{^}{create refs/tags/include/$. }" <before |
+ git update-ref --stdin &&
+ git -c pack.preferBitmapTips=refs/tags/include repack -adb &&
+
+ # finally, check that the commit(s) without bitmap coverage
+ # are not the same ones as before
+ test-tool bitmap list-commits | sort >bitmaps &&
+ comm -13 bitmaps commits >after &&
+
+ ! test_cmp before after
+ )
+'
+
test_done