diff hgext/fetch.py @ 7007:a6b74fbb5ce0

fetch: added support for named branches Previously, fetch didn't really work when there were multiple named branches in the repository. Now it tries to do the right thing(tm) in all situations.
author Sune Foldager <cryo@cyanite.org>
date Mon, 08 Sep 2008 12:55:46 +0200
parents b2bc2d984bac
children 6489ee64b522
line wrap: on
line diff
--- a/hgext/fetch.py	Mon Sep 08 12:55:27 2008 +0200
+++ b/hgext/fetch.py	Mon Sep 08 12:55:46 2008 +0200
@@ -16,7 +16,7 @@
     This finds all changes from the repository at the specified path
     or URL and adds them to the local repository.
 
-    If the pulled changes add a new head, the head is automatically
+    If the pulled changes add a new branch head, the head is automatically
     merged, and the result of the merge is committed.  Otherwise, the
     working directory is updated to include the new changes.
 
@@ -33,9 +33,10 @@
         opts['date'] = util.parsedate(date)
 
     parent, p2 = repo.dirstate.parents()
-    if parent != repo.changelog.tip():
-        raise util.Abort(_('working dir not at tip '
-                           '(use "hg update" to check out tip)'))
+    branch = repo[parent].branch()
+    if parent != repo[branch].node():
+        raise util.Abort(_('working dir not at branch tip '
+                           '(use "hg update" to check out branch tip)'))
 
     if p2 != nullid:
         raise util.Abort(_('outstanding uncommitted merge'))
@@ -50,9 +51,9 @@
             raise util.Abort(_('outstanding uncommitted changes'))
         if del_:
             raise util.Abort(_('working directory is missing some files'))
-        if len(repo.heads()) > 1:
-            raise util.Abort(_('multiple heads in this repository '
-                               '(use "hg heads" and "hg merge" to merge)'))
+        if len(repo.branchheads(branch)) > 1:
+            raise util.Abort(_('multiple heads in this branch '
+                               '(use "hg heads ." and "hg merge" to merge)'))
 
         cmdutil.setremoteconfig(ui, opts)
 
@@ -67,27 +68,35 @@
             else:
                 revs = [other.lookup(rev) for rev in opts['rev']]
 
+        # Are there any changes at all?
         modheads = repo.pull(other, heads=revs)
         if modheads == 0:
             return 0
-        if modheads == 1:
-            return hg.clean(repo, repo.changelog.tip())
 
-        newheads = repo.heads(parent)
-        newchildren = [n for n in repo.heads(parent) if n != parent]
+        # Is this a simple fast-forward along the current branch?
+        newheads = repo.branchheads(branch)
+        newchildren = repo.changelog.nodesbetween([parent], newheads)[2]
+        if len(newheads) == 1:
+            if newchildren[0] != parent:
+                return hg.clean(repo, newchildren[0])
+            else:
+                return
+
+        # Are there more than one additional branch heads?
+        newchildren = [n for n in newchildren if n != parent]
         newparent = parent
         if newchildren:
             newparent = newchildren[0]
             hg.clean(repo, newparent)
-
-        newheads = [n for n in repo.heads() if n != newparent]
+        newheads = [n for n in newheads if n != newparent]
         if len(newheads) > 1:
-            ui.status(_('not merging with %d other new heads '
-                        '(use "hg heads" and "hg merge" to merge them)') %
+            ui.status(_('not merging with %d other new branch heads '
+                        '(use "hg heads ." and "hg merge" to merge them)\n') %
                       (len(newheads) - 1))
             return
+
+        # Otherwise, let's merge.
         err = False
-
         if newheads:
             # By default, we consider the repository we're pulling
             # *from* as authoritative, so we merge our changes into