On 1/29/2021 12:11 PM, René Scharfe wrote: > Am 28.01.21 um 21:51 schrieb Junio C Hamano: >> "Derrick Stolee via GitGitGadget" <gitgitgadget@xxxxxxxxx> writes: >>> + /* rearrange array */ >>> + dup = xcalloc(cnt, sizeof(struct commit *)); >>> + COPY_ARRAY(dup, array, cnt); >>> + for (i = 0; i < cnt; i++) { >>> + if (dup[i]->object.flags & STALE) { >>> + int insert = cnt - 1 - (i - count_non_stale); >>> + array[insert] = dup[i]; >>> + } else { >>> + array[count_non_stale] = dup[i]; >>> + count_non_stale++; >>> + } >>> + } >>> + free(dup); >> >> The "fill stale ones from the end, non-stale ones from the >> beginning" in the loop looks unnecessarily complex to me. I wonder >> if we can do only the "fill non-stale ones from the beginning" half, >> i.e. >> >> for (i = count_non_stale = 0; i < cnt; i++) { >> if (dup[i] is not stale) >> array[count_non_stale++] = dup[i]; >> } >> >> without the "keep the stale one at the end of array[]", and clear >> marks using what is in dup[] as starting points before discarding >> dup[]? >> >> Or do the callers still look at the entries beyond count_non_stale? > > Had the same reaction. Both callers ignore the stale entries. Ok, I can update that logic accordingly. I wanted to keep consistent with the comment at the start of the method: /* * Some commit in the array may be an ancestor of * another commit. Move such commit to the end of * the array, and return the number of commits that * are independent from each other. */ but if no caller actually needs that, then I can remove this behavior. Anyone mind if it is a follow-up patch to change this part of the behavior? >> Other than that, nicely done. >> >>> + /* clear marks */ >>> + for (i = 0; i < cnt; i++) { >>> + struct commit_list *parents; >>> + parents = array[i]->parents; >>> + >>> + while (parents) { >>> + clear_commit_marks(parents->item, STALE); >>> + parents = parents->next; >>> } > > This loop clears STALE from the parents of both the non-stale and > stale entries. OK. Should it also clear it from the stale entries > themselves? clear_commit_marks() walks commits starting from the input commit (parents->item in this case) and clears the STALE bit as long as it is present. This way, the accumulated clear_commit_marks() will walk each commit only once _and_ will visit any of the commits from 'array' that received the STALE bit during the above walk. Thanks, -Stolee