struct string_list *pack_indexes = NULL;
struct string_list *commit_hex = NULL;
struct string_list lines;
+ int result = 0;
static struct option builtin_commit_graph_write_options[] = {
OPT_STRING(0, "object-dir", &opts.obj_dir,
read_replace_refs = 0;
- if (opts.reachable) {
- write_commit_graph_reachable(opts.obj_dir, opts.append, 1);
- return 0;
- }
+ if (opts.reachable)
+ return write_commit_graph_reachable(opts.obj_dir, opts.append, 1);
string_list_init(&lines, 0);
if (opts.stdin_packs || opts.stdin_commits) {
UNLEAK(buf);
}
- write_commit_graph(opts.obj_dir,
- pack_indexes,
- commit_hex,
- opts.append,
- 1);
+ if (write_commit_graph(opts.obj_dir,
+ pack_indexes,
+ commit_hex,
+ opts.append,
+ 1))
+ result = 1;
UNLEAK(lines);
- return 0;
+ return result;
}
int cmd_commit_graph(int argc, const char **argv, const char *prefix)
return 0;
}
-void write_commit_graph_reachable(const char *obj_dir, int append,
- int report_progress)
+int write_commit_graph_reachable(const char *obj_dir, int append,
+ int report_progress)
{
struct string_list list = STRING_LIST_INIT_DUP;
+ int result;
for_each_ref(add_ref_to_list, &list);
- write_commit_graph(obj_dir, NULL, &list, append, report_progress);
+ result = write_commit_graph(obj_dir, NULL, &list,
+ append, report_progress);
string_list_clear(&list, 0);
+ return result;
}
-void write_commit_graph(const char *obj_dir,
- struct string_list *pack_indexes,
- struct string_list *commit_hex,
- int append, int report_progress)
+int write_commit_graph(const char *obj_dir,
+ struct string_list *pack_indexes,
+ struct string_list *commit_hex,
+ int append, int report_progress)
{
struct packed_oid_list oids;
struct packed_commit_list commits;
struct hashfile *f;
uint32_t i, count_distinct = 0;
- char *graph_name;
+ char *graph_name = NULL;
struct lock_file lk = LOCK_INIT;
uint32_t chunk_ids[5];
uint64_t chunk_offsets[5];
uint64_t progress_cnt = 0;
struct strbuf progress_title = STRBUF_INIT;
unsigned long approx_nr_objects;
+ int res = 0;
if (!commit_graph_compatible(the_repository))
- return;
+ return 0;
oids.nr = 0;
approx_nr_objects = approximate_object_count();
oids.alloc = approx_nr_objects / 32;
oids.progress = NULL;
oids.progress_done = 0;
+ commits.list = NULL;
if (append) {
prepare_commit_graph_one(the_repository, obj_dir);
strbuf_setlen(&packname, dirlen);
strbuf_addstr(&packname, pack_indexes->items[i].string);
p = add_packed_git(packname.buf, packname.len, 1);
- if (!p)
- die(_("error adding pack %s"), packname.buf);
- if (open_pack_index(p))
- die(_("error opening index for %s"), packname.buf);
+ if (!p) {
+ error(_("error adding pack %s"), packname.buf);
+ res = -1;
+ goto cleanup;
+ }
+ if (open_pack_index(p)) {
+ error(_("error opening index for %s"), packname.buf);
+ res = -1;
+ goto cleanup;
+ }
for_each_object_in_pack(p, add_packed_commits, &oids,
FOR_EACH_OBJECT_PACK_ORDER);
close_pack(p);
}
stop_progress(&progress);
- if (count_distinct >= GRAPH_EDGE_LAST_MASK)
- die(_("the commit graph format cannot write %d commits"), count_distinct);
+ if (count_distinct >= GRAPH_EDGE_LAST_MASK) {
+ error(_("the commit graph format cannot write %d commits"), count_distinct);
+ res = -1;
+ goto cleanup;
+ }
commits.nr = 0;
commits.alloc = count_distinct;
num_chunks = num_extra_edges ? 4 : 3;
stop_progress(&progress);
- if (commits.nr >= GRAPH_EDGE_LAST_MASK)
- die(_("too many commits to write graph"));
+ if (commits.nr >= GRAPH_EDGE_LAST_MASK) {
+ error(_("too many commits to write graph"));
+ res = -1;
+ goto cleanup;
+ }
compute_generation_numbers(&commits, report_progress);
graph_name = get_commit_graph_filename(obj_dir);
if (safe_create_leading_directories(graph_name)) {
UNLEAK(graph_name);
- die_errno(_("unable to create leading directories of %s"),
- graph_name);
+ error(_("unable to create leading directories of %s"),
+ graph_name);
+ res = -1;
+ goto cleanup;
}
hold_lock_file_for_update(&lk, graph_name, LOCK_DIE_ON_ERROR);
finalize_hashfile(f, NULL, CSUM_HASH_IN_STREAM | CSUM_FSYNC);
commit_lock_file(&lk);
+cleanup:
free(graph_name);
free(commits.list);
free(oids.list);
+
+ return res;
}
#define VERIFY_COMMIT_GRAPH_ERROR_HASH 2
*/
int generation_numbers_enabled(struct repository *r);
-void write_commit_graph_reachable(const char *obj_dir, int append,
+/*
+ * The write_commit_graph* methods return zero on success
+ * and a negative value on failure. Note that if the repository
+ * is not compatible with the commit-graph feature, then the
+ * methods will return 0 without writing a commit-graph.
+ */
+int write_commit_graph_reachable(const char *obj_dir, int append,
int report_progress);
-void write_commit_graph(const char *obj_dir,
- struct string_list *pack_indexes,
- struct string_list *commit_hex,
- int append, int report_progress);
+int write_commit_graph(const char *obj_dir,
+ struct string_list *pack_indexes,
+ struct string_list *commit_hex,
+ int append, int report_progress);
int verify_commit_graph(struct repository *r, struct commit_graph *g);