Merge branch 'tb/pack-preferred-tips-to-give-bitmap'

A configuration variable has been added to force tips of certain
refs to be given a reachability bitmap.

* tb/pack-preferred-tips-to-give-bitmap:
  builtin/pack-objects.c: respect 'pack.preferBitmapTips'
  t/helper/test-bitmap.c: initial commit
  pack-bitmap: add 'test_bitmap_commits()' helper
This commit is contained in:
Junio C Hamano 2021-04-13 15:28:50 -07:00
commit 0623669fc6
9 changed files with 142 additions and 0 deletions

View File

@ -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`.

View File

@ -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

View File

@ -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);

View File

@ -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");
}

View File

@ -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

24
t/helper/test-bitmap.c Normal file
View File

@ -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;
}

View File

@ -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 },

View File

@ -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);

View File

@ -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