[PATCH] named branches: --newbranch option to allow intial push of new branches

Sune Foldager sune.foldager at edlund.dk
Sat Jun 20 05:22:06 CDT 2009


# HG changeset patch
# User Sune Foldager <sune.foldager at edlund.dk>
# Date 1245491231 -7200
# Node ID 8fcc4eacbf961f09b6820d9d0c397905e99a926b
# Parent  b30775386d4064a22a52b35cd5449a2623cec27a
named branches: --newbranch option to allow intial push of new branches

Compare this to --force which allows anything to be pushed. With --newbranch,
only changesets to named branches not present on the remote are allowed.

Developed by
  Henrik Stuart <henrik.stuart at edlund.dk>
  Sune Foldager <cryo at cyanite.org>

diff --git a/hgext/mq.py b/hgext/mq.py
--- a/hgext/mq.py
+++ b/hgext/mq.py
@@ -2417,10 +2417,10 @@
             return super(mqrepo, self).commit(text, user, date, match, force,
                                               editor, extra)
 
-        def push(self, remote, force=False, revs=None):
+        def push(self, remote, force=False, revs=None, newbranch=False):
             if self.mq.applied and not force and not revs:
                 raise util.Abort(_('source has mq patches applied'))
-            return super(mqrepo, self).push(remote, force, revs)
+            return super(mqrepo, self).push(remote, force, revs, newbranch)
 
         def tags(self):
             if self.tagscache:
diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -2296,7 +2296,7 @@
     for s in sorted(subs):
         c.sub(s).push(opts.get('force'))
 
-    r = repo.push(other, opts.get('force'), revs=revs)
+    r = repo.push(other, opts.get('force'), revs=revs, newbranch=opts.get('newbranch'))
     return r == 0
 
 def recover(ui, repo):
@@ -3391,6 +3391,8 @@
          [('f', 'force', None, _('force push')),
           ('r', 'rev', [],
            _('a specific revision up to which you would like to push')),
+          ('', 'newbranch', False,
+           _('allows you to push a new branch')),
          ] + remoteopts,
          _('[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]')),
     "recover": (recover, []),
diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -1455,7 +1455,7 @@
         finally:
             lock.release()
 
-    def push(self, remote, force=False, revs=None):
+    def push(self, remote, force=False, revs=None, newbranch=False):
         # there are two ways to push to remote repo:
         #
         # addchangegroup assumes local user can lock remote
@@ -1465,10 +1465,10 @@
         # servers, http servers).
 
         if remote.capable('unbundle'):
-            return self.push_unbundle(remote, force, revs)
-        return self.push_addchangegroup(remote, force, revs)
+            return self.push_unbundle(remote, force, revs, newbranch)
+        return self.push_addchangegroup(remote, force, revs, newbranch)
 
-    def prepush(self, remote, force, revs):
+    def prepush(self, remote, force, revs, newbranch):
         common = {}
         remote_heads = remote.heads()
         inc = self.findincoming(remote, common, remote_heads, force=force)
@@ -1489,8 +1489,9 @@
             updatelh: outgoing local branch heads
             '''
 
+            if not rheads and newbranch:
+                return True
             warn = 0
-
             if not revs and len(lheads) > len(rheads):
                 warn = 1
             else:
@@ -1513,15 +1514,14 @@
                     warn = 1
 
             if warn:
-                if not rheads: # new branch requires --force
+                if not rheads: # new remote branch
                     self.ui.warn(_("abort: push creates new"
                                    " remote branch '%s'!\n" %
                                    self[updatelh[0]].branch()))
+                    self.ui.status(_("(use push --newbranch to create new remote branch)\n"))
                 else:
                     self.ui.warn(_("abort: push creates new remote heads!\n"))
-
-                self.ui.status(_("(did you forget to merge?"
-                                 " use push -f to force)\n"))
+                    self.ui.status(_("(did you forget to merge? use push -f to force)\n"))
                 return False
             return True
 
@@ -1580,10 +1580,10 @@
             cg = self.changegroupsubset(update, revs, 'push')
         return cg, remote_heads
 
-    def push_addchangegroup(self, remote, force, revs):
+    def push_addchangegroup(self, remote, force, revs, newbranch):
         lock = remote.lock()
         try:
-            ret = self.prepush(remote, force, revs)
+            ret = self.prepush(remote, force, revs, newbranch)
             if ret[0] is not None:
                 cg, remote_heads = ret
                 return remote.addchangegroup(cg, 'push', self.url())
@@ -1591,13 +1591,13 @@
         finally:
             lock.release()
 
-    def push_unbundle(self, remote, force, revs):
+    def push_unbundle(self, remote, force, revs, newbranch):
         # local repo finds heads on server, finds out what revs it
         # must push.  once revs transferred, if server finds it has
         # different heads (someone else won commit/push race), server
         # aborts.
 
-        ret = self.prepush(remote, force, revs)
+        ret = self.prepush(remote, force, revs, newbranch)
         if ret[0] is not None:
             cg, remote_heads = ret
             if force: remote_heads = ['force']


More information about the Mercurial-devel mailing list