[PATCH 1 of 2 RFC] bookmarks: allow push to create a new remote head if it is about to be bookmarked via -B

Stephen Lee sphen.lee at gmail.com
Wed Mar 13 06:13:32 CDT 2013


# HG changeset patch
# User Stephen Lee <sphen.lee at gmail.com>
# Date 1363171419 -39600
# Node ID 8dc95dea42930a4fa251f3bd67a3eb759b51e304
# Parent  a07be895373394be66ba38b1ff111e26aca03ac8
bookmarks: allow push to create a new remote head if it is about to be bookmarked via -B

Push is currently allowed to create a new head if there is a remote bookmark that will
be updated to point to the new head.  If the bookmark is not known remotely then
push aborts, even if a -B argument is about to push the bookmark. This change allows
push to continue in this case.  This does not require a wireproto force.

This is an RFC change.  The list of new bookmarks is stored in config to avoid changing
the signature of localrepo.push which is wrapped by many extensions (both bundled and external).
A real solution would need to find a cleaner way to do this.

diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -4766,6 +4766,7 @@
     """
 
     if opts.get('bookmark'):
+        ui.setconfig('bookmarks', 'pushing', opts['bookmark'])
         for b in opts['bookmark']:
             # translate -B options to -r so changesets get pushed
             if b in repo._bookmarks:
diff --git a/mercurial/discovery.py b/mercurial/discovery.py
--- a/mercurial/discovery.py
+++ b/mercurial/discovery.py
@@ -219,7 +219,8 @@
     unsynced = inc and set([None]) or set()
     return {None: (oldheads, newheads, unsynced)}
 
-def checkheads(repo, remote, outgoing, remoteheads, newbranch=False, inc=False):
+def checkheads(repo, remote, outgoing, remoteheads, newbranch=False, inc=False,
+               newbookmarks=[]):
     """Check that a push won't add any outgoing head
 
     raise Abort error and display ui message as needed.
@@ -259,6 +260,9 @@
             lctx, rctx = repo[bm], repo[rnode]
             if bookmarks.validdest(repo, rctx, lctx):
                 bookmarkedheads.add(lctx.node())
+        else:
+            if bm in newbookmarks:
+                bookmarkedheads.add(repo[bm].node())
 
     # 3. Check for new heads.
     # If there are more heads after the push than before, a suitable
diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -1806,9 +1806,10 @@
                                     raise util.Abort(_(mst)
                                                      % (ctx.troubles()[0],
                                                         ctx))
+                        newbm = self.ui.configlist('bookmarks', 'pushing')
                         discovery.checkheads(unfi, remote, outgoing,
                                              remoteheads, newbranch,
-                                             bool(inc))
+                                             bool(inc), newbm)
 
                     # create a changegroup from local
                     if revs is None and not outgoing.excluded:
diff --git a/tests/test-bookmarks-pushpull.t b/tests/test-bookmarks-pushpull.t
--- a/tests/test-bookmarks-pushpull.t
+++ b/tests/test-bookmarks-pushpull.t
@@ -392,4 +392,23 @@
   updating bookmark @ failed!
   exporting bookmark add-foo
 
+pushing a new bookmark on a new head does not require -f if -B is specified
+
+  $ hg up -q X
+  $ hg book W
+  $ echo c5 > f2
+  $ hg ci -Am5
+  created new head
+  $ hg push -B W
+  pushing to http://localhost:$HGPORT/
+  searching for changes
+  remote: adding changesets
+  remote: adding manifests
+  remote: adding file changes
+  remote: added 1 changesets with 1 changes to 1 files (+1 heads)
+  updating bookmark @ failed!
+  exporting bookmark W
+  $ hg -R ../b id -r W
+  cc978a373a53 tip W
+
   $ cd ..


More information about the Mercurial-devel mailing list