commit b7e5019680e3d2e1827b8c759abbaf3e4e04ea0c from: Stefan Sperling via: Thomas Adam date: Fri Jun 27 06:52:35 2025 UTC fix looping in got-read-pack's version of repaint_parent_commits() as well This can be observed during 'got send' or 'gotadmin pack/cleanup' in some cases. We would keep processing the same parent commits over and over. commit - a474b672ce9285ba515ade45d6e91fe4a1648d2a commit + b7e5019680e3d2e1827b8c759abbaf3e4e04ea0c blob - 7cb78aa34375f957fecf53754566e88d72544b8a blob + 2af7045e637ced6184114182f42ce6e74105305c --- libexec/got-read-pack/got-read-pack.c +++ libexec/got-read-pack/got-read-pack.c @@ -1685,13 +1685,18 @@ repaint_parent_commits(struct got_object_id *commit_id struct got_pack *pack, struct got_packidx *packidx, struct got_object_cache *objcache) { - const struct got_error *err; + const struct got_error *err = NULL; const struct got_object_id_queue *parents; - struct got_commit_object *commit; + struct got_commit_object *commit = NULL; struct got_object_id_queue repaint; + struct got_object_idset *traversed; STAILQ_INIT(&repaint); + traversed = got_object_idset_alloc(); + if (traversed == NULL) + return got_error_from_errno("got_object_idset_alloc"); + err = open_commit(&commit, pack, packidx, commit_idx, commit_id, objcache); if (err) @@ -1719,8 +1724,15 @@ repaint_parent_commits(struct got_object_id *commit_id got_object_idset_contains(skip, &pid->id)) continue; + if (got_object_idset_contains(traversed, + &pid->id)) + continue; err = queue_commit_id(&repaint, &pid->id, color); + if (err) + goto done; + err = got_object_idset_add(traversed, + &pid->id, NULL); if (err) goto done; } @@ -1790,6 +1802,7 @@ done: if (commit) got_object_commit_close(commit); got_object_id_queue_free(&repaint); + got_object_idset_free(traversed); return err; }