Mercurial > hg
comparison mercurial/discovery.py @ 50393:f95ab2c53303
outgoing: fix common-heads computation from `missingroots` argument
When initializing a `outgoing` object, the `common set` can be defined explicitly (with the `commonheads` argument`) or implicitly (with the missingroots arguments).
It turns out the logic to compute `commonheads` from `missingroots` is buggy, as it does not consider the parents of enough changesets. Previously, it only considered parents of "missingroots` items, while it need to consider all parents of missing. Here is an example:
F
|\
C E
| |
B D
|/
A
If we use [E] as missing-roots, the missing set is [E, F], and the common-heads
are [C, D]. However you cannot only consider the parent of [E] to find them, as
[C] is not a parent of [E].
This already fix the bundle generated in one test, and it would prevent many
other to misbehave with future change from this series.
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Fri, 10 Mar 2023 04:04:10 +0100 |
parents | 642e31cb55f0 |
children | 2e10ddbb9faa |
comparison
equal
deleted
inserted
replaced
50392:385a4f8056e5 | 50393:f95ab2c53303 |
---|---|
102 assert None in (commonheads, missingroots) | 102 assert None in (commonheads, missingroots) |
103 cl = repo.changelog | 103 cl = repo.changelog |
104 if ancestorsof is None: | 104 if ancestorsof is None: |
105 ancestorsof = cl.heads() | 105 ancestorsof = cl.heads() |
106 if missingroots: | 106 if missingroots: |
107 discbases = [] | |
108 for n in missingroots: | |
109 discbases.extend([p for p in cl.parents(n) if p != repo.nullid]) | |
110 # TODO remove call to nodesbetween. | 107 # TODO remove call to nodesbetween. |
111 # TODO populate attributes on outgoing instance instead of setting | 108 # TODO populate attributes on outgoing instance instead of setting |
112 # discbases. | 109 # discbases. |
113 csets, roots, heads = cl.nodesbetween(missingroots, ancestorsof) | 110 csets, roots, heads = cl.nodesbetween(missingroots, ancestorsof) |
114 included = set(csets) | 111 included = set(csets) |
112 discbases = [] | |
113 for n in csets: | |
114 discbases.extend([p for p in cl.parents(n) if p != repo.nullid]) | |
115 ancestorsof = heads | 115 ancestorsof = heads |
116 commonheads = [n for n in discbases if n not in included] | 116 commonheads = [n for n in discbases if n not in included] |
117 elif not commonheads: | 117 elif not commonheads: |
118 commonheads = [repo.nullid] | 118 commonheads = [repo.nullid] |
119 self.commonheads = commonheads | 119 self.commonheads = commonheads |