From 9916073be5dc59997e7cb9f7577bc7c91fd8f44a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?SZEDER=20G=C3=A1bor?= Date: Mon, 5 Aug 2019 10:02:38 +0200 Subject: [PATCH 1/3] t5318-commit-graph: use 'test_expect_code' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In 't5318-commit-graph.sh' the test 'close with correct error on bad input' manually verifies the exit code of a 'git commit-graph write' command. Use 'test_expect_code' instead. Signed-off-by: SZEDER Gábor Acked-by: Derrick Stolee Signed-off-by: Junio C Hamano --- t/t5318-commit-graph.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/t/t5318-commit-graph.sh b/t/t5318-commit-graph.sh index 22cb9d6643..4391007f4c 100755 --- a/t/t5318-commit-graph.sh +++ b/t/t5318-commit-graph.sh @@ -26,8 +26,7 @@ test_expect_success 'write graph with no packs' ' test_expect_success 'close with correct error on bad input' ' cd "$TRASH_DIRECTORY/full" && echo doesnotexist >in && - { git commit-graph write --stdin-packs stderr; ret=$?; } && - test "$ret" = 1 && + test_expect_code 1 git commit-graph write --stdin-packs stderr && test_i18ngrep "error adding pack" stderr ' From 39d88318569188c0544c3c0f8207f2e1b1829e60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?SZEDER=20G=C3=A1bor?= Date: Mon, 5 Aug 2019 10:02:39 +0200 Subject: [PATCH 2/3] commit-graph: turn a group of write-related macro flags into an enum MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: SZEDER Gábor Acked-by: Derrick Stolee Signed-off-by: Junio C Hamano --- builtin/commit-graph.c | 6 +++--- builtin/gc.c | 2 +- commit-graph.c | 11 ++++++----- commit-graph.h | 13 ++++++++----- 4 files changed, 18 insertions(+), 14 deletions(-) diff --git a/builtin/commit-graph.c b/builtin/commit-graph.c index 38027b83d9..64eccde314 100644 --- a/builtin/commit-graph.c +++ b/builtin/commit-graph.c @@ -154,7 +154,7 @@ static int graph_write(int argc, const char **argv) struct string_list *commit_hex = NULL; struct string_list lines; int result = 0; - unsigned int flags = COMMIT_GRAPH_PROGRESS; + enum commit_graph_write_flags flags = COMMIT_GRAPH_WRITE_PROGRESS; static struct option builtin_commit_graph_write_options[] = { OPT_STRING(0, "object-dir", &opts.obj_dir, @@ -192,9 +192,9 @@ static int graph_write(int argc, const char **argv) if (!opts.obj_dir) opts.obj_dir = get_object_directory(); if (opts.append) - flags |= COMMIT_GRAPH_APPEND; + flags |= COMMIT_GRAPH_WRITE_APPEND; if (opts.split) - flags |= COMMIT_GRAPH_SPLIT; + flags |= COMMIT_GRAPH_WRITE_SPLIT; read_replace_refs = 0; diff --git a/builtin/gc.c b/builtin/gc.c index c18efadda5..305fb0f45a 100644 --- a/builtin/gc.c +++ b/builtin/gc.c @@ -687,7 +687,7 @@ int cmd_gc(int argc, const char **argv, const char *prefix) if (gc_write_commit_graph && write_commit_graph_reachable(get_object_directory(), - !quiet && !daemonized ? COMMIT_GRAPH_PROGRESS : 0, + !quiet && !daemonized ? COMMIT_GRAPH_WRITE_PROGRESS : 0, NULL)) return 1; diff --git a/commit-graph.c b/commit-graph.c index b3c4de79b6..04324a4648 100644 --- a/commit-graph.c +++ b/commit-graph.c @@ -1133,7 +1133,8 @@ static int add_ref_to_list(const char *refname, return 0; } -int write_commit_graph_reachable(const char *obj_dir, unsigned int flags, +int write_commit_graph_reachable(const char *obj_dir, + enum commit_graph_write_flags flags, const struct split_commit_graph_opts *split_opts) { struct string_list list = STRING_LIST_INIT_DUP; @@ -1750,7 +1751,7 @@ static void expire_commit_graphs(struct write_commit_graph_context *ctx) int write_commit_graph(const char *obj_dir, struct string_list *pack_indexes, struct string_list *commit_hex, - unsigned int flags, + enum commit_graph_write_flags flags, const struct split_commit_graph_opts *split_opts) { struct write_commit_graph_context *ctx; @@ -1771,9 +1772,9 @@ int write_commit_graph(const char *obj_dir, if (len && ctx->obj_dir[len - 1] == '/') ctx->obj_dir[len - 1] = 0; - ctx->append = flags & COMMIT_GRAPH_APPEND ? 1 : 0; - ctx->report_progress = flags & COMMIT_GRAPH_PROGRESS ? 1 : 0; - ctx->split = flags & COMMIT_GRAPH_SPLIT ? 1 : 0; + ctx->append = flags & COMMIT_GRAPH_WRITE_APPEND ? 1 : 0; + ctx->report_progress = flags & COMMIT_GRAPH_WRITE_PROGRESS ? 1 : 0; + ctx->split = flags & COMMIT_GRAPH_WRITE_SPLIT ? 1 : 0; ctx->split_opts = split_opts; if (ctx->split) { diff --git a/commit-graph.h b/commit-graph.h index df9a3b20e4..ae4db87fb5 100644 --- a/commit-graph.h +++ b/commit-graph.h @@ -71,9 +71,11 @@ struct commit_graph *parse_commit_graph(void *graph_map, int fd, */ int generation_numbers_enabled(struct repository *r); -#define COMMIT_GRAPH_APPEND (1 << 0) -#define COMMIT_GRAPH_PROGRESS (1 << 1) -#define COMMIT_GRAPH_SPLIT (1 << 2) +enum commit_graph_write_flags { + COMMIT_GRAPH_WRITE_APPEND = (1 << 0), + COMMIT_GRAPH_WRITE_PROGRESS = (1 << 1), + COMMIT_GRAPH_WRITE_SPLIT = (1 << 2) +}; struct split_commit_graph_opts { int size_multiple; @@ -87,12 +89,13 @@ struct split_commit_graph_opts { * 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, unsigned int flags, +int write_commit_graph_reachable(const char *obj_dir, + enum commit_graph_write_flags flags, const struct split_commit_graph_opts *split_opts); int write_commit_graph(const char *obj_dir, struct string_list *pack_indexes, struct string_list *commit_hex, - unsigned int flags, + enum commit_graph_write_flags flags, const struct split_commit_graph_opts *split_opts); #define COMMIT_GRAPH_VERIFY_SHALLOW (1 << 0) From 7c5c9b9c57d58273d17dfc3fec3ebdb25077a9de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?SZEDER=20G=C3=A1bor?= Date: Mon, 5 Aug 2019 10:02:40 +0200 Subject: [PATCH 3/3] commit-graph: error out on invalid commit oids in 'write --stdin-commits' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit While 'git commit-graph write --stdin-commits' expects commit object ids as input, it accepts and silently skips over any invalid commit object ids, and still exits with success: # nonsense $ echo not-a-commit-oid | git commit-graph write --stdin-commits $ echo $? 0 # sometimes I forgot that refs are not good... $ echo HEAD | git commit-graph write --stdin-commits $ echo $? 0 # valid tree OID, but not a commit OID $ git rev-parse HEAD^{tree} | git commit-graph write --stdin-commits $ echo $? 0 $ ls -l .git/objects/info/commit-graph ls: cannot access '.git/objects/info/commit-graph': No such file or directory Check that all input records are indeed valid commit object ids and return with error otherwise, the same way '--stdin-packs' handles invalid input; see e103f7276f (commit-graph: return with errors during write, 2019-06-12). Note that it should only return with error when encountering an invalid commit object id coming from standard input. However, '--reachable' uses the same code path to process object ids pointed to by all refs, and that includes tag object ids as well, which should still be skipped over. Therefore add a new flag to 'enum commit_graph_write_flags' and a corresponding field to 'struct write_commit_graph_context', so we can differentiate between those two cases. Signed-off-by: SZEDER Gábor Acked-by: Derrick Stolee Signed-off-by: Junio C Hamano --- builtin/commit-graph.c | 4 +++- commit-graph.c | 29 +++++++++++++++++------------ commit-graph.h | 4 +++- t/t5318-commit-graph.sh | 11 ++++++++++- 4 files changed, 33 insertions(+), 15 deletions(-) diff --git a/builtin/commit-graph.c b/builtin/commit-graph.c index 64eccde314..57863619b7 100644 --- a/builtin/commit-graph.c +++ b/builtin/commit-graph.c @@ -213,8 +213,10 @@ static int graph_write(int argc, const char **argv) if (opts.stdin_packs) pack_indexes = &lines; - if (opts.stdin_commits) + if (opts.stdin_commits) { commit_hex = &lines; + flags |= COMMIT_GRAPH_WRITE_CHECK_OIDS; + } UNLEAK(buf); } diff --git a/commit-graph.c b/commit-graph.c index 04324a4648..821900675b 100644 --- a/commit-graph.c +++ b/commit-graph.c @@ -782,7 +782,8 @@ struct write_commit_graph_context { unsigned append:1, report_progress:1, - split:1; + split:1, + check_oids:1; const struct split_commit_graph_opts *split_opts; }; @@ -1193,8 +1194,8 @@ static int fill_oids_from_packs(struct write_commit_graph_context *ctx, return 0; } -static void fill_oids_from_commit_hex(struct write_commit_graph_context *ctx, - struct string_list *commit_hex) +static int fill_oids_from_commit_hex(struct write_commit_graph_context *ctx, + struct string_list *commit_hex) { uint32_t i; struct strbuf progress_title = STRBUF_INIT; @@ -1215,20 +1216,21 @@ static void fill_oids_from_commit_hex(struct write_commit_graph_context *ctx, struct commit *result; display_progress(ctx->progress, i + 1); - if (commit_hex->items[i].string && - parse_oid_hex(commit_hex->items[i].string, &oid, &end)) - continue; - - result = lookup_commit_reference_gently(ctx->r, &oid, 1); - - if (result) { + if (!parse_oid_hex(commit_hex->items[i].string, &oid, &end) && + (result = lookup_commit_reference_gently(ctx->r, &oid, 1))) { ALLOC_GROW(ctx->oids.list, ctx->oids.nr + 1, ctx->oids.alloc); oidcpy(&ctx->oids.list[ctx->oids.nr], &(result->object.oid)); ctx->oids.nr++; + } else if (ctx->check_oids) { + error(_("invalid commit object id: %s"), + commit_hex->items[i].string); + return -1; } } stop_progress(&ctx->progress); strbuf_release(&progress_title); + + return 0; } static void fill_oids_from_all_packs(struct write_commit_graph_context *ctx) @@ -1775,6 +1777,7 @@ int write_commit_graph(const char *obj_dir, ctx->append = flags & COMMIT_GRAPH_WRITE_APPEND ? 1 : 0; ctx->report_progress = flags & COMMIT_GRAPH_WRITE_PROGRESS ? 1 : 0; ctx->split = flags & COMMIT_GRAPH_WRITE_SPLIT ? 1 : 0; + ctx->check_oids = flags & COMMIT_GRAPH_WRITE_CHECK_OIDS ? 1 : 0; ctx->split_opts = split_opts; if (ctx->split) { @@ -1829,8 +1832,10 @@ int write_commit_graph(const char *obj_dir, goto cleanup; } - if (commit_hex) - fill_oids_from_commit_hex(ctx, commit_hex); + if (commit_hex) { + if ((res = fill_oids_from_commit_hex(ctx, commit_hex))) + goto cleanup; + } if (!pack_indexes && !commit_hex) fill_oids_from_all_packs(ctx); diff --git a/commit-graph.h b/commit-graph.h index ae4db87fb5..486e64e591 100644 --- a/commit-graph.h +++ b/commit-graph.h @@ -74,7 +74,9 @@ int generation_numbers_enabled(struct repository *r); enum commit_graph_write_flags { COMMIT_GRAPH_WRITE_APPEND = (1 << 0), COMMIT_GRAPH_WRITE_PROGRESS = (1 << 1), - COMMIT_GRAPH_WRITE_SPLIT = (1 << 2) + COMMIT_GRAPH_WRITE_SPLIT = (1 << 2), + /* Make sure that each OID in the input is a valid commit OID. */ + COMMIT_GRAPH_WRITE_CHECK_OIDS = (1 << 3) }; struct split_commit_graph_opts { diff --git a/t/t5318-commit-graph.sh b/t/t5318-commit-graph.sh index 4391007f4c..ab3eccf0fa 100755 --- a/t/t5318-commit-graph.sh +++ b/t/t5318-commit-graph.sh @@ -23,7 +23,7 @@ test_expect_success 'write graph with no packs' ' test_path_is_missing info/commit-graph ' -test_expect_success 'close with correct error on bad input' ' +test_expect_success 'exit with correct error on bad input to --stdin-packs' ' cd "$TRASH_DIRECTORY/full" && echo doesnotexist >in && test_expect_code 1 git commit-graph write --stdin-packs stderr && @@ -40,6 +40,15 @@ test_expect_success 'create commits and repack' ' git repack ' +test_expect_success 'exit with correct error on bad input to --stdin-commits' ' + cd "$TRASH_DIRECTORY/full" && + echo HEAD | test_expect_code 1 git commit-graph write --stdin-commits 2>stderr && + test_i18ngrep "invalid commit object id" stderr && + # valid tree OID, but not a commit OID + git rev-parse HEAD^{tree} | test_expect_code 1 git commit-graph write --stdin-commits 2>stderr && + test_i18ngrep "invalid commit object id" stderr +' + graph_git_two_modes() { git -c core.commitGraph=true $1 >output git -c core.commitGraph=false $1 >expect