Merge branch 'tb/commit-graph-genv2-upgrade-fix'
There was a bug in the codepath to upgrade generation information in commit-graph from v1 to v2 format, which has been corrected. * tb/commit-graph-genv2-upgrade-fix: commit-graph: fix corrupt upgrade from generation v1 to v2 commit-graph: introduce `repo_find_commit_pos_in_graph()` t5318: demonstrate commit-graph generation v2 corruption
This commit is contained in:
commit
37e4bdd5ee
10
bloom.c
10
bloom.c
@ -30,10 +30,9 @@ static inline unsigned char get_bitmask(uint32_t pos)
|
||||
|
||||
static int load_bloom_filter_from_graph(struct commit_graph *g,
|
||||
struct bloom_filter *filter,
|
||||
struct commit *c)
|
||||
uint32_t graph_pos)
|
||||
{
|
||||
uint32_t lex_pos, start_index, end_index;
|
||||
uint32_t graph_pos = commit_graph_position(c);
|
||||
|
||||
while (graph_pos < g->num_commits_in_base)
|
||||
g = g->base_graph;
|
||||
@ -203,9 +202,10 @@ struct bloom_filter *get_or_compute_bloom_filter(struct repository *r,
|
||||
filter = bloom_filter_slab_at(&bloom_filters, c);
|
||||
|
||||
if (!filter->data) {
|
||||
load_commit_graph_info(r, c);
|
||||
if (commit_graph_position(c) != COMMIT_NOT_FROM_GRAPH)
|
||||
load_bloom_filter_from_graph(r->objects->commit_graph, filter, c);
|
||||
uint32_t graph_pos;
|
||||
if (repo_find_commit_pos_in_graph(r, c, &graph_pos))
|
||||
load_bloom_filter_from_graph(r->objects->commit_graph,
|
||||
filter, graph_pos);
|
||||
}
|
||||
|
||||
if (filter->data && filter->len)
|
||||
|
@ -888,6 +888,14 @@ static int find_commit_pos_in_graph(struct commit *item, struct commit_graph *g,
|
||||
}
|
||||
}
|
||||
|
||||
int repo_find_commit_pos_in_graph(struct repository *r, struct commit *c,
|
||||
uint32_t *pos)
|
||||
{
|
||||
if (!prepare_commit_graph(r))
|
||||
return 0;
|
||||
return find_commit_pos_in_graph(c, r->objects->commit_graph, pos);
|
||||
}
|
||||
|
||||
struct commit *lookup_commit_in_graph(struct repository *repo, const struct object_id *id)
|
||||
{
|
||||
struct commit *commit;
|
||||
@ -945,9 +953,7 @@ int parse_commit_in_graph(struct repository *r, struct commit *item)
|
||||
void load_commit_graph_info(struct repository *r, struct commit *item)
|
||||
{
|
||||
uint32_t pos;
|
||||
if (!prepare_commit_graph(r))
|
||||
return;
|
||||
if (find_commit_pos_in_graph(item, r->objects->commit_graph, &pos))
|
||||
if (repo_find_commit_pos_in_graph(r, item, &pos))
|
||||
fill_commit_graph_info(item, r->objects->commit_graph, pos);
|
||||
}
|
||||
|
||||
|
@ -40,6 +40,21 @@ int open_commit_graph(const char *graph_file, int *fd, struct stat *st);
|
||||
*/
|
||||
int parse_commit_in_graph(struct repository *r, struct commit *item);
|
||||
|
||||
/*
|
||||
* Fills `*pos` with the graph position of `c`, and returns 1 if `c` is
|
||||
* found in the commit-graph belonging to `r`, or 0 otherwise.
|
||||
* Initializes the commit-graph belonging to `r` if it hasn't been
|
||||
* already.
|
||||
*
|
||||
* Note: this is a low-level helper that does not alter any slab data
|
||||
* associated with `c`. Useful in circumstances where the slab data is
|
||||
* already being modified (e.g., writing the commit-graph itself).
|
||||
*
|
||||
* In most cases, callers should use `parse_commit_in_graph()` instead.
|
||||
*/
|
||||
int repo_find_commit_pos_in_graph(struct repository *r, struct commit *c,
|
||||
uint32_t *pos);
|
||||
|
||||
/*
|
||||
* Look up the given commit ID in the commit-graph. This will only return a
|
||||
* commit if the ID exists both in the graph and in the object database such
|
||||
|
@ -812,4 +812,31 @@ test_expect_success 'set up and verify repo with generation data overflow chunk'
|
||||
|
||||
graph_git_behavior 'generation data overflow chunk repo' repo left right
|
||||
|
||||
test_expect_success 'overflow during generation version upgrade' '
|
||||
git init overflow-v2-upgrade &&
|
||||
(
|
||||
cd overflow-v2-upgrade &&
|
||||
|
||||
# This commit will have a date at two seconds past the Epoch,
|
||||
# and a (v1) generation number of 1, since it is a root commit.
|
||||
#
|
||||
# The offset will then be computed as 1-2, which will underflow
|
||||
# to 2^31, which is greater than the v2 offset small limit of
|
||||
# 2^31-1.
|
||||
#
|
||||
# This is sufficient to need a large offset table for the v2
|
||||
# generation numbers.
|
||||
test_commit --date "@2 +0000" base &&
|
||||
git repack -d &&
|
||||
|
||||
# Test that upgrading from generation v1 to v2 correctly
|
||||
# produces the overflow table.
|
||||
git -c commitGraph.generationVersion=1 commit-graph write &&
|
||||
git -c commitGraph.generationVersion=2 commit-graph write \
|
||||
--changed-paths &&
|
||||
|
||||
git rev-list --all
|
||||
)
|
||||
'
|
||||
|
||||
test_done
|
||||
|
Loading…
Reference in New Issue
Block a user