mercurial/localrepo.py
changeset 4648 8e503fa54d2d
parent 4635 63b9d2deed48
child 4829 0403b80352c9
child 4864 fc389dcc33f5
equal deleted inserted replaced
4647:7c80e3e6f030 4648:8e503fa54d2d
  1016         heads = self.changelog.heads(start)
  1016         heads = self.changelog.heads(start)
  1017         # sort the output in rev descending order
  1017         # sort the output in rev descending order
  1018         heads = [(-self.changelog.rev(h), h) for h in heads]
  1018         heads = [(-self.changelog.rev(h), h) for h in heads]
  1019         heads.sort()
  1019         heads.sort()
  1020         return [n for (r, n) in heads]
  1020         return [n for (r, n) in heads]
       
  1021 
       
  1022     def branchheads(self, branch, start=None):
       
  1023         branches = self.branchtags()
       
  1024         if branch not in branches:
       
  1025             return []
       
  1026         # The basic algorithm is this:
       
  1027         #
       
  1028         # Start from the branch tip since there are no later revisions that can
       
  1029         # possibly be in this branch, and the tip is a guaranteed head.
       
  1030         #
       
  1031         # Remember the tip's parents as the first ancestors, since these by
       
  1032         # definition are not heads.
       
  1033         #
       
  1034         # Step backwards from the brach tip through all the revisions. We are
       
  1035         # guaranteed by the rules of Mercurial that we will now be visiting the
       
  1036         # nodes in reverse topological order (children before parents).
       
  1037         #
       
  1038         # If a revision is one of the ancestors of a head then we can toss it
       
  1039         # out of the ancestors set (we've already found it and won't be
       
  1040         # visiting it again) and put its parents in the ancestors set.
       
  1041         #
       
  1042         # Otherwise, if a revision is in the branch it's another head, since it
       
  1043         # wasn't in the ancestor list of an existing head.  So add it to the
       
  1044         # head list, and add its parents to the ancestor list.
       
  1045         #
       
  1046         # If it is not in the branch ignore it.
       
  1047         #
       
  1048         # Once we have a list of heads, use nodesbetween to filter out all the
       
  1049         # heads that cannot be reached from startrev.  There may be a more
       
  1050         # efficient way to do this as part of the previous algorithm.
       
  1051 
       
  1052         set = util.set
       
  1053         heads = [self.changelog.rev(branches[branch])]
       
  1054         # Don't care if ancestors contains nullrev or not.
       
  1055         ancestors = set(self.changelog.parentrevs(heads[0]))
       
  1056         for rev in xrange(heads[0] - 1, nullrev, -1):
       
  1057             if rev in ancestors:
       
  1058                 ancestors.update(self.changelog.parentrevs(rev))
       
  1059                 ancestors.remove(rev)
       
  1060             elif self.changectx(rev).branch() == branch:
       
  1061                 heads.append(rev)
       
  1062                 ancestors.update(self.changelog.parentrevs(rev))
       
  1063         heads = [self.changelog.node(rev) for rev in heads]
       
  1064         if start is not None:
       
  1065             heads = self.changelog.nodesbetween([start], heads)[2]
       
  1066         return heads
  1021 
  1067 
  1022     def branches(self, nodes):
  1068     def branches(self, nodes):
  1023         if not nodes:
  1069         if not nodes:
  1024             nodes = [self.changelog.tip()]
  1070             nodes = [self.changelog.tip()]
  1025         b = []
  1071         b = []