mirror of
https://github.com/git/git.git
synced 2026-02-28 02:42:52 +00:00
Merge branch 'ps/for-each-ref-in-fixes' into ps/refs-for-each
* ps/for-each-ref-in-fixes: bisect: simplify string_list memory handling bisect: fix misuse of `refs_for_each_ref_in()` pack-bitmap: fix bug with exact ref match in "pack.preferBitmapTips" pack-bitmap: deduplicate logic to iterate over preferred bitmap tips
This commit is contained in:
@@ -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.
|
||||
|
||||
16
bisect.c
16
bisect.c
@@ -1180,8 +1180,7 @@ int estimate_bisect_steps(int all)
|
||||
static int mark_for_removal(const struct reference *ref, void *cb_data)
|
||||
{
|
||||
struct string_list *refs = cb_data;
|
||||
char *bisect_ref = xstrfmt("refs/bisect%s", ref->name);
|
||||
string_list_append(refs, bisect_ref);
|
||||
string_list_append(refs, ref->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1190,16 +1189,15 @@ int bisect_clean_state(void)
|
||||
int result = 0;
|
||||
|
||||
/* There may be some refs packed during bisection */
|
||||
struct string_list refs_for_removal = STRING_LIST_INIT_NODUP;
|
||||
refs_for_each_ref_in(get_main_ref_store(the_repository),
|
||||
"refs/bisect", mark_for_removal,
|
||||
(void *) &refs_for_removal);
|
||||
string_list_append(&refs_for_removal, xstrdup("BISECT_HEAD"));
|
||||
string_list_append(&refs_for_removal, xstrdup("BISECT_EXPECTED_REV"));
|
||||
struct string_list refs_for_removal = STRING_LIST_INIT_DUP;
|
||||
refs_for_each_fullref_in(get_main_ref_store(the_repository),
|
||||
"refs/bisect/", NULL, mark_for_removal,
|
||||
&refs_for_removal);
|
||||
string_list_append(&refs_for_removal, "BISECT_HEAD");
|
||||
string_list_append(&refs_for_removal, "BISECT_EXPECTED_REV");
|
||||
result = refs_delete_refs(get_main_ref_store(the_repository),
|
||||
"bisect: remove", &refs_for_removal,
|
||||
REF_NO_DEREF);
|
||||
refs_for_removal.strdup_strings = 1;
|
||||
string_list_clear(&refs_for_removal, 0);
|
||||
unlink_or_warn(git_path_bisect_ancestors_ok());
|
||||
unlink_or_warn(git_path_bisect_log());
|
||||
|
||||
@@ -4551,22 +4551,6 @@ static int mark_bitmap_preferred_tip(const struct reference *ref, void *data UNU
|
||||
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) {
|
||||
refs_for_each_ref_in(get_main_ref_store(the_repository),
|
||||
item->string, mark_bitmap_preferred_tip,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static inline int is_oid_uninteresting(struct repository *repo,
|
||||
struct object_id *oid)
|
||||
{
|
||||
@@ -4707,7 +4691,8 @@ static void get_object_list(struct rev_info *revs, struct strvec *argv)
|
||||
load_delta_islands(the_repository, progress);
|
||||
|
||||
if (write_bitmap_index)
|
||||
mark_bitmap_preferred_tips();
|
||||
for_each_preferred_bitmap_tip(the_repository, mark_bitmap_preferred_tip,
|
||||
NULL);
|
||||
|
||||
if (!fn_show_object)
|
||||
fn_show_object = show_object;
|
||||
|
||||
@@ -3314,7 +3314,7 @@ int bitmap_is_midx(struct bitmap_index *bitmap_git)
|
||||
return !!bitmap_git->midx;
|
||||
}
|
||||
|
||||
const struct string_list *bitmap_preferred_tips(struct repository *r)
|
||||
static const struct string_list *bitmap_preferred_tips(struct repository *r)
|
||||
{
|
||||
const struct string_list *dest;
|
||||
|
||||
@@ -3323,6 +3323,33 @@ const struct string_list *bitmap_preferred_tips(struct repository *r)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void for_each_preferred_bitmap_tip(struct repository *repo,
|
||||
each_ref_fn cb, void *cb_data)
|
||||
{
|
||||
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),
|
||||
pattern, cb, cb_data);
|
||||
}
|
||||
|
||||
strbuf_release(&buf);
|
||||
}
|
||||
|
||||
int bitmap_is_preferred_refname(struct repository *r, const char *refname)
|
||||
{
|
||||
const struct string_list *preferred_tips = bitmap_preferred_tips(r);
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "khash.h"
|
||||
#include "pack.h"
|
||||
#include "pack-objects.h"
|
||||
#include "refs.h"
|
||||
#include "string-list.h"
|
||||
|
||||
struct commit;
|
||||
@@ -99,6 +100,13 @@ int for_each_bitmapped_object(struct bitmap_index *bitmap_git,
|
||||
show_reachable_fn show_reach,
|
||||
void *payload);
|
||||
|
||||
/*
|
||||
* Iterate over all references that are configured as preferred bitmap tips via
|
||||
* "pack.preferBitmapTips" and invoke the callback on each function.
|
||||
*/
|
||||
void for_each_preferred_bitmap_tip(struct repository *repo,
|
||||
each_ref_fn cb, void *cb_data);
|
||||
|
||||
#define GIT_TEST_PACK_USE_BITMAP_BOUNDARY_TRAVERSAL \
|
||||
"GIT_TEST_PACK_USE_BITMAP_BOUNDARY_TRAVERSAL"
|
||||
|
||||
@@ -182,7 +190,6 @@ char *pack_bitmap_filename(struct packed_git *p);
|
||||
|
||||
int bitmap_is_midx(struct bitmap_index *bitmap_git);
|
||||
|
||||
const struct string_list *bitmap_preferred_tips(struct repository *r);
|
||||
int bitmap_is_preferred_refname(struct repository *r, const char *refname);
|
||||
|
||||
int verify_bitmap_files(struct repository *r);
|
||||
|
||||
@@ -40,7 +40,6 @@ static int midx_snapshot_ref_one(const struct reference *ref, void *_data)
|
||||
void midx_snapshot_refs(struct repository *repo, struct tempfile *f)
|
||||
{
|
||||
struct midx_snapshot_ref_data data;
|
||||
const struct string_list *preferred = bitmap_preferred_tips(repo);
|
||||
|
||||
data.repo = repo;
|
||||
data.f = f;
|
||||
@@ -51,16 +50,9 @@ void midx_snapshot_refs(struct repository *repo, struct tempfile *f)
|
||||
die(_("could not open tempfile %s for writing"),
|
||||
get_tempfile_path(f));
|
||||
|
||||
if (preferred) {
|
||||
struct string_list_item *item;
|
||||
|
||||
data.preferred = 1;
|
||||
for_each_string_list_item(item, preferred)
|
||||
refs_for_each_ref_in(get_main_ref_store(repo),
|
||||
item->string,
|
||||
midx_snapshot_ref_one, &data);
|
||||
data.preferred = 0;
|
||||
}
|
||||
data.preferred = 1;
|
||||
for_each_preferred_bitmap_tip(repo, midx_snapshot_ref_one, &data);
|
||||
data.preferred = 0;
|
||||
|
||||
refs_for_each_ref(get_main_ref_store(repo),
|
||||
midx_snapshot_ref_one, &data);
|
||||
|
||||
@@ -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 &&
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user