path-walk: create initializer for path lists

The previous change fixed a bug in 'git repack -adf --path-walk' that was due to an update to how path lists are initialized and missing some important cases when processing the pending objects. This change takes the three critical places where path lists are initialized and combines them into a static method. This simplifies the callers somewhat while also helping to avoid a missed update in the future. The other places where a path list (struct type_and_oid_list) is initialized is for the following "fixed" lists: * Tag objects. * Commit objects. * Root trees. * Tagged trees. * Tagged blobs. These lists are created and consumed in different ways, with only the root trees being passed into the logic that cares about the "maybe_interesting" bit. It is appropriate to keep these uses separate. Signed-off-by: Derrick Stolee <stolee@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Derrick Stolee committed Aug 25, 2025 at 12:49 UTC 93afe9b060dedd94c20feb8da553cef0e4301176
1 file changed +25 -32
path-walk.c
+25 -32
@@ -105,6 +105,24 @@ static void push_to_stack(struct path_walk_context *ctx,
105 prio_queue_put(&ctx->path_stack, xstrdup(path));
106 }
107
108 +static void add_path_to_list(struct path_walk_context *ctx,
109 + const char *path,
110 + enum object_type type,
111 + struct object_id *oid,
112 + int interesting)
113 +{
114 + struct type_and_oid_list *list = strmap_get(&ctx->paths_to_lists, path);
115 +
116 + if (!list) {
117 + CALLOC_ARRAY(list, 1);
118 + list->type = type;
119 + strmap_put(&ctx->paths_to_lists, path, list);
120 + }
121 +
122 + list->maybe_interesting |= interesting;
123 + oid_array_append(&list->oids, oid);
124 +}
125 +
126 static int add_tree_entries(struct path_walk_context *ctx,
127 const char *base_path,
128 struct object_id *oid)
@@ -129,7 +147,6 @@ static int add_tree_entries(struct path_walk_context *ctx,
147
148 init_tree_desc(&desc, &tree->object.oid, tree->buffer, tree->size);
149 while (tree_entry(&desc, &entry)) {
132 - struct type_and_oid_list *list;
150 struct object *o;
151 /* Not actually true, but we will ignore submodules later. */
152 enum object_type type = S_ISDIR(entry.mode) ? OBJ_TREE : OBJ_BLOB;
@@ -190,17 +207,10 @@ static int add_tree_entries(struct path_walk_context *ctx,
207 continue;
208 }
209
193 - if (!(list = strmap_get(&ctx->paths_to_lists, path.buf))) {
194 - CALLOC_ARRAY(list, 1);
195 - list->type = type;
196 - strmap_put(&ctx->paths_to_lists, path.buf, list);
197 - }
198 - push_to_stack(ctx, path.buf);
199 -
200 - if (!(o->flags & UNINTERESTING))
201 - list->maybe_interesting = 1;
210 + add_path_to_list(ctx, path.buf, type, &entry.oid,
211 + !(o->flags & UNINTERESTING));
212
203 - oid_array_append(&list->oids, &entry.oid);
213 + push_to_stack(ctx, path.buf);
214 }
215
216 free_tree_buffer(tree);
@@ -377,16 +387,9 @@ static int setup_pending_objects(struct path_walk_info *info,
387 if (!info->trees)
388 continue;
389 if (pending->path) {
380 - struct type_and_oid_list *list;
390 char *path = *pending->path ? xstrfmt("%s/", pending->path)
391 : xstrdup("");
383 - if (!(list = strmap_get(&ctx->paths_to_lists, path))) {
384 - CALLOC_ARRAY(list, 1);
385 - list->type = OBJ_TREE;
386 - strmap_put(&ctx->paths_to_lists, path, list);
387 - }
388 - list->maybe_interesting = 1;
389 - oid_array_append(&list->oids, &obj->oid);
392 + add_path_to_list(ctx, path, OBJ_TREE, &obj->oid, 1);
393 free(path);
394 } else {
395 /* assume a root tree, such as a lightweight tag. */
@@ -397,20 +400,10 @@ static int setup_pending_objects(struct path_walk_info *info,
400 case OBJ_BLOB:
401 if (!info->blobs)
402 continue;
400 - if (pending->path) {
401 - struct type_and_oid_list *list;
402 - char *path = pending->path;
403 - if (!(list = strmap_get(&ctx->paths_to_lists, path))) {
404 - CALLOC_ARRAY(list, 1);
405 - list->type = OBJ_BLOB;
406 - strmap_put(&ctx->paths_to_lists, path, list);
407 - }
408 - list->maybe_interesting = 1;
409 - oid_array_append(&list->oids, &obj->oid);
410 - } else {
411 - /* assume a root tree, such as a lightweight tag. */
403 + if (pending->path)
404 + add_path_to_list(ctx, pending->path, OBJ_BLOB, &obj->oid, 1);
405 + else
406 oid_array_append(&tagged_blobs->oids, &obj->oid);
413 - }
407 break;
408
409 case OBJ_COMMIT: