зеркало из https://github.com/microsoft/git.git
Merge branch 'tb/commit-graph-object-dir'
The code to compute the commit-graph has been taught to use a more robust way to tell if two object directories refer to the same thing. * tb/commit-graph-object-dir: commit-graph.h: use odb in 'load_commit_graph_one_fd_st' commit-graph.c: remove path normalization, comparison commit-graph.h: store object directory in 'struct commit_graph' commit-graph.h: store an odb in 'struct write_commit_graph_context' t5318: don't pass non-object directory to '--object-dir'
This commit is contained in:
Коммит
53c3be2c29
|
@ -26,7 +26,10 @@ OPTIONS
|
||||||
file. This parameter exists to specify the location of an alternate
|
file. This parameter exists to specify the location of an alternate
|
||||||
that only has the objects directory, not a full `.git` directory. The
|
that only has the objects directory, not a full `.git` directory. The
|
||||||
commit-graph file is expected to be in the `<dir>/info` directory and
|
commit-graph file is expected to be in the `<dir>/info` directory and
|
||||||
the packfiles are expected to be in `<dir>/pack`.
|
the packfiles are expected to be in `<dir>/pack`. If the directory
|
||||||
|
could not be made into an absolute path, or does not match any known
|
||||||
|
object directory, `git commit-graph ...` will exit with non-zero
|
||||||
|
status.
|
||||||
|
|
||||||
--[no-]progress::
|
--[no-]progress::
|
||||||
Turn progress on/off explicitly. If neither is specified, progress is
|
Turn progress on/off explicitly. If neither is specified, progress is
|
||||||
|
|
|
@ -34,9 +34,29 @@ static struct opts_commit_graph {
|
||||||
int progress;
|
int progress;
|
||||||
} opts;
|
} opts;
|
||||||
|
|
||||||
|
static struct object_directory *find_odb(struct repository *r,
|
||||||
|
const char *obj_dir)
|
||||||
|
{
|
||||||
|
struct object_directory *odb;
|
||||||
|
char *obj_dir_real = real_pathdup(obj_dir, 1);
|
||||||
|
|
||||||
|
prepare_alt_odb(r);
|
||||||
|
for (odb = r->objects->odb; odb; odb = odb->next) {
|
||||||
|
if (!strcmp(obj_dir_real, real_path(odb->path)))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(obj_dir_real);
|
||||||
|
|
||||||
|
if (!odb)
|
||||||
|
die(_("could not find object directory matching %s"), obj_dir);
|
||||||
|
return odb;
|
||||||
|
}
|
||||||
|
|
||||||
static int graph_verify(int argc, const char **argv)
|
static int graph_verify(int argc, const char **argv)
|
||||||
{
|
{
|
||||||
struct commit_graph *graph = NULL;
|
struct commit_graph *graph = NULL;
|
||||||
|
struct object_directory *odb = NULL;
|
||||||
char *graph_name;
|
char *graph_name;
|
||||||
int open_ok;
|
int open_ok;
|
||||||
int fd;
|
int fd;
|
||||||
|
@ -67,7 +87,8 @@ static int graph_verify(int argc, const char **argv)
|
||||||
if (opts.progress)
|
if (opts.progress)
|
||||||
flags |= COMMIT_GRAPH_WRITE_PROGRESS;
|
flags |= COMMIT_GRAPH_WRITE_PROGRESS;
|
||||||
|
|
||||||
graph_name = get_commit_graph_filename(opts.obj_dir);
|
odb = find_odb(the_repository, opts.obj_dir);
|
||||||
|
graph_name = get_commit_graph_filename(odb);
|
||||||
open_ok = open_commit_graph(graph_name, &fd, &st);
|
open_ok = open_commit_graph(graph_name, &fd, &st);
|
||||||
if (!open_ok && errno != ENOENT)
|
if (!open_ok && errno != ENOENT)
|
||||||
die_errno(_("Could not open commit-graph '%s'"), graph_name);
|
die_errno(_("Could not open commit-graph '%s'"), graph_name);
|
||||||
|
@ -75,9 +96,9 @@ static int graph_verify(int argc, const char **argv)
|
||||||
FREE_AND_NULL(graph_name);
|
FREE_AND_NULL(graph_name);
|
||||||
|
|
||||||
if (open_ok)
|
if (open_ok)
|
||||||
graph = load_commit_graph_one_fd_st(fd, &st);
|
graph = load_commit_graph_one_fd_st(fd, &st, odb);
|
||||||
else
|
else
|
||||||
graph = read_commit_graph_one(the_repository, opts.obj_dir);
|
graph = read_commit_graph_one(the_repository, odb);
|
||||||
|
|
||||||
/* Return failure if open_ok predicted success */
|
/* Return failure if open_ok predicted success */
|
||||||
if (!graph)
|
if (!graph)
|
||||||
|
@ -94,6 +115,7 @@ static int graph_write(int argc, const char **argv)
|
||||||
{
|
{
|
||||||
struct string_list *pack_indexes = NULL;
|
struct string_list *pack_indexes = NULL;
|
||||||
struct string_list *commit_hex = NULL;
|
struct string_list *commit_hex = NULL;
|
||||||
|
struct object_directory *odb = NULL;
|
||||||
struct string_list lines;
|
struct string_list lines;
|
||||||
int result = 0;
|
int result = 0;
|
||||||
enum commit_graph_write_flags flags = 0;
|
enum commit_graph_write_flags flags = 0;
|
||||||
|
@ -145,9 +167,10 @@ static int graph_write(int argc, const char **argv)
|
||||||
flags |= COMMIT_GRAPH_WRITE_PROGRESS;
|
flags |= COMMIT_GRAPH_WRITE_PROGRESS;
|
||||||
|
|
||||||
read_replace_refs = 0;
|
read_replace_refs = 0;
|
||||||
|
odb = find_odb(the_repository, opts.obj_dir);
|
||||||
|
|
||||||
if (opts.reachable) {
|
if (opts.reachable) {
|
||||||
if (write_commit_graph_reachable(opts.obj_dir, flags, &split_opts))
|
if (write_commit_graph_reachable(odb, flags, &split_opts))
|
||||||
return 1;
|
return 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -169,7 +192,7 @@ static int graph_write(int argc, const char **argv)
|
||||||
UNLEAK(buf);
|
UNLEAK(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (write_commit_graph(opts.obj_dir,
|
if (write_commit_graph(odb,
|
||||||
pack_indexes,
|
pack_indexes,
|
||||||
commit_hex,
|
commit_hex,
|
||||||
flags,
|
flags,
|
||||||
|
|
|
@ -1693,7 +1693,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
|
||||||
"not exceeded, and then \"git restore --staged :/\" to recover."));
|
"not exceeded, and then \"git restore --staged :/\" to recover."));
|
||||||
|
|
||||||
if (git_env_bool(GIT_TEST_COMMIT_GRAPH, 0) &&
|
if (git_env_bool(GIT_TEST_COMMIT_GRAPH, 0) &&
|
||||||
write_commit_graph_reachable(get_object_directory(), 0, NULL))
|
write_commit_graph_reachable(the_repository->objects->odb, 0, NULL))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
repo_rerere(the_repository, 0);
|
repo_rerere(the_repository, 0);
|
||||||
|
|
|
@ -1879,7 +1879,7 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
|
||||||
if (progress)
|
if (progress)
|
||||||
commit_graph_flags |= COMMIT_GRAPH_WRITE_PROGRESS;
|
commit_graph_flags |= COMMIT_GRAPH_WRITE_PROGRESS;
|
||||||
|
|
||||||
write_commit_graph_reachable(get_object_directory(),
|
write_commit_graph_reachable(the_repository->objects->odb,
|
||||||
commit_graph_flags,
|
commit_graph_flags,
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
|
@ -686,7 +686,7 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
|
||||||
|
|
||||||
prepare_repo_settings(the_repository);
|
prepare_repo_settings(the_repository);
|
||||||
if (the_repository->settings.gc_write_commit_graph == 1)
|
if (the_repository->settings.gc_write_commit_graph == 1)
|
||||||
write_commit_graph_reachable(get_object_directory(),
|
write_commit_graph_reachable(the_repository->objects->odb,
|
||||||
!quiet && !daemonized ? COMMIT_GRAPH_WRITE_PROGRESS : 0,
|
!quiet && !daemonized ? COMMIT_GRAPH_WRITE_PROGRESS : 0,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
|
|
115
commit-graph.c
115
commit-graph.c
|
@ -44,30 +44,21 @@
|
||||||
/* Remember to update object flag allocation in object.h */
|
/* Remember to update object flag allocation in object.h */
|
||||||
#define REACHABLE (1u<<15)
|
#define REACHABLE (1u<<15)
|
||||||
|
|
||||||
char *get_commit_graph_filename(const char *obj_dir)
|
char *get_commit_graph_filename(struct object_directory *odb)
|
||||||
{
|
{
|
||||||
char *filename = xstrfmt("%s/info/commit-graph", obj_dir);
|
return xstrfmt("%s/info/commit-graph", odb->path);
|
||||||
char *normalized = xmalloc(strlen(filename) + 1);
|
|
||||||
normalize_path_copy(normalized, filename);
|
|
||||||
free(filename);
|
|
||||||
return normalized;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *get_split_graph_filename(const char *obj_dir,
|
static char *get_split_graph_filename(struct object_directory *odb,
|
||||||
const char *oid_hex)
|
const char *oid_hex)
|
||||||
{
|
{
|
||||||
char *filename = xstrfmt("%s/info/commit-graphs/graph-%s.graph",
|
return xstrfmt("%s/info/commit-graphs/graph-%s.graph", odb->path,
|
||||||
obj_dir,
|
oid_hex);
|
||||||
oid_hex);
|
|
||||||
char *normalized = xmalloc(strlen(filename) + 1);
|
|
||||||
normalize_path_copy(normalized, filename);
|
|
||||||
free(filename);
|
|
||||||
return normalized;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *get_chain_filename(const char *obj_dir)
|
static char *get_chain_filename(struct object_directory *odb)
|
||||||
{
|
{
|
||||||
return xstrfmt("%s/info/commit-graphs/commit-graph-chain", obj_dir);
|
return xstrfmt("%s/info/commit-graphs/commit-graph-chain", odb->path);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t oid_version(void)
|
static uint8_t oid_version(void)
|
||||||
|
@ -117,7 +108,8 @@ int open_commit_graph(const char *graph_file, int *fd, struct stat *st)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct commit_graph *load_commit_graph_one_fd_st(int fd, struct stat *st)
|
struct commit_graph *load_commit_graph_one_fd_st(int fd, struct stat *st,
|
||||||
|
struct object_directory *odb)
|
||||||
{
|
{
|
||||||
void *graph_map;
|
void *graph_map;
|
||||||
size_t graph_size;
|
size_t graph_size;
|
||||||
|
@ -133,7 +125,9 @@ struct commit_graph *load_commit_graph_one_fd_st(int fd, struct stat *st)
|
||||||
graph_map = xmmap(NULL, graph_size, PROT_READ, MAP_PRIVATE, fd, 0);
|
graph_map = xmmap(NULL, graph_size, PROT_READ, MAP_PRIVATE, fd, 0);
|
||||||
ret = parse_commit_graph(graph_map, fd, graph_size);
|
ret = parse_commit_graph(graph_map, fd, graph_size);
|
||||||
|
|
||||||
if (!ret) {
|
if (ret)
|
||||||
|
ret->odb = odb;
|
||||||
|
else {
|
||||||
munmap(graph_map, graph_size);
|
munmap(graph_map, graph_size);
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
|
@ -308,7 +302,8 @@ struct commit_graph *parse_commit_graph(void *graph_map, int fd,
|
||||||
return graph;
|
return graph;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct commit_graph *load_commit_graph_one(const char *graph_file)
|
static struct commit_graph *load_commit_graph_one(const char *graph_file,
|
||||||
|
struct object_directory *odb)
|
||||||
{
|
{
|
||||||
|
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
@ -319,7 +314,7 @@ static struct commit_graph *load_commit_graph_one(const char *graph_file)
|
||||||
if (!open_ok)
|
if (!open_ok)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
g = load_commit_graph_one_fd_st(fd, &st);
|
g = load_commit_graph_one_fd_st(fd, &st, odb);
|
||||||
|
|
||||||
if (g)
|
if (g)
|
||||||
g->filename = xstrdup(graph_file);
|
g->filename = xstrdup(graph_file);
|
||||||
|
@ -327,15 +322,13 @@ static struct commit_graph *load_commit_graph_one(const char *graph_file)
|
||||||
return g;
|
return g;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct commit_graph *load_commit_graph_v1(struct repository *r, const char *obj_dir)
|
static struct commit_graph *load_commit_graph_v1(struct repository *r,
|
||||||
|
struct object_directory *odb)
|
||||||
{
|
{
|
||||||
char *graph_name = get_commit_graph_filename(obj_dir);
|
char *graph_name = get_commit_graph_filename(odb);
|
||||||
struct commit_graph *g = load_commit_graph_one(graph_name);
|
struct commit_graph *g = load_commit_graph_one(graph_name, odb);
|
||||||
free(graph_name);
|
free(graph_name);
|
||||||
|
|
||||||
if (g)
|
|
||||||
g->obj_dir = obj_dir;
|
|
||||||
|
|
||||||
return g;
|
return g;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -372,14 +365,15 @@ static int add_graph_to_chain(struct commit_graph *g,
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct commit_graph *load_commit_graph_chain(struct repository *r, const char *obj_dir)
|
static struct commit_graph *load_commit_graph_chain(struct repository *r,
|
||||||
|
struct object_directory *odb)
|
||||||
{
|
{
|
||||||
struct commit_graph *graph_chain = NULL;
|
struct commit_graph *graph_chain = NULL;
|
||||||
struct strbuf line = STRBUF_INIT;
|
struct strbuf line = STRBUF_INIT;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
struct object_id *oids;
|
struct object_id *oids;
|
||||||
int i = 0, valid = 1, count;
|
int i = 0, valid = 1, count;
|
||||||
char *chain_name = get_chain_filename(obj_dir);
|
char *chain_name = get_chain_filename(odb);
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
int stat_res;
|
int stat_res;
|
||||||
|
|
||||||
|
@ -412,14 +406,12 @@ static struct commit_graph *load_commit_graph_chain(struct repository *r, const
|
||||||
|
|
||||||
valid = 0;
|
valid = 0;
|
||||||
for (odb = r->objects->odb; odb; odb = odb->next) {
|
for (odb = r->objects->odb; odb; odb = odb->next) {
|
||||||
char *graph_name = get_split_graph_filename(odb->path, line.buf);
|
char *graph_name = get_split_graph_filename(odb, line.buf);
|
||||||
struct commit_graph *g = load_commit_graph_one(graph_name);
|
struct commit_graph *g = load_commit_graph_one(graph_name, odb);
|
||||||
|
|
||||||
free(graph_name);
|
free(graph_name);
|
||||||
|
|
||||||
if (g) {
|
if (g) {
|
||||||
g->obj_dir = odb->path;
|
|
||||||
|
|
||||||
if (add_graph_to_chain(g, graph_chain, oids, i)) {
|
if (add_graph_to_chain(g, graph_chain, oids, i)) {
|
||||||
graph_chain = g;
|
graph_chain = g;
|
||||||
valid = 1;
|
valid = 1;
|
||||||
|
@ -442,23 +434,25 @@ static struct commit_graph *load_commit_graph_chain(struct repository *r, const
|
||||||
return graph_chain;
|
return graph_chain;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct commit_graph *read_commit_graph_one(struct repository *r, const char *obj_dir)
|
struct commit_graph *read_commit_graph_one(struct repository *r,
|
||||||
|
struct object_directory *odb)
|
||||||
{
|
{
|
||||||
struct commit_graph *g = load_commit_graph_v1(r, obj_dir);
|
struct commit_graph *g = load_commit_graph_v1(r, odb);
|
||||||
|
|
||||||
if (!g)
|
if (!g)
|
||||||
g = load_commit_graph_chain(r, obj_dir);
|
g = load_commit_graph_chain(r, odb);
|
||||||
|
|
||||||
return g;
|
return g;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void prepare_commit_graph_one(struct repository *r, const char *obj_dir)
|
static void prepare_commit_graph_one(struct repository *r,
|
||||||
|
struct object_directory *odb)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (r->objects->commit_graph)
|
if (r->objects->commit_graph)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
r->objects->commit_graph = read_commit_graph_one(r, obj_dir);
|
r->objects->commit_graph = read_commit_graph_one(r, odb);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -505,7 +499,7 @@ static int prepare_commit_graph(struct repository *r)
|
||||||
for (odb = r->objects->odb;
|
for (odb = r->objects->odb;
|
||||||
!r->objects->commit_graph && odb;
|
!r->objects->commit_graph && odb;
|
||||||
odb = odb->next)
|
odb = odb->next)
|
||||||
prepare_commit_graph_one(r, odb->path);
|
prepare_commit_graph_one(r, odb);
|
||||||
return !!r->objects->commit_graph;
|
return !!r->objects->commit_graph;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -772,7 +766,7 @@ struct packed_oid_list {
|
||||||
|
|
||||||
struct write_commit_graph_context {
|
struct write_commit_graph_context {
|
||||||
struct repository *r;
|
struct repository *r;
|
||||||
char *obj_dir;
|
struct object_directory *odb;
|
||||||
char *graph_name;
|
char *graph_name;
|
||||||
struct packed_oid_list oids;
|
struct packed_oid_list oids;
|
||||||
struct packed_commit_list commits;
|
struct packed_commit_list commits;
|
||||||
|
@ -1149,7 +1143,7 @@ static int add_ref_to_list(const char *refname,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int write_commit_graph_reachable(const char *obj_dir,
|
int write_commit_graph_reachable(struct object_directory *odb,
|
||||||
enum commit_graph_write_flags flags,
|
enum commit_graph_write_flags flags,
|
||||||
const struct split_commit_graph_opts *split_opts)
|
const struct split_commit_graph_opts *split_opts)
|
||||||
{
|
{
|
||||||
|
@ -1157,7 +1151,7 @@ int write_commit_graph_reachable(const char *obj_dir,
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
for_each_ref(add_ref_to_list, &list);
|
for_each_ref(add_ref_to_list, &list);
|
||||||
result = write_commit_graph(obj_dir, NULL, &list,
|
result = write_commit_graph(odb, NULL, &list,
|
||||||
flags, split_opts);
|
flags, split_opts);
|
||||||
|
|
||||||
string_list_clear(&list, 0);
|
string_list_clear(&list, 0);
|
||||||
|
@ -1172,7 +1166,7 @@ static int fill_oids_from_packs(struct write_commit_graph_context *ctx,
|
||||||
struct strbuf packname = STRBUF_INIT;
|
struct strbuf packname = STRBUF_INIT;
|
||||||
int dirlen;
|
int dirlen;
|
||||||
|
|
||||||
strbuf_addf(&packname, "%s/pack/", ctx->obj_dir);
|
strbuf_addf(&packname, "%s/pack/", ctx->odb->path);
|
||||||
dirlen = packname.len;
|
dirlen = packname.len;
|
||||||
if (ctx->report_progress) {
|
if (ctx->report_progress) {
|
||||||
strbuf_addf(&progress_title,
|
strbuf_addf(&progress_title,
|
||||||
|
@ -1368,10 +1362,10 @@ static int write_commit_graph_file(struct write_commit_graph_context *ctx)
|
||||||
|
|
||||||
strbuf_addf(&tmp_file,
|
strbuf_addf(&tmp_file,
|
||||||
"%s/info/commit-graphs/tmp_graph_XXXXXX",
|
"%s/info/commit-graphs/tmp_graph_XXXXXX",
|
||||||
ctx->obj_dir);
|
ctx->odb->path);
|
||||||
ctx->graph_name = strbuf_detach(&tmp_file, NULL);
|
ctx->graph_name = strbuf_detach(&tmp_file, NULL);
|
||||||
} else {
|
} else {
|
||||||
ctx->graph_name = get_commit_graph_filename(ctx->obj_dir);
|
ctx->graph_name = get_commit_graph_filename(ctx->odb);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (safe_create_leading_directories(ctx->graph_name)) {
|
if (safe_create_leading_directories(ctx->graph_name)) {
|
||||||
|
@ -1382,7 +1376,7 @@ static int write_commit_graph_file(struct write_commit_graph_context *ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx->split) {
|
if (ctx->split) {
|
||||||
char *lock_name = get_chain_filename(ctx->obj_dir);
|
char *lock_name = get_chain_filename(ctx->odb);
|
||||||
|
|
||||||
hold_lock_file_for_update(&lk, lock_name, LOCK_DIE_ON_ERROR);
|
hold_lock_file_for_update(&lk, lock_name, LOCK_DIE_ON_ERROR);
|
||||||
|
|
||||||
|
@ -1470,7 +1464,7 @@ static int write_commit_graph_file(struct write_commit_graph_context *ctx)
|
||||||
|
|
||||||
if (ctx->split && ctx->base_graph_name && ctx->num_commit_graphs_after > 1) {
|
if (ctx->split && ctx->base_graph_name && ctx->num_commit_graphs_after > 1) {
|
||||||
char *new_base_hash = xstrdup(oid_to_hex(&ctx->new_base_graph->oid));
|
char *new_base_hash = xstrdup(oid_to_hex(&ctx->new_base_graph->oid));
|
||||||
char *new_base_name = get_split_graph_filename(ctx->new_base_graph->obj_dir, new_base_hash);
|
char *new_base_name = get_split_graph_filename(ctx->new_base_graph->odb, new_base_hash);
|
||||||
|
|
||||||
free(ctx->commit_graph_filenames_after[ctx->num_commit_graphs_after - 2]);
|
free(ctx->commit_graph_filenames_after[ctx->num_commit_graphs_after - 2]);
|
||||||
free(ctx->commit_graph_hash_after[ctx->num_commit_graphs_after - 2]);
|
free(ctx->commit_graph_hash_after[ctx->num_commit_graphs_after - 2]);
|
||||||
|
@ -1506,12 +1500,12 @@ static int write_commit_graph_file(struct write_commit_graph_context *ctx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
char *graph_name = get_commit_graph_filename(ctx->obj_dir);
|
char *graph_name = get_commit_graph_filename(ctx->odb);
|
||||||
unlink(graph_name);
|
unlink(graph_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx->commit_graph_hash_after[ctx->num_commit_graphs_after - 1] = xstrdup(oid_to_hex(&file_hash));
|
ctx->commit_graph_hash_after[ctx->num_commit_graphs_after - 1] = xstrdup(oid_to_hex(&file_hash));
|
||||||
final_graph_name = get_split_graph_filename(ctx->obj_dir,
|
final_graph_name = get_split_graph_filename(ctx->odb,
|
||||||
ctx->commit_graph_hash_after[ctx->num_commit_graphs_after - 1]);
|
ctx->commit_graph_hash_after[ctx->num_commit_graphs_after - 1]);
|
||||||
ctx->commit_graph_filenames_after[ctx->num_commit_graphs_after - 1] = final_graph_name;
|
ctx->commit_graph_filenames_after[ctx->num_commit_graphs_after - 1] = final_graph_name;
|
||||||
|
|
||||||
|
@ -1553,7 +1547,7 @@ static void split_graph_merge_strategy(struct write_commit_graph_context *ctx)
|
||||||
|
|
||||||
while (g && (g->num_commits <= size_mult * num_commits ||
|
while (g && (g->num_commits <= size_mult * num_commits ||
|
||||||
(max_commits && num_commits > max_commits))) {
|
(max_commits && num_commits > max_commits))) {
|
||||||
if (strcmp(g->obj_dir, ctx->obj_dir))
|
if (g->odb != ctx->odb)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
num_commits += g->num_commits;
|
num_commits += g->num_commits;
|
||||||
|
@ -1565,10 +1559,10 @@ static void split_graph_merge_strategy(struct write_commit_graph_context *ctx)
|
||||||
ctx->new_base_graph = g;
|
ctx->new_base_graph = g;
|
||||||
|
|
||||||
if (ctx->num_commit_graphs_after == 2) {
|
if (ctx->num_commit_graphs_after == 2) {
|
||||||
char *old_graph_name = get_commit_graph_filename(g->obj_dir);
|
char *old_graph_name = get_commit_graph_filename(g->odb);
|
||||||
|
|
||||||
if (!strcmp(g->filename, old_graph_name) &&
|
if (!strcmp(g->filename, old_graph_name) &&
|
||||||
strcmp(g->obj_dir, ctx->obj_dir)) {
|
g->odb != ctx->odb) {
|
||||||
ctx->num_commit_graphs_after = 1;
|
ctx->num_commit_graphs_after = 1;
|
||||||
ctx->new_base_graph = NULL;
|
ctx->new_base_graph = NULL;
|
||||||
}
|
}
|
||||||
|
@ -1719,13 +1713,13 @@ static void expire_commit_graphs(struct write_commit_graph_context *ctx)
|
||||||
if (ctx->split_opts && ctx->split_opts->expire_time)
|
if (ctx->split_opts && ctx->split_opts->expire_time)
|
||||||
expire_time -= ctx->split_opts->expire_time;
|
expire_time -= ctx->split_opts->expire_time;
|
||||||
if (!ctx->split) {
|
if (!ctx->split) {
|
||||||
char *chain_file_name = get_chain_filename(ctx->obj_dir);
|
char *chain_file_name = get_chain_filename(ctx->odb);
|
||||||
unlink(chain_file_name);
|
unlink(chain_file_name);
|
||||||
free(chain_file_name);
|
free(chain_file_name);
|
||||||
ctx->num_commit_graphs_after = 0;
|
ctx->num_commit_graphs_after = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
strbuf_addstr(&path, ctx->obj_dir);
|
strbuf_addstr(&path, ctx->odb->path);
|
||||||
strbuf_addstr(&path, "/info/commit-graphs");
|
strbuf_addstr(&path, "/info/commit-graphs");
|
||||||
dir = opendir(path.buf);
|
dir = opendir(path.buf);
|
||||||
|
|
||||||
|
@ -1764,7 +1758,7 @@ out:
|
||||||
strbuf_release(&path);
|
strbuf_release(&path);
|
||||||
}
|
}
|
||||||
|
|
||||||
int write_commit_graph(const char *obj_dir,
|
int write_commit_graph(struct object_directory *odb,
|
||||||
struct string_list *pack_indexes,
|
struct string_list *pack_indexes,
|
||||||
struct string_list *commit_hex,
|
struct string_list *commit_hex,
|
||||||
enum commit_graph_write_flags flags,
|
enum commit_graph_write_flags flags,
|
||||||
|
@ -1772,7 +1766,6 @@ int write_commit_graph(const char *obj_dir,
|
||||||
{
|
{
|
||||||
struct write_commit_graph_context *ctx;
|
struct write_commit_graph_context *ctx;
|
||||||
uint32_t i, count_distinct = 0;
|
uint32_t i, count_distinct = 0;
|
||||||
size_t len;
|
|
||||||
int res = 0;
|
int res = 0;
|
||||||
|
|
||||||
if (!commit_graph_compatible(the_repository))
|
if (!commit_graph_compatible(the_repository))
|
||||||
|
@ -1780,14 +1773,7 @@ int write_commit_graph(const char *obj_dir,
|
||||||
|
|
||||||
ctx = xcalloc(1, sizeof(struct write_commit_graph_context));
|
ctx = xcalloc(1, sizeof(struct write_commit_graph_context));
|
||||||
ctx->r = the_repository;
|
ctx->r = the_repository;
|
||||||
|
ctx->odb = odb;
|
||||||
/* normalize object dir with no trailing slash */
|
|
||||||
ctx->obj_dir = xmallocz(strlen(obj_dir) + 1);
|
|
||||||
normalize_path_copy(ctx->obj_dir, obj_dir);
|
|
||||||
len = strlen(ctx->obj_dir);
|
|
||||||
if (len && ctx->obj_dir[len - 1] == '/')
|
|
||||||
ctx->obj_dir[len - 1] = 0;
|
|
||||||
|
|
||||||
ctx->append = flags & COMMIT_GRAPH_WRITE_APPEND ? 1 : 0;
|
ctx->append = flags & COMMIT_GRAPH_WRITE_APPEND ? 1 : 0;
|
||||||
ctx->report_progress = flags & COMMIT_GRAPH_WRITE_PROGRESS ? 1 : 0;
|
ctx->report_progress = flags & COMMIT_GRAPH_WRITE_PROGRESS ? 1 : 0;
|
||||||
ctx->split = flags & COMMIT_GRAPH_WRITE_SPLIT ? 1 : 0;
|
ctx->split = flags & COMMIT_GRAPH_WRITE_SPLIT ? 1 : 0;
|
||||||
|
@ -1824,7 +1810,7 @@ int write_commit_graph(const char *obj_dir,
|
||||||
ctx->oids.alloc = split_opts->max_commits;
|
ctx->oids.alloc = split_opts->max_commits;
|
||||||
|
|
||||||
if (ctx->append) {
|
if (ctx->append) {
|
||||||
prepare_commit_graph_one(ctx->r, ctx->obj_dir);
|
prepare_commit_graph_one(ctx->r, ctx->odb);
|
||||||
if (ctx->r->objects->commit_graph)
|
if (ctx->r->objects->commit_graph)
|
||||||
ctx->oids.alloc += ctx->r->objects->commit_graph->num_commits;
|
ctx->oids.alloc += ctx->r->objects->commit_graph->num_commits;
|
||||||
}
|
}
|
||||||
|
@ -1898,7 +1884,6 @@ cleanup:
|
||||||
free(ctx->graph_name);
|
free(ctx->graph_name);
|
||||||
free(ctx->commits.list);
|
free(ctx->commits.list);
|
||||||
free(ctx->oids.list);
|
free(ctx->oids.list);
|
||||||
free(ctx->obj_dir);
|
|
||||||
|
|
||||||
if (ctx->commit_graph_filenames_after) {
|
if (ctx->commit_graph_filenames_after) {
|
||||||
for (i = 0; i < ctx->num_commit_graphs_after; i++) {
|
for (i = 0; i < ctx->num_commit_graphs_after; i++) {
|
||||||
|
|
|
@ -5,13 +5,14 @@
|
||||||
#include "repository.h"
|
#include "repository.h"
|
||||||
#include "string-list.h"
|
#include "string-list.h"
|
||||||
#include "cache.h"
|
#include "cache.h"
|
||||||
|
#include "object-store.h"
|
||||||
|
|
||||||
#define GIT_TEST_COMMIT_GRAPH "GIT_TEST_COMMIT_GRAPH"
|
#define GIT_TEST_COMMIT_GRAPH "GIT_TEST_COMMIT_GRAPH"
|
||||||
#define GIT_TEST_COMMIT_GRAPH_DIE_ON_LOAD "GIT_TEST_COMMIT_GRAPH_DIE_ON_LOAD"
|
#define GIT_TEST_COMMIT_GRAPH_DIE_ON_LOAD "GIT_TEST_COMMIT_GRAPH_DIE_ON_LOAD"
|
||||||
|
|
||||||
struct commit;
|
struct commit;
|
||||||
|
|
||||||
char *get_commit_graph_filename(const char *obj_dir);
|
char *get_commit_graph_filename(struct object_directory *odb);
|
||||||
int open_commit_graph(const char *graph_file, int *fd, struct stat *st);
|
int open_commit_graph(const char *graph_file, int *fd, struct stat *st);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -48,7 +49,7 @@ struct commit_graph {
|
||||||
uint32_t num_commits;
|
uint32_t num_commits;
|
||||||
struct object_id oid;
|
struct object_id oid;
|
||||||
char *filename;
|
char *filename;
|
||||||
const char *obj_dir;
|
struct object_directory *odb;
|
||||||
|
|
||||||
uint32_t num_commits_in_base;
|
uint32_t num_commits_in_base;
|
||||||
struct commit_graph *base_graph;
|
struct commit_graph *base_graph;
|
||||||
|
@ -60,8 +61,10 @@ struct commit_graph {
|
||||||
const unsigned char *chunk_base_graphs;
|
const unsigned char *chunk_base_graphs;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct commit_graph *load_commit_graph_one_fd_st(int fd, struct stat *st);
|
struct commit_graph *load_commit_graph_one_fd_st(int fd, struct stat *st,
|
||||||
struct commit_graph *read_commit_graph_one(struct repository *r, const char *obj_dir);
|
struct object_directory *odb);
|
||||||
|
struct commit_graph *read_commit_graph_one(struct repository *r,
|
||||||
|
struct object_directory *odb);
|
||||||
struct commit_graph *parse_commit_graph(void *graph_map, int fd,
|
struct commit_graph *parse_commit_graph(void *graph_map, int fd,
|
||||||
size_t graph_size);
|
size_t graph_size);
|
||||||
|
|
||||||
|
@ -91,10 +94,10 @@ struct split_commit_graph_opts {
|
||||||
* is not compatible with the commit-graph feature, then the
|
* is not compatible with the commit-graph feature, then the
|
||||||
* methods will return 0 without writing a commit-graph.
|
* methods will return 0 without writing a commit-graph.
|
||||||
*/
|
*/
|
||||||
int write_commit_graph_reachable(const char *obj_dir,
|
int write_commit_graph_reachable(struct object_directory *odb,
|
||||||
enum commit_graph_write_flags flags,
|
enum commit_graph_write_flags flags,
|
||||||
const struct split_commit_graph_opts *split_opts);
|
const struct split_commit_graph_opts *split_opts);
|
||||||
int write_commit_graph(const char *obj_dir,
|
int write_commit_graph(struct object_directory *odb,
|
||||||
struct string_list *pack_indexes,
|
struct string_list *pack_indexes,
|
||||||
struct string_list *commit_hex,
|
struct string_list *commit_hex,
|
||||||
enum commit_graph_write_flags flags,
|
enum commit_graph_write_flags flags,
|
||||||
|
|
|
@ -11,18 +11,18 @@ int cmd__read_graph(int argc, const char **argv)
|
||||||
int open_ok;
|
int open_ok;
|
||||||
int fd;
|
int fd;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
const char *object_dir;
|
struct object_directory *odb;
|
||||||
|
|
||||||
setup_git_directory();
|
setup_git_directory();
|
||||||
object_dir = get_object_directory();
|
odb = the_repository->objects->odb;
|
||||||
|
|
||||||
graph_name = get_commit_graph_filename(object_dir);
|
graph_name = get_commit_graph_filename(odb);
|
||||||
|
|
||||||
open_ok = open_commit_graph(graph_name, &fd, &st);
|
open_ok = open_commit_graph(graph_name, &fd, &st);
|
||||||
if (!open_ok)
|
if (!open_ok)
|
||||||
die_errno(_("Could not open commit-graph '%s'"), graph_name);
|
die_errno(_("Could not open commit-graph '%s'"), graph_name);
|
||||||
|
|
||||||
graph = load_commit_graph_one_fd_st(fd, &st);
|
graph = load_commit_graph_one_fd_st(fd, &st, odb);
|
||||||
if (!graph)
|
if (!graph)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
|
|
@ -19,8 +19,8 @@ test_expect_success 'verify graph with no graph file' '
|
||||||
|
|
||||||
test_expect_success 'write graph with no packs' '
|
test_expect_success 'write graph with no packs' '
|
||||||
cd "$TRASH_DIRECTORY/full" &&
|
cd "$TRASH_DIRECTORY/full" &&
|
||||||
git commit-graph write --object-dir . &&
|
git commit-graph write --object-dir $objdir &&
|
||||||
test_path_is_missing info/commit-graph
|
test_path_is_missing $objdir/info/commit-graph
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'exit with correct error on bad input to --stdin-packs' '
|
test_expect_success 'exit with correct error on bad input to --stdin-packs' '
|
||||||
|
|
Загрузка…
Ссылка в новой задаче