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.