475 topoheads = None |
477 topoheads = None |
476 |
478 |
477 # If a changeset is visible, its parents must be visible too, so |
479 # If a changeset is visible, its parents must be visible too, so |
478 # use the faster unfiltered parent accessor. |
480 # use the faster unfiltered parent accessor. |
479 parentrevs = repo.unfiltered().changelog.parentrevs |
481 parentrevs = repo.unfiltered().changelog.parentrevs |
|
482 |
|
483 # Faster than using ctx.obsolete() |
|
484 obsrevs = obsolete.getrevs(repo, b'obsolete') |
480 |
485 |
481 for branch, newheadrevs in pycompat.iteritems(newbranches): |
486 for branch, newheadrevs in pycompat.iteritems(newbranches): |
482 # For every branch, compute the new branchheads. |
487 # For every branch, compute the new branchheads. |
483 # A branchhead is a revision such that no descendant is on |
488 # A branchhead is a revision such that no descendant is on |
484 # the same branch. |
489 # the same branch. |
516 # This computation is heavy and avoided if at all possible. |
521 # This computation is heavy and avoided if at all possible. |
517 bheads = self._entries.setdefault(branch, []) |
522 bheads = self._entries.setdefault(branch, []) |
518 bheadset = {cl.rev(node) for node in bheads} |
523 bheadset = {cl.rev(node) for node in bheads} |
519 uncertain = set() |
524 uncertain = set() |
520 for newrev in sorted(newheadrevs): |
525 for newrev in sorted(newheadrevs): |
|
526 if newrev in obsrevs: |
|
527 # We ignore obsolete changesets as they shouldn't be |
|
528 # considered heads. |
|
529 continue |
|
530 |
521 if not bheadset: |
531 if not bheadset: |
522 bheadset.add(newrev) |
532 bheadset.add(newrev) |
523 continue |
533 continue |
524 |
534 |
525 parents = [p for p in parentrevs(newrev) if p != nullrev] |
535 parents = [p for p in parentrevs(newrev) if p != nullrev] |
526 samebranch = set() |
536 samebranch = set() |
527 otherbranch = set() |
537 otherbranch = set() |
|
538 obsparents = set() |
528 for p in parents: |
539 for p in parents: |
529 if p in bheadset or getbranchinfo(p)[0] == branch: |
540 if p in obsrevs: |
|
541 # We ignored this obsolete changeset earlier, but now |
|
542 # that it has non-ignored children, we need to make |
|
543 # sure their ancestors are not considered heads. To |
|
544 # achieve that, we will simply treat this obsolete |
|
545 # changeset as a parent from other branch. |
|
546 obsparents.add(p) |
|
547 elif p in bheadset or getbranchinfo(p)[0] == branch: |
530 samebranch.add(p) |
548 samebranch.add(p) |
531 else: |
549 else: |
532 otherbranch.add(p) |
550 otherbranch.add(p) |
533 if otherbranch and not (len(bheadset) == len(samebranch) == 1): |
551 if not (len(bheadset) == len(samebranch) == 1): |
534 uncertain.update(otherbranch) |
552 uncertain.update(otherbranch) |
|
553 uncertain.update(obsparents) |
535 bheadset.difference_update(samebranch) |
554 bheadset.difference_update(samebranch) |
536 bheadset.add(newrev) |
555 bheadset.add(newrev) |
537 |
556 |
538 if uncertain: |
557 if uncertain: |
539 if topoheads is None: |
558 if topoheads is None: |
540 topoheads = set(cl.headrevs()) |
559 topoheads = set(cl.headrevs()) |
541 if bheadset - topoheads: |
560 if bheadset - topoheads: |
542 floorrev = min(bheadset) |
561 floorrev = min(bheadset) |
543 ancestors = set(cl.ancestors(newheadrevs, floorrev)) |
562 if floorrev <= max(uncertain): |
544 bheadset -= ancestors |
563 ancestors = set(cl.ancestors(uncertain, floorrev)) |
|
564 bheadset -= ancestors |
545 bheadrevs = sorted(bheadset) |
565 bheadrevs = sorted(bheadset) |
546 self[branch] = [cl.node(rev) for rev in bheadrevs] |
566 self[branch] = [cl.node(rev) for rev in bheadrevs] |
547 tiprev = bheadrevs[-1] |
567 tiprev = max(newheadrevs) |
548 if tiprev > ntiprev: |
568 if tiprev > ntiprev: |
549 ntiprev = tiprev |
569 ntiprev = tiprev |
550 |
570 |
551 if ntiprev > self.tiprev: |
571 if ntiprev > self.tiprev: |
552 self.tiprev = ntiprev |
572 self.tiprev = ntiprev |
553 self.tipnode = cl.node(ntiprev) |
573 self.tipnode = cl.node(ntiprev) |
554 |
574 |
555 if not self.validfor(repo): |
575 if not self.validfor(repo): |
556 # cache key are not valid anymore |
576 # old cache key is now invalid for the repo, but we've just updated |
|
577 # the cache and we assume it's valid, so let's make the cache key |
|
578 # valid as well by recomputing it from the cached data |
557 self.tipnode = repo.nullid |
579 self.tipnode = repo.nullid |
558 self.tiprev = nullrev |
580 self.tiprev = nullrev |
559 for heads in self.iterheads(): |
581 for heads in self.iterheads(): |
|
582 if not heads: |
|
583 # all revisions on a branch are obsolete |
|
584 continue |
|
585 # note: tiprev is not necessarily the tip revision of repo, |
|
586 # because the tip could be obsolete (i.e. not a head) |
560 tiprev = max(cl.rev(node) for node in heads) |
587 tiprev = max(cl.rev(node) for node in heads) |
561 if tiprev > self.tiprev: |
588 if tiprev > self.tiprev: |
562 self.tipnode = cl.node(tiprev) |
589 self.tipnode = cl.node(tiprev) |
563 self.tiprev = tiprev |
590 self.tiprev = tiprev |
564 self.filteredhash = scmutil.filteredhash(repo, self.tiprev) |
591 self.filteredhash = scmutil.filteredhash( |
|
592 repo, self.tiprev, needobsolete=True |
|
593 ) |
565 |
594 |
566 duration = util.timer() - starttime |
595 duration = util.timer() - starttime |
567 repo.ui.log( |
596 repo.ui.log( |
568 b'branchcache', |
597 b'branchcache', |
569 b'updated %s in %.4f seconds\n', |
598 b'updated %s in %.4f seconds\n', |