mercurial/localrepo.py
changeset 9567 02c43e8e0835
parent 9437 1c4e4004f3a6
parent 9479 f3569d95c2ab
child 9569 ceb0f59e1327
--- a/mercurial/localrepo.py	Tue Sep 29 00:54:15 2009 +0200
+++ b/mercurial/localrepo.py	Wed Sep 30 21:14:24 2009 +0200
@@ -1159,17 +1159,24 @@
         return [n for (r, n) in sorted(heads)]
 
     def branchheads(self, branch=None, start=None, closed=False):
+        '''return a (possibly filtered) list of heads for the given branch
+
+        Heads are returned in topological order, from newest to oldest.
+        If branch is None, use the dirstate branch.
+        If start is not None, return only heads reachable from start.
+        If closed is True, return heads that are marked as closed as well.
+        '''
         if branch is None:
             branch = self[None].branch()
         branches = self.branchmap()
         if branch not in branches:
             return []
-        bheads = branches[branch]
         # the cache returns heads ordered lowest to highest
-        bheads.reverse()
+        bheads = list(reversed(branches[branch]))
         if start is not None:
             # filter out the heads that cannot be reached from startrev
-            bheads = self.changelog.nodesbetween([start], bheads)[2]
+            fbheads = set(self.changelog.nodesbetween([start], bheads)[2])
+            bheads = [h for h in bheads if h in fbheads]
         if not closed:
             bheads = [h for h in bheads if
                       ('close' not in self.changelog.read(h)[5])]
@@ -1468,19 +1475,16 @@
         inc = self.findincoming(remote, common, remote_heads, force=force)
 
         update, updated_heads = self.findoutgoing(remote, common, remote_heads)
-        if revs is not None:
-            msng_cl, bases, heads = self.changelog.nodesbetween(update, revs)
-        else:
-            bases, heads = update, self.changelog.heads()
+        msng_cl, bases, heads = self.changelog.nodesbetween(update, revs)
 
-        def checkbranch(lheads, rheads, updatelh):
+        def checkbranch(lheads, rheads, updatelb):
             '''
             check whether there are more local heads than remote heads on
             a specific branch.
 
             lheads: local branch heads
             rheads: remote branch heads
-            updatelh: outgoing local branch heads
+            updatelb: outgoing local branch bases
             '''
 
             warn = 0
@@ -1488,13 +1492,15 @@
             if not revs and len(lheads) > len(rheads):
                 warn = 1
             else:
+                # add local heads involved in the push
                 updatelheads = [self.changelog.heads(x, lheads)
-                                for x in updatelh]
+                                for x in updatelb]
                 newheads = set(sum(updatelheads, [])) & set(lheads)
 
                 if not newheads:
                     return True
 
+                # add heads we don't have or that are not involved in the push
                 for r in rheads:
                     if r in self.changelog.nodemap:
                         desc = self.changelog.heads(r, heads)
@@ -1510,7 +1516,7 @@
                 if not rheads: # new branch requires --force
                     self.ui.warn(_("abort: push creates new"
                                    " remote branch '%s'!\n") %
-                                   self[updatelh[0]].branch())
+                                   self[updatelb[0]].branch())
                 else:
                     self.ui.warn(_("abort: push creates new remote heads!\n"))
 
@@ -1553,11 +1559,11 @@
                         else:
                             rheads = []
                         lheads = localhds[lh]
-                        updatelh = [upd for upd in update
+                        updatelb = [upd for upd in update
                                     if self[upd].branch() == lh]
-                        if not updatelh:
+                        if not updatelb:
                             continue
-                        if not checkbranch(lheads, rheads, updatelh):
+                        if not checkbranch(lheads, rheads, updatelb):
                             return None, 0
                 else:
                     if not checkbranch(heads, remote_heads, update):