commit df9fee32dd219ae70b3e0c8d7a0bd95a8d063f68 from: Stefan Sperling date: Wed Jun 25 19:00:44 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 - 82bf4748c2294f02084474503c8929675108b220 commit + df9fee32dd219ae70b3e0c8d7a0bd95a8d063f68 blob - 6a99c87bcd4304e66565ac48ac46681c1e80c623 blob + d37eb5a0e5cefff82a8f7ed72c8d4a06d4513a8e --- libexec/got-read-pack/got-read-pack.c +++ libexec/got-read-pack/got-read-pack.c @@ -1688,13 +1688,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) @@ -1722,8 +1727,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; } @@ -1793,6 +1805,7 @@ done: if (commit) got_object_commit_close(commit); got_object_id_queue_free(&repaint); + got_object_idset_free(traversed); return err; }