diff options
author | Junio C Hamano <gitster@pobox.com> | 2023-05-10 20:23:27 +0300 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2023-05-10 20:23:28 +0300 |
commit | e2abfa7212525daa24a52d9f53c45b736abb5dfe (patch) | |
tree | 955c71a79ebb32c86f1d09bbe181b914ecb13da6 /negotiator/skipping.c | |
parent | 07ac32fff94b245aec3e2b80efad0b5dada629cb (diff) | |
parent | 10e8a52ef11bbf260f0cb672d9b02b3cd9c780ca (diff) |
Merge branch 'hx/negotiator-non-recursive'
The implementation of the default "negotiator", used to find common
ancestor over the network for object tranfer, used to be recursive;
it was updated to be iterative to conserve stackspace usage.
* hx/negotiator-non-recursive:
negotiator/skipping: fix some problems in mark_common()
negotiator/default: avoid stack overflow
Diffstat (limited to 'negotiator/skipping.c')
-rw-r--r-- | negotiator/skipping.c | 22 |
1 files changed, 15 insertions, 7 deletions
diff --git a/negotiator/skipping.c b/negotiator/skipping.c index 97e7e1ae72..5b91520430 100644 --- a/negotiator/skipping.c +++ b/negotiator/skipping.c @@ -86,29 +86,37 @@ static int clear_marks(const char *refname, const struct object_id *oid, } /* - * Mark this SEEN commit and all its SEEN ancestors as COMMON. + * Mark this SEEN commit and all its parsed SEEN ancestors as COMMON. */ static void mark_common(struct data *data, struct commit *seen_commit) { struct prio_queue queue = { NULL }; struct commit *c; + if (seen_commit->object.flags & COMMON) + return; + prio_queue_put(&queue, seen_commit); + seen_commit->object.flags |= COMMON; while ((c = prio_queue_get(&queue))) { struct commit_list *p; - if (c->object.flags & COMMON) - return; - c->object.flags |= COMMON; + if (!(c->object.flags & POPPED)) data->non_common_revs--; if (!c->object.parsed) - return; + continue; for (p = c->parents; p; p = p->next) { - if (p->item->object.flags & SEEN) - prio_queue_put(&queue, p->item); + if (!(p->item->object.flags & SEEN) || + (p->item->object.flags & COMMON)) + continue; + + p->item->object.flags |= COMMON; + prio_queue_put(&queue, p->item); } } + + clear_prio_queue(&queue); } /* |