Mercurial > hg
comparison mercurial/discovery.py @ 44450:7d5455b988ec stable
discovery: avoid wrong detection of multiple branch heads (issue6256)
This fix the code using obsolescence markers to remove "to be obsoleted" heads
during the detection of new head creation from push. The code turned out to not
use the branch information at all. This lead changeset from different branch to
be detected as new head on unrelated branch.
The code fix is actually quite simple. New tests have been added to covers
these cases.
Differential Revision: https://phab.mercurial-scm.org/D8259
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Fri, 06 Mar 2020 23:27:28 +0100 |
parents | 65d6770273c8 |
children | a08bbdf839ae b561f3a68e41 |
comparison
equal
deleted
inserted
replaced
44432:dca4b5da417d | 44450:7d5455b988ec |
---|---|
496 # marker and a new is created | 496 # marker and a new is created |
497 | 497 |
498 # define various utilities and containers | 498 # define various utilities and containers |
499 repo = pushop.repo | 499 repo = pushop.repo |
500 unfi = repo.unfiltered() | 500 unfi = repo.unfiltered() |
501 tonode = unfi.changelog.node | |
502 torev = unfi.changelog.index.get_rev | 501 torev = unfi.changelog.index.get_rev |
503 public = phases.public | 502 public = phases.public |
504 getphase = unfi._phasecache.phase | 503 getphase = unfi._phasecache.phase |
505 ispublic = lambda r: getphase(unfi, r) == public | 504 ispublic = lambda r: getphase(unfi, r) == public |
506 ispushed = lambda n: torev(n) in futurecommon | 505 ispushed = lambda n: torev(n) in futurecommon |
528 return unknownheads | set(candidate_newhs), set() | 527 return unknownheads | set(candidate_newhs), set() |
529 | 528 |
530 # actually process branch replacement | 529 # actually process branch replacement |
531 while localcandidate: | 530 while localcandidate: |
532 nh = localcandidate.pop() | 531 nh = localcandidate.pop() |
532 current_branch = unfi[nh].branch() | |
533 # run this check early to skip the evaluation of the whole branch | 533 # run this check early to skip the evaluation of the whole branch |
534 if torev(nh) in futurecommon or ispublic(torev(nh)): | 534 if torev(nh) in futurecommon or ispublic(torev(nh)): |
535 newhs.add(nh) | 535 newhs.add(nh) |
536 continue | 536 continue |
537 | 537 |
538 # Get all revs/nodes on the branch exclusive to this head | 538 # Get all revs/nodes on the branch exclusive to this head |
539 # (already filtered heads are "ignored")) | 539 # (already filtered heads are "ignored")) |
540 branchrevs = unfi.revs( | 540 branchrevs = unfi.revs( |
541 b'only(%n, (%ln+%ln))', nh, localcandidate, newhs | 541 b'only(%n, (%ln+%ln))', nh, localcandidate, newhs |
542 ) | 542 ) |
543 branchnodes = [tonode(r) for r in branchrevs] | 543 |
544 branchnodes = [] | |
545 for r in branchrevs: | |
546 c = unfi[r] | |
547 if c.branch() == current_branch: | |
548 branchnodes.append(c.node()) | |
544 | 549 |
545 # The branch won't be hidden on the remote if | 550 # The branch won't be hidden on the remote if |
546 # * any part of it is public, | 551 # * any part of it is public, |
547 # * any part of it is considered part of the result by previous logic, | 552 # * any part of it is considered part of the result by previous logic, |
548 # * if we have no markers to push to obsolete it. | 553 # * if we have no markers to push to obsolete it. |