commit 2aca439f3f359e933abf310f4f0e0c95b93d2b65 from: Stefan Sperling via: Thomas Adam date: Fri Aug 15 14:42:43 2025 UTC better fix for long loop bug during commit coloring with offloading Repaint already queued commits in the main process instead of removing them from the queue. Otherwise we may never converge to a state where all commits are marked as skipped. Instead such commits can inherit color keep and we'll keep on asking got-read-pack to paint more commits for a very long time. ok op@ commit - 75b646bca6910853e348c548ab9677b68c2eed11 commit + 2aca439f3f359e933abf310f4f0e0c95b93d2b65 blob - e8b3e76a49c73b7f020f80fa794734e3fd506cfe blob + dc083bc858e0c9c77103cab6f819d1185a4e9656 --- lib/pack_create_privsep.c +++ lib/pack_create_privsep.c @@ -217,7 +217,7 @@ recv_painted_commit(void *arg, struct got_object_id *i { const struct got_error *err = NULL; struct recv_painted_commit_arg *a = arg; - struct got_object_qid *qid, *tmp; + struct got_object_qid *qid; if (a->cancel_cb) { err = a->cancel_cb(a->cancel_arg); @@ -254,17 +254,18 @@ recv_painted_commit(void *arg, struct got_object_id *i "%s invalid commit color %"PRIdPTR, __func__, color); } - STAILQ_FOREACH_SAFE(qid, a->ids, entry, tmp) { + STAILQ_FOREACH(qid, a->ids, entry) { + int ocolor; if (got_object_id_cmp(&qid->id, id) != 0) continue; - STAILQ_REMOVE(a->ids, qid, got_object_qid, entry); - color = (intptr_t)qid->data; - if (*(a->qid0) == qid) - *(a->qid0) = NULL; - got_object_qid_free(qid); - (*a->nqueued)--; - if (color == COLOR_SKIP) - (*a->nskip)--; + ocolor = (intptr_t)qid->data; + if (ocolor != color) { + got_pack_paint_commit(qid, color); + if (ocolor == COLOR_SKIP) + (*a->nskip)--; + else if (color == COLOR_SKIP) + (*a->nskip)++; + } break; }