@matheusbsbs / matheus-bagliano / commits / 6830c36077
Fork 0

commit-graph.h: replace 'commit_hex' with 'commits'

The 'write_commit_graph()' function takes in either a string list of pack indices, or a string list of hexadecimal commit OIDs. These correspond to the '--stdin-packs' and '--stdin-commits' mode(s) from 'git commit-graph write'. Using a string_list of hexadecimal commit IDs is not the most efficient use of memory, since we can instead use the 'struct oidset', which is more well-suited for this case. This has another benefit which will become apparent in the following commit. This is that we are about to disambiguate the kinds of errors we produce with '--stdin-commits' into "non-hex input" and "hex-input, but referring to a non-commit object". By having 'write_commit_graph' take in a 'struct oidset *' of commits, we place the burden on the caller (in this case, the builtin) to handle the first case, and the commit-graph machinery can handle the second case. Suggested-by: Jeff King <peff@peff.net> Signed-off-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Taylor Blau committed Apr 13, 2020 at 22:04 UTC 6830c360777468434184f60023e2562348c9dacc
4 files changed +52 -31
builtin/commit-graph.c
+16 -3
@@ -137,7 +137,7 @@ static int write_option_parse_split(const struct option *opt, const char *arg,
137 static int graph_write(int argc, const char **argv)
138 {
139 struct string_list *pack_indexes = NULL;
140 - struct string_list *commit_hex = NULL;
140 + struct oidset commits = OIDSET_INIT;
141 struct object_directory *odb = NULL;
142 struct string_list lines;
143 int result = 0;
@@ -210,7 +210,20 @@ static int graph_write(int argc, const char **argv)
210 if (opts.stdin_packs)
211 pack_indexes = &lines;
212 if (opts.stdin_commits) {
213 - commit_hex = &lines;
213 + struct string_list_item *item;
214 + oidset_init(&commits, lines.nr);
215 + for_each_string_list_item(item, &lines) {
216 + struct object_id oid;
217 + const char *end;
218 +
219 + if (parse_oid_hex(item->string, &oid, &end)) {
220 + error(_("unexpected non-hex object ID: "
221 + "%s"), item->string);
222 + return 1;
223 + }
224 +
225 + oidset_insert(&commits, &oid);
226 + }
227 flags |= COMMIT_GRAPH_WRITE_CHECK_OIDS;
228 }
229
@@ -219,7 +232,7 @@ static int graph_write(int argc, const char **argv)
232
233 if (write_commit_graph(odb,
234 pack_indexes,
222 - commit_hex,
235 + opts.stdin_commits ? &commits : NULL,
236 flags,
237 &split_opts))
238 result = 1;
commit-graph.c
+33 -26
@@ -1136,13 +1136,13 @@ static void compute_generation_numbers(struct write_commit_graph_context *ctx)
1136 stop_progress(&ctx->progress);
1137 }
1138
1139 -static int add_ref_to_list(const char *refname,
1140 - const struct object_id *oid,
1141 - int flags, void *cb_data)
1139 +static int add_ref_to_set(const char *refname,
1140 + const struct object_id *oid,
1141 + int flags, void *cb_data)
1142 {
1143 - struct string_list *list = (struct string_list *)cb_data;
1143 + struct oidset *commits = (struct oidset *)cb_data;
1144
1145 - string_list_append(list, oid_to_hex(oid));
1145 + oidset_insert(commits, oid);
1146 return 0;
1147 }
1148
@@ -1150,14 +1150,14 @@ int write_commit_graph_reachable(struct object_directory *odb,
1150 enum commit_graph_write_flags flags,
1151 const struct split_commit_graph_opts *split_opts)
1152 {
1153 - struct string_list list = STRING_LIST_INIT_DUP;
1153 + struct oidset commits = OIDSET_INIT;
1154 int result;
1155
1156 - for_each_ref(add_ref_to_list, &list);
1157 - result = write_commit_graph(odb, NULL, &list,
1156 + for_each_ref(add_ref_to_set, &commits);
1157 + result = write_commit_graph(odb, NULL, &commits,
1158 flags, split_opts);
1159
1160 - string_list_clear(&list, 0);
1160 + oidset_clear(&commits);
1161 return result;
1162 }
1163
@@ -1206,39 +1206,46 @@ static int fill_oids_from_packs(struct write_commit_graph_context *ctx,
1206 return 0;
1207 }
1208
1209 -static int fill_oids_from_commit_hex(struct write_commit_graph_context *ctx,
1210 - struct string_list *commit_hex)
1209 +static int fill_oids_from_commits(struct write_commit_graph_context *ctx,
1210 + struct oidset *commits)
1211 {
1212 - uint32_t i;
1212 + uint32_t i = 0;
1213 struct strbuf progress_title = STRBUF_INIT;
1214 + struct oidset_iter iter;
1215 + struct object_id *oid;
1216 +
1217 + if (!oidset_size(commits))
1218 + return 0;
1219
1220 if (ctx->report_progress) {
1221 strbuf_addf(&progress_title,
1222 Q_("Finding commits for commit graph from %d ref",
1223 "Finding commits for commit graph from %d refs",
1219 - commit_hex->nr),
1220 - commit_hex->nr);
1224 + oidset_size(commits)),
1225 + oidset_size(commits));
1226 ctx->progress = start_delayed_progress(
1227 progress_title.buf,
1223 - commit_hex->nr);
1228 + oidset_size(commits));
1229 }
1225 - for (i = 0; i < commit_hex->nr; i++) {
1226 - const char *end;
1227 - struct object_id oid;
1230 +
1231 + oidset_iter_init(commits, &iter);
1232 + while ((oid = oidset_iter_next(&iter))) {
1233 struct commit *result;
1234
1230 - display_progress(ctx->progress, i + 1);
1231 - if (!parse_oid_hex(commit_hex->items[i].string, &oid, &end) &&
1232 - (result = lookup_commit_reference_gently(ctx->r, &oid, 1))) {
1235 + display_progress(ctx->progress, ++i);
1236 +
1237 + result = lookup_commit_reference_gently(ctx->r, oid, 1);
1238 + if (result) {
1239 ALLOC_GROW(ctx->oids.list, ctx->oids.nr + 1, ctx->oids.alloc);
1240 oidcpy(&ctx->oids.list[ctx->oids.nr], &(result->object.oid));
1241 ctx->oids.nr++;
1242 } else if (ctx->check_oids) {
1243 error(_("invalid commit object id: %s"),
1238 - commit_hex->items[i].string);
1244 + oid_to_hex(oid));
1245 return -1;
1246 }
1247 }
1248 +
1249 stop_progress(&ctx->progress);
1250 strbuf_release(&progress_title);
1251
@@ -1785,7 +1792,7 @@ out:
1792
1793 int write_commit_graph(struct object_directory *odb,
1794 struct string_list *pack_indexes,
1788 - struct string_list *commit_hex,
1795 + struct oidset *commits,
1796 enum commit_graph_write_flags flags,
1797 const struct split_commit_graph_opts *split_opts)
1798 {
@@ -1861,12 +1868,12 @@ int write_commit_graph(struct object_directory *odb,
1868 goto cleanup;
1869 }
1870
1864 - if (commit_hex) {
1865 - if ((res = fill_oids_from_commit_hex(ctx, commit_hex)))
1871 + if (commits) {
1872 + if ((res = fill_oids_from_commits(ctx, commits)))
1873 goto cleanup;
1874 }
1875
1869 - if (!pack_indexes && !commit_hex)
1876 + if (!pack_indexes && !commits)
1877 fill_oids_from_all_packs(ctx);
1878
1879 close_reachable(ctx);
commit-graph.h
+2 -1
@@ -6,6 +6,7 @@
6 #include "string-list.h"
7 #include "cache.h"
8 #include "object-store.h"
9 +#include "oidset.h"
10
11 #define GIT_TEST_COMMIT_GRAPH "GIT_TEST_COMMIT_GRAPH"
12 #define GIT_TEST_COMMIT_GRAPH_DIE_ON_LOAD "GIT_TEST_COMMIT_GRAPH_DIE_ON_LOAD"
@@ -106,7 +107,7 @@ int write_commit_graph_reachable(struct object_directory *odb,
107 const struct split_commit_graph_opts *split_opts);
108 int write_commit_graph(struct object_directory *odb,
109 struct string_list *pack_indexes,
109 - struct string_list *commit_hex,
110 + struct oidset *commits,
111 enum commit_graph_write_flags flags,
112 const struct split_commit_graph_opts *split_opts);
113
t/t5318-commit-graph.sh
+1 -1
@@ -43,7 +43,7 @@ test_expect_success 'create commits and repack' '
43 test_expect_success 'exit with correct error on bad input to --stdin-commits' '
44 cd "$TRASH_DIRECTORY/full" &&
45 echo HEAD | test_expect_code 1 git commit-graph write --stdin-commits 2>stderr &&
46 - test_i18ngrep "invalid commit object id" stderr &&
46 + test_i18ngrep "unexpected non-hex object ID: HEAD" stderr &&
47 # valid tree OID, but not a commit OID
48 git rev-parse HEAD^{tree} | test_expect_code 1 git commit-graph write --stdin-commits 2>stderr &&
49 test_i18ngrep "invalid commit object id" stderr