|
|
|
|
@@ -1,4 +1,3 @@
|
|
|
|
|
#define USE_THE_REPOSITORY_VARIABLE
|
|
|
|
|
#define DISABLE_SIGN_COMPARE_WARNINGS
|
|
|
|
|
|
|
|
|
|
#include "git-compat-util.h"
|
|
|
|
|
@@ -29,7 +28,7 @@
|
|
|
|
|
#include "tree.h"
|
|
|
|
|
#include "chunk-format.h"
|
|
|
|
|
|
|
|
|
|
void git_test_write_commit_graph_or_die(void)
|
|
|
|
|
void git_test_write_commit_graph_or_die(struct odb_source *source)
|
|
|
|
|
{
|
|
|
|
|
int flags = 0;
|
|
|
|
|
if (!git_env_bool(GIT_TEST_COMMIT_GRAPH, 0))
|
|
|
|
|
@@ -38,8 +37,7 @@ void git_test_write_commit_graph_or_die(void)
|
|
|
|
|
if (git_env_bool(GIT_TEST_COMMIT_GRAPH_CHANGED_PATHS, 0))
|
|
|
|
|
flags = COMMIT_GRAPH_WRITE_BLOOM_FILTERS;
|
|
|
|
|
|
|
|
|
|
if (write_commit_graph_reachable(the_repository->objects->sources,
|
|
|
|
|
flags, NULL))
|
|
|
|
|
if (write_commit_graph_reachable(source, flags, NULL))
|
|
|
|
|
die("failed to write commit-graph under GIT_TEST_COMMIT_GRAPH");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -54,8 +52,6 @@ void git_test_write_commit_graph_or_die(void)
|
|
|
|
|
#define GRAPH_CHUNKID_BLOOMDATA 0x42444154 /* "BDAT" */
|
|
|
|
|
#define GRAPH_CHUNKID_BASE 0x42415345 /* "BASE" */
|
|
|
|
|
|
|
|
|
|
#define GRAPH_DATA_WIDTH (the_hash_algo->rawsz + 16)
|
|
|
|
|
|
|
|
|
|
#define GRAPH_VERSION_1 0x1
|
|
|
|
|
#define GRAPH_VERSION GRAPH_VERSION_1
|
|
|
|
|
|
|
|
|
|
@@ -67,8 +63,6 @@ void git_test_write_commit_graph_or_die(void)
|
|
|
|
|
|
|
|
|
|
#define GRAPH_HEADER_SIZE 8
|
|
|
|
|
#define GRAPH_FANOUT_SIZE (4 * 256)
|
|
|
|
|
#define GRAPH_MIN_SIZE (GRAPH_HEADER_SIZE + 4 * CHUNK_TOC_ENTRY_SIZE \
|
|
|
|
|
+ GRAPH_FANOUT_SIZE + the_hash_algo->rawsz)
|
|
|
|
|
|
|
|
|
|
#define CORRECTED_COMMIT_DATE_OFFSET_OVERFLOW (1ULL << 31)
|
|
|
|
|
|
|
|
|
|
@@ -81,6 +75,16 @@ define_commit_slab(topo_level_slab, uint32_t);
|
|
|
|
|
define_commit_slab(commit_pos, int);
|
|
|
|
|
static struct commit_pos commit_pos = COMMIT_SLAB_INIT(1, commit_pos);
|
|
|
|
|
|
|
|
|
|
static size_t graph_data_width(const struct git_hash_algo *algop)
|
|
|
|
|
{
|
|
|
|
|
return algop->rawsz + 16;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static size_t graph_min_size(const struct git_hash_algo *algop)
|
|
|
|
|
{
|
|
|
|
|
return GRAPH_HEADER_SIZE + 4 * CHUNK_TOC_ENTRY_SIZE + GRAPH_FANOUT_SIZE + algop->rawsz;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void set_commit_pos(struct repository *r, const struct object_id *oid)
|
|
|
|
|
{
|
|
|
|
|
static int32_t max_pos;
|
|
|
|
|
@@ -249,9 +253,8 @@ int open_commit_graph(const char *graph_file, int *fd, struct stat *st)
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct commit_graph *load_commit_graph_one_fd_st(struct repository *r,
|
|
|
|
|
int fd, struct stat *st,
|
|
|
|
|
struct odb_source *source)
|
|
|
|
|
struct commit_graph *load_commit_graph_one_fd_st(struct odb_source *source,
|
|
|
|
|
int fd, struct stat *st)
|
|
|
|
|
{
|
|
|
|
|
void *graph_map;
|
|
|
|
|
size_t graph_size;
|
|
|
|
|
@@ -259,16 +262,15 @@ struct commit_graph *load_commit_graph_one_fd_st(struct repository *r,
|
|
|
|
|
|
|
|
|
|
graph_size = xsize_t(st->st_size);
|
|
|
|
|
|
|
|
|
|
if (graph_size < GRAPH_MIN_SIZE) {
|
|
|
|
|
if (graph_size < graph_min_size(source->odb->repo->hash_algo)) {
|
|
|
|
|
close(fd);
|
|
|
|
|
error(_("commit-graph file is too small"));
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
graph_map = xmmap(NULL, graph_size, PROT_READ, MAP_PRIVATE, fd, 0);
|
|
|
|
|
close(fd);
|
|
|
|
|
prepare_repo_settings(r);
|
|
|
|
|
ret = parse_commit_graph(&r->settings, graph_map, graph_size);
|
|
|
|
|
|
|
|
|
|
ret = parse_commit_graph(source->odb->repo, graph_map, graph_size);
|
|
|
|
|
if (ret)
|
|
|
|
|
ret->odb_source = source;
|
|
|
|
|
else
|
|
|
|
|
@@ -306,7 +308,7 @@ static int graph_read_oid_lookup(const unsigned char *chunk_start,
|
|
|
|
|
{
|
|
|
|
|
struct commit_graph *g = data;
|
|
|
|
|
g->chunk_oid_lookup = chunk_start;
|
|
|
|
|
if (chunk_size / g->hash_len != g->num_commits)
|
|
|
|
|
if (chunk_size / g->hash_algo->rawsz != g->num_commits)
|
|
|
|
|
return error(_("commit-graph OID lookup chunk is the wrong size"));
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
@@ -315,7 +317,7 @@ static int graph_read_commit_data(const unsigned char *chunk_start,
|
|
|
|
|
size_t chunk_size, void *data)
|
|
|
|
|
{
|
|
|
|
|
struct commit_graph *g = data;
|
|
|
|
|
if (chunk_size / GRAPH_DATA_WIDTH != g->num_commits)
|
|
|
|
|
if (chunk_size / graph_data_width(g->hash_algo) != g->num_commits)
|
|
|
|
|
return error(_("commit-graph commit data chunk is wrong size"));
|
|
|
|
|
g->chunk_commit_data = chunk_start;
|
|
|
|
|
return 0;
|
|
|
|
|
@@ -368,7 +370,7 @@ static int graph_read_bloom_data(const unsigned char *chunk_start,
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct commit_graph *parse_commit_graph(struct repo_settings *s,
|
|
|
|
|
struct commit_graph *parse_commit_graph(struct repository *r,
|
|
|
|
|
void *graph_map, size_t graph_size)
|
|
|
|
|
{
|
|
|
|
|
const unsigned char *data;
|
|
|
|
|
@@ -380,7 +382,7 @@ struct commit_graph *parse_commit_graph(struct repo_settings *s,
|
|
|
|
|
if (!graph_map)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
if (graph_size < GRAPH_MIN_SIZE)
|
|
|
|
|
if (graph_size < graph_min_size(r->hash_algo))
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
data = (const unsigned char *)graph_map;
|
|
|
|
|
@@ -400,22 +402,22 @@ struct commit_graph *parse_commit_graph(struct repo_settings *s,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
hash_version = *(unsigned char*)(data + 5);
|
|
|
|
|
if (hash_version != oid_version(the_hash_algo)) {
|
|
|
|
|
if (hash_version != oid_version(r->hash_algo)) {
|
|
|
|
|
error(_("commit-graph hash version %X does not match version %X"),
|
|
|
|
|
hash_version, oid_version(the_hash_algo));
|
|
|
|
|
hash_version, oid_version(r->hash_algo));
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
graph = alloc_commit_graph();
|
|
|
|
|
|
|
|
|
|
graph->hash_len = the_hash_algo->rawsz;
|
|
|
|
|
graph->hash_algo = r->hash_algo;
|
|
|
|
|
graph->num_chunks = *(unsigned char*)(data + 6);
|
|
|
|
|
graph->data = graph_map;
|
|
|
|
|
graph->data_len = graph_size;
|
|
|
|
|
|
|
|
|
|
if (graph_size < GRAPH_HEADER_SIZE +
|
|
|
|
|
(graph->num_chunks + 1) * CHUNK_TOC_ENTRY_SIZE +
|
|
|
|
|
GRAPH_FANOUT_SIZE + the_hash_algo->rawsz) {
|
|
|
|
|
GRAPH_FANOUT_SIZE + r->hash_algo->rawsz) {
|
|
|
|
|
error(_("commit-graph file is too small to hold %u chunks"),
|
|
|
|
|
graph->num_chunks);
|
|
|
|
|
free(graph);
|
|
|
|
|
@@ -446,7 +448,9 @@ struct commit_graph *parse_commit_graph(struct repo_settings *s,
|
|
|
|
|
pair_chunk(cf, GRAPH_CHUNKID_BASE, &graph->chunk_base_graphs,
|
|
|
|
|
&graph->chunk_base_graphs_size);
|
|
|
|
|
|
|
|
|
|
if (s->commit_graph_generation_version >= 2) {
|
|
|
|
|
prepare_repo_settings(r);
|
|
|
|
|
|
|
|
|
|
if (r->settings.commit_graph_generation_version >= 2) {
|
|
|
|
|
read_chunk(cf, GRAPH_CHUNKID_GENERATION_DATA,
|
|
|
|
|
graph_read_generation_data, graph);
|
|
|
|
|
pair_chunk(cf, GRAPH_CHUNKID_GENERATION_DATA_OVERFLOW,
|
|
|
|
|
@@ -457,7 +461,7 @@ struct commit_graph *parse_commit_graph(struct repo_settings *s,
|
|
|
|
|
graph->read_generation_data = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (s->commit_graph_changed_paths_version) {
|
|
|
|
|
if (r->settings.commit_graph_changed_paths_version) {
|
|
|
|
|
read_chunk(cf, GRAPH_CHUNKID_BLOOMINDEXES,
|
|
|
|
|
graph_read_bloom_index, graph);
|
|
|
|
|
read_chunk(cf, GRAPH_CHUNKID_BLOOMDATA,
|
|
|
|
|
@@ -473,8 +477,8 @@ struct commit_graph *parse_commit_graph(struct repo_settings *s,
|
|
|
|
|
FREE_AND_NULL(graph->bloom_filter_settings);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
oidread(&graph->oid, graph->data + graph->data_len - graph->hash_len,
|
|
|
|
|
the_repository->hash_algo);
|
|
|
|
|
oidread(&graph->oid, graph->data + graph->data_len - graph->hash_algo->rawsz,
|
|
|
|
|
r->hash_algo);
|
|
|
|
|
|
|
|
|
|
free_chunkfile(cf);
|
|
|
|
|
return graph;
|
|
|
|
|
@@ -486,11 +490,9 @@ free_and_return:
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct commit_graph *load_commit_graph_one(struct repository *r,
|
|
|
|
|
const char *graph_file,
|
|
|
|
|
struct odb_source *source)
|
|
|
|
|
static struct commit_graph *load_commit_graph_one(struct odb_source *source,
|
|
|
|
|
const char *graph_file)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
struct stat st;
|
|
|
|
|
int fd;
|
|
|
|
|
struct commit_graph *g;
|
|
|
|
|
@@ -499,19 +501,17 @@ static struct commit_graph *load_commit_graph_one(struct repository *r,
|
|
|
|
|
if (!open_ok)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
g = load_commit_graph_one_fd_st(r, fd, &st, source);
|
|
|
|
|
|
|
|
|
|
g = load_commit_graph_one_fd_st(source, fd, &st);
|
|
|
|
|
if (g)
|
|
|
|
|
g->filename = xstrdup(graph_file);
|
|
|
|
|
|
|
|
|
|
return g;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct commit_graph *load_commit_graph_v1(struct repository *r,
|
|
|
|
|
struct odb_source *source)
|
|
|
|
|
static struct commit_graph *load_commit_graph_v1(struct odb_source *source)
|
|
|
|
|
{
|
|
|
|
|
char *graph_name = get_commit_graph_filename(source);
|
|
|
|
|
struct commit_graph *g = load_commit_graph_one(r, graph_name, source);
|
|
|
|
|
struct commit_graph *g = load_commit_graph_one(source, graph_name);
|
|
|
|
|
free(graph_name);
|
|
|
|
|
|
|
|
|
|
return g;
|
|
|
|
|
@@ -579,7 +579,7 @@ static int add_graph_to_chain(struct commit_graph *g,
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (g->chunk_base_graphs_size / g->hash_len < n) {
|
|
|
|
|
if (g->chunk_base_graphs_size / g->hash_algo->rawsz < n) {
|
|
|
|
|
warning(_("commit-graph base graphs chunk is too small"));
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
@@ -589,8 +589,8 @@ static int add_graph_to_chain(struct commit_graph *g,
|
|
|
|
|
|
|
|
|
|
if (!cur_g ||
|
|
|
|
|
!oideq(&oids[n], &cur_g->oid) ||
|
|
|
|
|
!hasheq(oids[n].hash, g->chunk_base_graphs + st_mult(g->hash_len, n),
|
|
|
|
|
the_repository->hash_algo)) {
|
|
|
|
|
!hasheq(oids[n].hash, g->chunk_base_graphs + st_mult(g->hash_algo->rawsz, n),
|
|
|
|
|
g->hash_algo)) {
|
|
|
|
|
warning(_("commit-graph chain does not match"));
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
@@ -614,7 +614,8 @@ static int add_graph_to_chain(struct commit_graph *g,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int open_commit_graph_chain(const char *chain_file,
|
|
|
|
|
int *fd, struct stat *st)
|
|
|
|
|
int *fd, struct stat *st,
|
|
|
|
|
const struct git_hash_algo *hash_algo)
|
|
|
|
|
{
|
|
|
|
|
*fd = git_open(chain_file);
|
|
|
|
|
if (*fd < 0)
|
|
|
|
|
@@ -623,7 +624,7 @@ int open_commit_graph_chain(const char *chain_file,
|
|
|
|
|
close(*fd);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
if (st->st_size < the_hash_algo->hexsz) {
|
|
|
|
|
if (st->st_size < hash_algo->hexsz) {
|
|
|
|
|
close(*fd);
|
|
|
|
|
if (!st->st_size) {
|
|
|
|
|
/* treat empty files the same as missing */
|
|
|
|
|
@@ -637,7 +638,7 @@ int open_commit_graph_chain(const char *chain_file,
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct commit_graph *load_commit_graph_chain_fd_st(struct repository *r,
|
|
|
|
|
struct commit_graph *load_commit_graph_chain_fd_st(struct object_database *odb,
|
|
|
|
|
int fd, struct stat *st,
|
|
|
|
|
int *incomplete_chain)
|
|
|
|
|
{
|
|
|
|
|
@@ -647,10 +648,10 @@ struct commit_graph *load_commit_graph_chain_fd_st(struct repository *r,
|
|
|
|
|
int i = 0, valid = 1, count;
|
|
|
|
|
FILE *fp = xfdopen(fd, "r");
|
|
|
|
|
|
|
|
|
|
count = st->st_size / (the_hash_algo->hexsz + 1);
|
|
|
|
|
count = st->st_size / (odb->repo->hash_algo->hexsz + 1);
|
|
|
|
|
CALLOC_ARRAY(oids, count);
|
|
|
|
|
|
|
|
|
|
odb_prepare_alternates(r->objects);
|
|
|
|
|
odb_prepare_alternates(odb);
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < count; i++) {
|
|
|
|
|
struct odb_source *source;
|
|
|
|
|
@@ -658,7 +659,7 @@ struct commit_graph *load_commit_graph_chain_fd_st(struct repository *r,
|
|
|
|
|
if (strbuf_getline_lf(&line, fp) == EOF)
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
if (get_oid_hex(line.buf, &oids[i])) {
|
|
|
|
|
if (get_oid_hex_algop(line.buf, &oids[i], odb->repo->hash_algo)) {
|
|
|
|
|
warning(_("invalid commit-graph chain: line '%s' not a hash"),
|
|
|
|
|
line.buf);
|
|
|
|
|
valid = 0;
|
|
|
|
|
@@ -666,9 +667,9 @@ struct commit_graph *load_commit_graph_chain_fd_st(struct repository *r,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
valid = 0;
|
|
|
|
|
for (source = r->objects->sources; source; source = source->next) {
|
|
|
|
|
for (source = odb->sources; source; source = source->next) {
|
|
|
|
|
char *graph_name = get_split_graph_filename(source, line.buf);
|
|
|
|
|
struct commit_graph *g = load_commit_graph_one(r, graph_name, source);
|
|
|
|
|
struct commit_graph *g = load_commit_graph_one(source, graph_name);
|
|
|
|
|
|
|
|
|
|
free(graph_name);
|
|
|
|
|
|
|
|
|
|
@@ -701,50 +702,38 @@ struct commit_graph *load_commit_graph_chain_fd_st(struct repository *r,
|
|
|
|
|
return graph_chain;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct commit_graph *load_commit_graph_chain(struct repository *r,
|
|
|
|
|
struct odb_source *source)
|
|
|
|
|
static struct commit_graph *load_commit_graph_chain(struct odb_source *source)
|
|
|
|
|
{
|
|
|
|
|
char *chain_file = get_commit_graph_chain_filename(source);
|
|
|
|
|
struct stat st;
|
|
|
|
|
int fd;
|
|
|
|
|
struct commit_graph *g = NULL;
|
|
|
|
|
|
|
|
|
|
if (open_commit_graph_chain(chain_file, &fd, &st)) {
|
|
|
|
|
if (open_commit_graph_chain(chain_file, &fd, &st, source->odb->repo->hash_algo)) {
|
|
|
|
|
int incomplete;
|
|
|
|
|
/* ownership of fd is taken over by load function */
|
|
|
|
|
g = load_commit_graph_chain_fd_st(r, fd, &st, &incomplete);
|
|
|
|
|
g = load_commit_graph_chain_fd_st(source->odb, fd, &st, &incomplete);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
free(chain_file);
|
|
|
|
|
return g;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct commit_graph *read_commit_graph_one(struct repository *r,
|
|
|
|
|
struct odb_source *source)
|
|
|
|
|
struct commit_graph *read_commit_graph_one(struct odb_source *source)
|
|
|
|
|
{
|
|
|
|
|
struct commit_graph *g = load_commit_graph_v1(r, source);
|
|
|
|
|
struct commit_graph *g = load_commit_graph_v1(source);
|
|
|
|
|
|
|
|
|
|
if (!g)
|
|
|
|
|
g = load_commit_graph_chain(r, source);
|
|
|
|
|
g = load_commit_graph_chain(source);
|
|
|
|
|
|
|
|
|
|
return g;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void prepare_commit_graph_one(struct repository *r,
|
|
|
|
|
struct odb_source *source)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
if (r->objects->commit_graph)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
r->objects->commit_graph = read_commit_graph_one(r, source);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Return 1 if commit_graph is non-NULL, and 0 otherwise.
|
|
|
|
|
*
|
|
|
|
|
* On the first invocation, this function attempts to load the commit
|
|
|
|
|
* graph if the_repository is configured to have one.
|
|
|
|
|
* graph if the repository is configured to have one.
|
|
|
|
|
*/
|
|
|
|
|
static int prepare_commit_graph(struct repository *r)
|
|
|
|
|
{
|
|
|
|
|
@@ -780,10 +769,12 @@ static int prepare_commit_graph(struct repository *r)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
odb_prepare_alternates(r->objects);
|
|
|
|
|
for (source = r->objects->sources;
|
|
|
|
|
!r->objects->commit_graph && source;
|
|
|
|
|
source = source->next)
|
|
|
|
|
prepare_commit_graph_one(r, source);
|
|
|
|
|
for (source = r->objects->sources; source; source = source->next) {
|
|
|
|
|
r->objects->commit_graph = read_commit_graph_one(source);
|
|
|
|
|
if (r->objects->commit_graph)
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return !!r->objects->commit_graph;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -800,7 +791,7 @@ int generation_numbers_enabled(struct repository *r)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
first_generation = get_be32(g->chunk_commit_data +
|
|
|
|
|
g->hash_len + 8) >> 2;
|
|
|
|
|
g->hash_algo->rawsz + 8) >> 2;
|
|
|
|
|
|
|
|
|
|
return !!first_generation;
|
|
|
|
|
}
|
|
|
|
|
@@ -844,7 +835,7 @@ void close_commit_graph(struct object_database *o)
|
|
|
|
|
static int bsearch_graph(struct commit_graph *g, const struct object_id *oid, uint32_t *pos)
|
|
|
|
|
{
|
|
|
|
|
return bsearch_hash(oid->hash, g->chunk_oid_fanout,
|
|
|
|
|
g->chunk_oid_lookup, g->hash_len, pos);
|
|
|
|
|
g->chunk_oid_lookup, g->hash_algo->rawsz, pos);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void load_oid_from_graph(struct commit_graph *g,
|
|
|
|
|
@@ -864,12 +855,11 @@ static void load_oid_from_graph(struct commit_graph *g,
|
|
|
|
|
|
|
|
|
|
lex_index = pos - g->num_commits_in_base;
|
|
|
|
|
|
|
|
|
|
oidread(oid, g->chunk_oid_lookup + st_mult(g->hash_len, lex_index),
|
|
|
|
|
the_repository->hash_algo);
|
|
|
|
|
oidread(oid, g->chunk_oid_lookup + st_mult(g->hash_algo->rawsz, lex_index),
|
|
|
|
|
g->hash_algo);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct commit_list **insert_parent_or_die(struct repository *r,
|
|
|
|
|
struct commit_graph *g,
|
|
|
|
|
static struct commit_list **insert_parent_or_die(struct commit_graph *g,
|
|
|
|
|
uint32_t pos,
|
|
|
|
|
struct commit_list **pptr)
|
|
|
|
|
{
|
|
|
|
|
@@ -880,7 +870,7 @@ static struct commit_list **insert_parent_or_die(struct repository *r,
|
|
|
|
|
die("invalid parent position %"PRIu32, pos);
|
|
|
|
|
|
|
|
|
|
load_oid_from_graph(g, pos, &oid);
|
|
|
|
|
c = lookup_commit(r, &oid);
|
|
|
|
|
c = lookup_commit(g->odb_source->odb->repo, &oid);
|
|
|
|
|
if (!c)
|
|
|
|
|
die(_("could not find commit %s"), oid_to_hex(&oid));
|
|
|
|
|
commit_graph_data_at(c)->graph_pos = pos;
|
|
|
|
|
@@ -901,13 +891,13 @@ static void fill_commit_graph_info(struct commit *item, struct commit_graph *g,
|
|
|
|
|
die(_("invalid commit position. commit-graph is likely corrupt"));
|
|
|
|
|
|
|
|
|
|
lex_index = pos - g->num_commits_in_base;
|
|
|
|
|
commit_data = g->chunk_commit_data + st_mult(GRAPH_DATA_WIDTH, lex_index);
|
|
|
|
|
commit_data = g->chunk_commit_data + st_mult(graph_data_width(g->hash_algo), lex_index);
|
|
|
|
|
|
|
|
|
|
graph_data = commit_graph_data_at(item);
|
|
|
|
|
graph_data->graph_pos = pos;
|
|
|
|
|
|
|
|
|
|
date_high = get_be32(commit_data + g->hash_len + 8) & 0x3;
|
|
|
|
|
date_low = get_be32(commit_data + g->hash_len + 12);
|
|
|
|
|
date_high = get_be32(commit_data + g->hash_algo->rawsz + 8) & 0x3;
|
|
|
|
|
date_low = get_be32(commit_data + g->hash_algo->rawsz + 12);
|
|
|
|
|
item->date = (timestamp_t)((date_high << 32) | date_low);
|
|
|
|
|
|
|
|
|
|
if (g->read_generation_data) {
|
|
|
|
|
@@ -925,10 +915,10 @@ static void fill_commit_graph_info(struct commit *item, struct commit_graph *g,
|
|
|
|
|
} else
|
|
|
|
|
graph_data->generation = item->date + offset;
|
|
|
|
|
} else
|
|
|
|
|
graph_data->generation = get_be32(commit_data + g->hash_len + 8) >> 2;
|
|
|
|
|
graph_data->generation = get_be32(commit_data + g->hash_algo->rawsz + 8) >> 2;
|
|
|
|
|
|
|
|
|
|
if (g->topo_levels)
|
|
|
|
|
*topo_level_slab_at(g->topo_levels, item) = get_be32(commit_data + g->hash_len + 8) >> 2;
|
|
|
|
|
*topo_level_slab_at(g->topo_levels, item) = get_be32(commit_data + g->hash_algo->rawsz + 8) >> 2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void set_commit_tree(struct commit *c, struct tree *t)
|
|
|
|
|
@@ -936,8 +926,7 @@ static inline void set_commit_tree(struct commit *c, struct tree *t)
|
|
|
|
|
c->maybe_tree = t;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int fill_commit_in_graph(struct repository *r,
|
|
|
|
|
struct commit *item,
|
|
|
|
|
static int fill_commit_in_graph(struct commit *item,
|
|
|
|
|
struct commit_graph *g, uint32_t pos)
|
|
|
|
|
{
|
|
|
|
|
uint32_t edge_value;
|
|
|
|
|
@@ -952,7 +941,7 @@ static int fill_commit_in_graph(struct repository *r,
|
|
|
|
|
fill_commit_graph_info(item, g, pos);
|
|
|
|
|
|
|
|
|
|
lex_index = pos - g->num_commits_in_base;
|
|
|
|
|
commit_data = g->chunk_commit_data + st_mult(g->hash_len + 16, lex_index);
|
|
|
|
|
commit_data = g->chunk_commit_data + st_mult(g->hash_algo->rawsz + 16, lex_index);
|
|
|
|
|
|
|
|
|
|
item->object.parsed = 1;
|
|
|
|
|
|
|
|
|
|
@@ -960,16 +949,16 @@ static int fill_commit_in_graph(struct repository *r,
|
|
|
|
|
|
|
|
|
|
pptr = &item->parents;
|
|
|
|
|
|
|
|
|
|
edge_value = get_be32(commit_data + g->hash_len);
|
|
|
|
|
edge_value = get_be32(commit_data + g->hash_algo->rawsz);
|
|
|
|
|
if (edge_value == GRAPH_PARENT_NONE)
|
|
|
|
|
return 1;
|
|
|
|
|
pptr = insert_parent_or_die(r, g, edge_value, pptr);
|
|
|
|
|
pptr = insert_parent_or_die(g, edge_value, pptr);
|
|
|
|
|
|
|
|
|
|
edge_value = get_be32(commit_data + g->hash_len + 4);
|
|
|
|
|
edge_value = get_be32(commit_data + g->hash_algo->rawsz + 4);
|
|
|
|
|
if (edge_value == GRAPH_PARENT_NONE)
|
|
|
|
|
return 1;
|
|
|
|
|
if (!(edge_value & GRAPH_EXTRA_EDGES_NEEDED)) {
|
|
|
|
|
pptr = insert_parent_or_die(r, g, edge_value, pptr);
|
|
|
|
|
pptr = insert_parent_or_die(g, edge_value, pptr);
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -984,7 +973,7 @@ static int fill_commit_in_graph(struct repository *r,
|
|
|
|
|
}
|
|
|
|
|
edge_value = get_be32(g->chunk_extra_edges +
|
|
|
|
|
sizeof(uint32_t) * parent_data_pos);
|
|
|
|
|
pptr = insert_parent_or_die(r, g,
|
|
|
|
|
pptr = insert_parent_or_die(g,
|
|
|
|
|
edge_value & GRAPH_EDGE_LAST_MASK,
|
|
|
|
|
pptr);
|
|
|
|
|
parent_data_pos++;
|
|
|
|
|
@@ -1050,14 +1039,13 @@ struct commit *lookup_commit_in_graph(struct repository *repo, const struct obje
|
|
|
|
|
if (commit->object.parsed)
|
|
|
|
|
return commit;
|
|
|
|
|
|
|
|
|
|
if (!fill_commit_in_graph(repo, commit, repo->objects->commit_graph, pos))
|
|
|
|
|
if (!fill_commit_in_graph(commit, repo->objects->commit_graph, pos))
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
return commit;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int parse_commit_in_graph_one(struct repository *r,
|
|
|
|
|
struct commit_graph *g,
|
|
|
|
|
static int parse_commit_in_graph_one(struct commit_graph *g,
|
|
|
|
|
struct commit *item)
|
|
|
|
|
{
|
|
|
|
|
uint32_t pos;
|
|
|
|
|
@@ -1066,7 +1054,7 @@ static int parse_commit_in_graph_one(struct repository *r,
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
if (find_commit_pos_in_graph(item, g, &pos))
|
|
|
|
|
return fill_commit_in_graph(r, item, g, pos);
|
|
|
|
|
return fill_commit_in_graph(item, g, pos);
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
@@ -1083,7 +1071,7 @@ int parse_commit_in_graph(struct repository *r, struct commit *item)
|
|
|
|
|
|
|
|
|
|
if (!prepare_commit_graph(r))
|
|
|
|
|
return 0;
|
|
|
|
|
return parse_commit_in_graph_one(r, r->objects->commit_graph, item);
|
|
|
|
|
return parse_commit_in_graph_one(r->objects->commit_graph, item);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void load_commit_graph_info(struct repository *r, struct commit *item)
|
|
|
|
|
@@ -1093,8 +1081,7 @@ void load_commit_graph_info(struct repository *r, struct commit *item)
|
|
|
|
|
fill_commit_graph_info(item, r->objects->commit_graph, pos);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct tree *load_tree_for_commit(struct repository *r,
|
|
|
|
|
struct commit_graph *g,
|
|
|
|
|
static struct tree *load_tree_for_commit(struct commit_graph *g,
|
|
|
|
|
struct commit *c)
|
|
|
|
|
{
|
|
|
|
|
struct object_id oid;
|
|
|
|
|
@@ -1105,16 +1092,16 @@ static struct tree *load_tree_for_commit(struct repository *r,
|
|
|
|
|
g = g->base_graph;
|
|
|
|
|
|
|
|
|
|
commit_data = g->chunk_commit_data +
|
|
|
|
|
st_mult(GRAPH_DATA_WIDTH, graph_pos - g->num_commits_in_base);
|
|
|
|
|
st_mult(graph_data_width(g->hash_algo),
|
|
|
|
|
graph_pos - g->num_commits_in_base);
|
|
|
|
|
|
|
|
|
|
oidread(&oid, commit_data, the_repository->hash_algo);
|
|
|
|
|
set_commit_tree(c, lookup_tree(r, &oid));
|
|
|
|
|
oidread(&oid, commit_data, g->hash_algo);
|
|
|
|
|
set_commit_tree(c, lookup_tree(g->odb_source->odb->repo, &oid));
|
|
|
|
|
|
|
|
|
|
return c->maybe_tree;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct tree *get_commit_tree_in_graph_one(struct repository *r,
|
|
|
|
|
struct commit_graph *g,
|
|
|
|
|
static struct tree *get_commit_tree_in_graph_one(struct commit_graph *g,
|
|
|
|
|
const struct commit *c)
|
|
|
|
|
{
|
|
|
|
|
if (c->maybe_tree)
|
|
|
|
|
@@ -1122,12 +1109,12 @@ static struct tree *get_commit_tree_in_graph_one(struct repository *r,
|
|
|
|
|
if (commit_graph_position(c) == COMMIT_NOT_FROM_GRAPH)
|
|
|
|
|
BUG("get_commit_tree_in_graph_one called from non-commit-graph commit");
|
|
|
|
|
|
|
|
|
|
return load_tree_for_commit(r, g, (struct commit *)c);
|
|
|
|
|
return load_tree_for_commit(g, (struct commit *)c);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct tree *get_commit_tree_in_graph(struct repository *r, const struct commit *c)
|
|
|
|
|
{
|
|
|
|
|
return get_commit_tree_in_graph_one(r, r->objects->commit_graph, c);
|
|
|
|
|
return get_commit_tree_in_graph_one(r->objects->commit_graph, c);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct packed_commit_list {
|
|
|
|
|
@@ -1213,7 +1200,7 @@ static int write_graph_chunk_oids(struct hashfile *f,
|
|
|
|
|
int count;
|
|
|
|
|
for (count = 0; count < ctx->commits.nr; count++, list++) {
|
|
|
|
|
display_progress(ctx->progress, ++ctx->progress_cnt);
|
|
|
|
|
hashwrite(f, (*list)->object.oid.hash, the_hash_algo->rawsz);
|
|
|
|
|
hashwrite(f, (*list)->object.oid.hash, f->algop->rawsz);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
@@ -1244,7 +1231,7 @@ static int write_graph_chunk_data(struct hashfile *f,
|
|
|
|
|
die(_("unable to parse commit %s"),
|
|
|
|
|
oid_to_hex(&(*list)->object.oid));
|
|
|
|
|
tree = get_commit_tree_oid(*list);
|
|
|
|
|
hashwrite(f, tree->hash, the_hash_algo->rawsz);
|
|
|
|
|
hashwrite(f, tree->hash, ctx->r->hash_algo->rawsz);
|
|
|
|
|
|
|
|
|
|
parent = (*list)->parents;
|
|
|
|
|
|
|
|
|
|
@@ -1534,7 +1521,7 @@ static void close_reachable(struct write_commit_graph_context *ctx)
|
|
|
|
|
|
|
|
|
|
if (ctx->report_progress)
|
|
|
|
|
ctx->progress = start_delayed_progress(
|
|
|
|
|
the_repository,
|
|
|
|
|
ctx->r,
|
|
|
|
|
_("Loading known commits in commit graph"),
|
|
|
|
|
ctx->oids.nr);
|
|
|
|
|
for (i = 0; i < ctx->oids.nr; i++) {
|
|
|
|
|
@@ -1552,7 +1539,7 @@ static void close_reachable(struct write_commit_graph_context *ctx)
|
|
|
|
|
*/
|
|
|
|
|
if (ctx->report_progress)
|
|
|
|
|
ctx->progress = start_delayed_progress(
|
|
|
|
|
the_repository,
|
|
|
|
|
ctx->r,
|
|
|
|
|
_("Expanding reachable commits in commit graph"),
|
|
|
|
|
0);
|
|
|
|
|
for (i = 0; i < ctx->oids.nr; i++) {
|
|
|
|
|
@@ -1573,7 +1560,7 @@ static void close_reachable(struct write_commit_graph_context *ctx)
|
|
|
|
|
|
|
|
|
|
if (ctx->report_progress)
|
|
|
|
|
ctx->progress = start_delayed_progress(
|
|
|
|
|
the_repository,
|
|
|
|
|
ctx->r,
|
|
|
|
|
_("Clearing commit marks in commit graph"),
|
|
|
|
|
ctx->oids.nr);
|
|
|
|
|
for (i = 0; i < ctx->oids.nr; i++) {
|
|
|
|
|
@@ -1691,7 +1678,7 @@ static void compute_topological_levels(struct write_commit_graph_context *ctx)
|
|
|
|
|
if (ctx->report_progress)
|
|
|
|
|
info.progress = ctx->progress
|
|
|
|
|
= start_delayed_progress(
|
|
|
|
|
the_repository,
|
|
|
|
|
ctx->r,
|
|
|
|
|
_("Computing commit graph topological levels"),
|
|
|
|
|
ctx->commits.nr);
|
|
|
|
|
|
|
|
|
|
@@ -1726,7 +1713,7 @@ static void compute_generation_numbers(struct write_commit_graph_context *ctx)
|
|
|
|
|
if (ctx->report_progress)
|
|
|
|
|
info.progress = ctx->progress
|
|
|
|
|
= start_delayed_progress(
|
|
|
|
|
the_repository,
|
|
|
|
|
ctx->r,
|
|
|
|
|
_("Computing commit graph generation numbers"),
|
|
|
|
|
ctx->commits.nr);
|
|
|
|
|
|
|
|
|
|
@@ -1803,7 +1790,7 @@ static void compute_bloom_filters(struct write_commit_graph_context *ctx)
|
|
|
|
|
|
|
|
|
|
if (ctx->report_progress)
|
|
|
|
|
progress = start_delayed_progress(
|
|
|
|
|
the_repository,
|
|
|
|
|
ctx->r,
|
|
|
|
|
_("Computing commit changed paths Bloom filters"),
|
|
|
|
|
ctx->commits.nr);
|
|
|
|
|
|
|
|
|
|
@@ -1849,6 +1836,7 @@ static void compute_bloom_filters(struct write_commit_graph_context *ctx)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct refs_cb_data {
|
|
|
|
|
struct repository *repo;
|
|
|
|
|
struct oidset *commits;
|
|
|
|
|
struct progress *progress;
|
|
|
|
|
};
|
|
|
|
|
@@ -1861,9 +1849,9 @@ static int add_ref_to_set(const char *refname UNUSED,
|
|
|
|
|
struct object_id peeled;
|
|
|
|
|
struct refs_cb_data *data = (struct refs_cb_data *)cb_data;
|
|
|
|
|
|
|
|
|
|
if (!peel_iterated_oid(the_repository, oid, &peeled))
|
|
|
|
|
if (!peel_iterated_oid(data->repo, oid, &peeled))
|
|
|
|
|
oid = &peeled;
|
|
|
|
|
if (odb_read_object_info(the_repository->objects, oid, NULL) == OBJ_COMMIT)
|
|
|
|
|
if (odb_read_object_info(data->repo->objects, oid, NULL) == OBJ_COMMIT)
|
|
|
|
|
oidset_insert(data->commits, oid);
|
|
|
|
|
|
|
|
|
|
display_progress(data->progress, oidset_size(data->commits));
|
|
|
|
|
@@ -1880,13 +1868,15 @@ int write_commit_graph_reachable(struct odb_source *source,
|
|
|
|
|
int result;
|
|
|
|
|
|
|
|
|
|
memset(&data, 0, sizeof(data));
|
|
|
|
|
data.repo = source->odb->repo;
|
|
|
|
|
data.commits = &commits;
|
|
|
|
|
|
|
|
|
|
if (flags & COMMIT_GRAPH_WRITE_PROGRESS)
|
|
|
|
|
data.progress = start_delayed_progress(
|
|
|
|
|
the_repository,
|
|
|
|
|
source->odb->repo,
|
|
|
|
|
_("Collecting referenced commits"), 0);
|
|
|
|
|
|
|
|
|
|
refs_for_each_ref(get_main_ref_store(the_repository), add_ref_to_set,
|
|
|
|
|
refs_for_each_ref(get_main_ref_store(source->odb->repo), add_ref_to_set,
|
|
|
|
|
&data);
|
|
|
|
|
|
|
|
|
|
stop_progress(&data.progress);
|
|
|
|
|
@@ -1915,7 +1905,7 @@ static int fill_oids_from_packs(struct write_commit_graph_context *ctx,
|
|
|
|
|
"Finding commits for commit graph in %"PRIuMAX" packs",
|
|
|
|
|
pack_indexes->nr),
|
|
|
|
|
(uintmax_t)pack_indexes->nr);
|
|
|
|
|
ctx->progress = start_delayed_progress(the_repository,
|
|
|
|
|
ctx->progress = start_delayed_progress(ctx->r,
|
|
|
|
|
progress_title.buf, 0);
|
|
|
|
|
ctx->progress_done = 0;
|
|
|
|
|
}
|
|
|
|
|
@@ -1969,7 +1959,7 @@ static void fill_oids_from_all_packs(struct write_commit_graph_context *ctx)
|
|
|
|
|
{
|
|
|
|
|
if (ctx->report_progress)
|
|
|
|
|
ctx->progress = start_delayed_progress(
|
|
|
|
|
the_repository,
|
|
|
|
|
ctx->r,
|
|
|
|
|
_("Finding commits for commit graph among packed objects"),
|
|
|
|
|
ctx->approx_nr_objects);
|
|
|
|
|
for_each_packed_object(ctx->r, add_packed_commits, ctx,
|
|
|
|
|
@@ -1988,7 +1978,7 @@ static void copy_oids_to_commits(struct write_commit_graph_context *ctx)
|
|
|
|
|
ctx->num_extra_edges = 0;
|
|
|
|
|
if (ctx->report_progress)
|
|
|
|
|
ctx->progress = start_delayed_progress(
|
|
|
|
|
the_repository,
|
|
|
|
|
ctx->r,
|
|
|
|
|
_("Finding extra edges in commit graph"),
|
|
|
|
|
ctx->oids.nr);
|
|
|
|
|
oid_array_sort(&ctx->oids);
|
|
|
|
|
@@ -2027,7 +2017,7 @@ static int write_graph_chunk_base_1(struct hashfile *f,
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
num = write_graph_chunk_base_1(f, g->base_graph);
|
|
|
|
|
hashwrite(f, g->oid.hash, the_hash_algo->rawsz);
|
|
|
|
|
hashwrite(f, g->oid.hash, g->hash_algo->rawsz);
|
|
|
|
|
return num + 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -2051,7 +2041,7 @@ static int write_commit_graph_file(struct write_commit_graph_context *ctx)
|
|
|
|
|
struct hashfile *f;
|
|
|
|
|
struct tempfile *graph_layer; /* when ctx->split is non-zero */
|
|
|
|
|
struct lock_file lk = LOCK_INIT;
|
|
|
|
|
const unsigned hashsz = the_hash_algo->rawsz;
|
|
|
|
|
const unsigned hashsz = ctx->r->hash_algo->rawsz;
|
|
|
|
|
struct strbuf progress_title = STRBUF_INIT;
|
|
|
|
|
struct chunkfile *cf;
|
|
|
|
|
unsigned char file_hash[GIT_MAX_RAWSZ];
|
|
|
|
|
@@ -2067,7 +2057,7 @@ static int write_commit_graph_file(struct write_commit_graph_context *ctx)
|
|
|
|
|
ctx->graph_name = get_commit_graph_filename(ctx->odb_source);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (safe_create_leading_directories(the_repository, ctx->graph_name)) {
|
|
|
|
|
if (safe_create_leading_directories(ctx->r, ctx->graph_name)) {
|
|
|
|
|
error(_("unable to create leading directories of %s"),
|
|
|
|
|
ctx->graph_name);
|
|
|
|
|
return -1;
|
|
|
|
|
@@ -2086,18 +2076,18 @@ static int write_commit_graph_file(struct write_commit_graph_context *ctx)
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (adjust_shared_perm(the_repository, get_tempfile_path(graph_layer))) {
|
|
|
|
|
if (adjust_shared_perm(ctx->r, get_tempfile_path(graph_layer))) {
|
|
|
|
|
error(_("unable to adjust shared permissions for '%s'"),
|
|
|
|
|
get_tempfile_path(graph_layer));
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
f = hashfd(the_repository->hash_algo,
|
|
|
|
|
f = hashfd(ctx->r->hash_algo,
|
|
|
|
|
get_tempfile_fd(graph_layer), get_tempfile_path(graph_layer));
|
|
|
|
|
} else {
|
|
|
|
|
hold_lock_file_for_update_mode(&lk, ctx->graph_name,
|
|
|
|
|
LOCK_DIE_ON_ERROR, 0444);
|
|
|
|
|
f = hashfd(the_repository->hash_algo,
|
|
|
|
|
f = hashfd(ctx->r->hash_algo,
|
|
|
|
|
get_lock_file_fd(&lk), get_lock_file_path(&lk));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -2139,7 +2129,7 @@ static int write_commit_graph_file(struct write_commit_graph_context *ctx)
|
|
|
|
|
hashwrite_be32(f, GRAPH_SIGNATURE);
|
|
|
|
|
|
|
|
|
|
hashwrite_u8(f, GRAPH_VERSION);
|
|
|
|
|
hashwrite_u8(f, oid_version(the_hash_algo));
|
|
|
|
|
hashwrite_u8(f, oid_version(ctx->r->hash_algo));
|
|
|
|
|
hashwrite_u8(f, get_num_chunks(cf));
|
|
|
|
|
hashwrite_u8(f, ctx->num_commit_graphs_after - 1);
|
|
|
|
|
|
|
|
|
|
@@ -2150,7 +2140,7 @@ static int write_commit_graph_file(struct write_commit_graph_context *ctx)
|
|
|
|
|
get_num_chunks(cf)),
|
|
|
|
|
get_num_chunks(cf));
|
|
|
|
|
ctx->progress = start_delayed_progress(
|
|
|
|
|
the_repository,
|
|
|
|
|
ctx->r,
|
|
|
|
|
progress_title.buf,
|
|
|
|
|
st_mult(get_num_chunks(cf), ctx->commits.nr));
|
|
|
|
|
}
|
|
|
|
|
@@ -2208,7 +2198,8 @@ static int write_commit_graph_file(struct write_commit_graph_context *ctx)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
free(ctx->commit_graph_hash_after[ctx->num_commit_graphs_after - 1]);
|
|
|
|
|
ctx->commit_graph_hash_after[ctx->num_commit_graphs_after - 1] = xstrdup(hash_to_hex(file_hash));
|
|
|
|
|
ctx->commit_graph_hash_after[ctx->num_commit_graphs_after - 1] =
|
|
|
|
|
xstrdup(hash_to_hex_algop(file_hash, ctx->r->hash_algo));
|
|
|
|
|
final_graph_name = get_split_graph_filename(ctx->odb_source,
|
|
|
|
|
ctx->commit_graph_hash_after[ctx->num_commit_graphs_after - 1]);
|
|
|
|
|
free(ctx->commit_graph_filenames_after[ctx->num_commit_graphs_after - 1]);
|
|
|
|
|
@@ -2363,7 +2354,7 @@ static void sort_and_scan_merged_commits(struct write_commit_graph_context *ctx)
|
|
|
|
|
|
|
|
|
|
if (ctx->report_progress)
|
|
|
|
|
ctx->progress = start_delayed_progress(
|
|
|
|
|
the_repository,
|
|
|
|
|
ctx->r,
|
|
|
|
|
_("Scanning merged commits"),
|
|
|
|
|
ctx->commits.nr);
|
|
|
|
|
|
|
|
|
|
@@ -2408,7 +2399,7 @@ static void merge_commit_graphs(struct write_commit_graph_context *ctx)
|
|
|
|
|
current_graph_number--;
|
|
|
|
|
|
|
|
|
|
if (ctx->report_progress)
|
|
|
|
|
ctx->progress = start_delayed_progress(the_repository,
|
|
|
|
|
ctx->progress = start_delayed_progress(ctx->r,
|
|
|
|
|
_("Merging commit-graph"), 0);
|
|
|
|
|
|
|
|
|
|
merge_commit_graph(ctx, g);
|
|
|
|
|
@@ -2511,7 +2502,7 @@ int write_commit_graph(struct odb_source *source,
|
|
|
|
|
enum commit_graph_write_flags flags,
|
|
|
|
|
const struct commit_graph_opts *opts)
|
|
|
|
|
{
|
|
|
|
|
struct repository *r = the_repository;
|
|
|
|
|
struct repository *r = source->odb->repo;
|
|
|
|
|
struct write_commit_graph_context ctx = {
|
|
|
|
|
.r = r,
|
|
|
|
|
.odb_source = source,
|
|
|
|
|
@@ -2611,14 +2602,14 @@ int write_commit_graph(struct odb_source *source,
|
|
|
|
|
replace = ctx.opts->split_flags & COMMIT_GRAPH_SPLIT_REPLACE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ctx.approx_nr_objects = repo_approximate_object_count(the_repository);
|
|
|
|
|
ctx.approx_nr_objects = repo_approximate_object_count(r);
|
|
|
|
|
|
|
|
|
|
if (ctx.append && ctx.r->objects->commit_graph) {
|
|
|
|
|
struct commit_graph *g = ctx.r->objects->commit_graph;
|
|
|
|
|
for (i = 0; i < g->num_commits; i++) {
|
|
|
|
|
struct object_id oid;
|
|
|
|
|
oidread(&oid, g->chunk_oid_lookup + st_mult(g->hash_len, i),
|
|
|
|
|
the_repository->hash_algo);
|
|
|
|
|
oidread(&oid, g->chunk_oid_lookup + st_mult(g->hash_algo->rawsz, i),
|
|
|
|
|
r->hash_algo);
|
|
|
|
|
oid_array_append(&ctx.oids, &oid);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@@ -2726,15 +2717,15 @@ static void graph_report(const char *fmt, ...)
|
|
|
|
|
|
|
|
|
|
static int commit_graph_checksum_valid(struct commit_graph *g)
|
|
|
|
|
{
|
|
|
|
|
return hashfile_checksum_valid(the_repository->hash_algo,
|
|
|
|
|
return hashfile_checksum_valid(g->hash_algo,
|
|
|
|
|
g->data, g->data_len);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int verify_one_commit_graph(struct repository *r,
|
|
|
|
|
struct commit_graph *g,
|
|
|
|
|
static int verify_one_commit_graph(struct commit_graph *g,
|
|
|
|
|
struct progress *progress,
|
|
|
|
|
uint64_t *seen)
|
|
|
|
|
{
|
|
|
|
|
struct repository *r = g->odb_source->odb->repo;
|
|
|
|
|
uint32_t i, cur_fanout_pos = 0;
|
|
|
|
|
struct object_id prev_oid, cur_oid;
|
|
|
|
|
struct commit *seen_gen_zero = NULL;
|
|
|
|
|
@@ -2748,8 +2739,8 @@ static int verify_one_commit_graph(struct repository *r,
|
|
|
|
|
for (i = 0; i < g->num_commits; i++) {
|
|
|
|
|
struct commit *graph_commit;
|
|
|
|
|
|
|
|
|
|
oidread(&cur_oid, g->chunk_oid_lookup + st_mult(g->hash_len, i),
|
|
|
|
|
the_repository->hash_algo);
|
|
|
|
|
oidread(&cur_oid, g->chunk_oid_lookup + st_mult(g->hash_algo->rawsz, i),
|
|
|
|
|
g->hash_algo);
|
|
|
|
|
|
|
|
|
|
if (i && oidcmp(&prev_oid, &cur_oid) >= 0)
|
|
|
|
|
graph_report(_("commit-graph has incorrect OID order: %s then %s"),
|
|
|
|
|
@@ -2768,7 +2759,7 @@ static int verify_one_commit_graph(struct repository *r,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
graph_commit = lookup_commit(r, &cur_oid);
|
|
|
|
|
if (!parse_commit_in_graph_one(r, g, graph_commit))
|
|
|
|
|
if (!parse_commit_in_graph_one(g, graph_commit))
|
|
|
|
|
graph_report(_("failed to parse commit %s from commit-graph"),
|
|
|
|
|
oid_to_hex(&cur_oid));
|
|
|
|
|
}
|
|
|
|
|
@@ -2793,8 +2784,8 @@ static int verify_one_commit_graph(struct repository *r,
|
|
|
|
|
timestamp_t generation;
|
|
|
|
|
|
|
|
|
|
display_progress(progress, ++(*seen));
|
|
|
|
|
oidread(&cur_oid, g->chunk_oid_lookup + st_mult(g->hash_len, i),
|
|
|
|
|
the_repository->hash_algo);
|
|
|
|
|
oidread(&cur_oid, g->chunk_oid_lookup + st_mult(g->hash_algo->rawsz, i),
|
|
|
|
|
g->hash_algo);
|
|
|
|
|
|
|
|
|
|
graph_commit = lookup_commit(r, &cur_oid);
|
|
|
|
|
odb_commit = (struct commit *)create_object(r, &cur_oid, alloc_commit_node(r));
|
|
|
|
|
@@ -2804,7 +2795,7 @@ static int verify_one_commit_graph(struct repository *r,
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!oideq(&get_commit_tree_in_graph_one(r, g, graph_commit)->object.oid,
|
|
|
|
|
if (!oideq(&get_commit_tree_in_graph_one(g, graph_commit)->object.oid,
|
|
|
|
|
get_commit_tree_oid(odb_commit)))
|
|
|
|
|
graph_report(_("root tree OID for commit %s in commit-graph is %s != %s"),
|
|
|
|
|
oid_to_hex(&cur_oid),
|
|
|
|
|
@@ -2822,7 +2813,7 @@ static int verify_one_commit_graph(struct repository *r,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* parse parent in case it is in a base graph */
|
|
|
|
|
parse_commit_in_graph_one(r, g, graph_parents->item);
|
|
|
|
|
parse_commit_in_graph_one(g, graph_parents->item);
|
|
|
|
|
|
|
|
|
|
if (!oideq(&graph_parents->item->object.oid, &odb_parents->item->object.oid))
|
|
|
|
|
graph_report(_("commit-graph parent for %s is %s != %s"),
|
|
|
|
|
@@ -2882,7 +2873,7 @@ static int verify_one_commit_graph(struct repository *r,
|
|
|
|
|
return verify_commit_graph_error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int verify_commit_graph(struct repository *r, struct commit_graph *g, int flags)
|
|
|
|
|
int verify_commit_graph(struct commit_graph *g, int flags)
|
|
|
|
|
{
|
|
|
|
|
struct progress *progress = NULL;
|
|
|
|
|
int local_error = 0;
|
|
|
|
|
@@ -2898,13 +2889,13 @@ int verify_commit_graph(struct repository *r, struct commit_graph *g, int flags)
|
|
|
|
|
if (!(flags & COMMIT_GRAPH_VERIFY_SHALLOW))
|
|
|
|
|
total += g->num_commits_in_base;
|
|
|
|
|
|
|
|
|
|
progress = start_progress(the_repository,
|
|
|
|
|
progress = start_progress(g->odb_source->odb->repo,
|
|
|
|
|
_("Verifying commits in commit graph"),
|
|
|
|
|
total);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (; g; g = g->base_graph) {
|
|
|
|
|
local_error |= verify_one_commit_graph(r, g, progress, &seen);
|
|
|
|
|
local_error |= verify_one_commit_graph(g, progress, &seen);
|
|
|
|
|
if (flags & COMMIT_GRAPH_VERIFY_SHALLOW)
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|