bookmarks: prevent pushes of divergent bookmarks (foo@remote)
Before this change, such bookmarks are write-only: a client can push
them but not pull/read them. And because these bookmark can't be read,
even pushes are limited (for instance trying to delete such a bookmark
fails with a vanilla client because the client thinks the bookmark is
neither on the local nor the remote).
This change makes the server refuses such bookmarks, and for earlier
errors, makes the client refuse to send them.
I think the change of behavior is acceptable because I think this is a
bug in push/pull, and I don't think we change the behavior of `hg
unbundle`, because it doesn't seem that `hg bundle` ever store
bookmarks (and even if it did, it would seem weird anyway to try to
send divergent bookmarks).
Differential Revision: https://phab.mercurial-scm.org/D8117
--- a/mercurial/bookmarks.py Thu Feb 13 22:06:57 2020 -0500
+++ b/mercurial/bookmarks.py Thu Feb 13 22:51:17 2020 -0500
@@ -487,6 +487,8 @@
def pushbookmark(repo, key, old, new):
+ if isdivergent(key):
+ return False
if bookmarksinstore(repo):
wlock = util.nullcontextmanager()
else:
--- a/mercurial/bundle2.py Thu Feb 13 22:06:57 2020 -0500
+++ b/mercurial/bundle2.py Thu Feb 13 22:51:17 2020 -0500
@@ -2368,6 +2368,11 @@
b'prepushkey', throw=True, **pycompat.strkwargs(hookargs)
)
+ for book, node in changes:
+ if bookmarks.isdivergent(book):
+ msg = _(b'cannot accept divergent bookmark %s!') % book
+ raise error.Abort(msg)
+
bookstore.applychanges(op.repo, op.gettransaction(), changes)
if pushkeycompat:
--- a/mercurial/exchange.py Thu Feb 13 22:06:57 2020 -0500
+++ b/mercurial/exchange.py Thu Feb 13 22:51:17 2020 -0500
@@ -856,7 +856,11 @@
for b, scid, dcid in addsrc:
if b in explicit:
explicit.remove(b)
- pushop.outbookmarks.append((b, b'', scid))
+ if bookmod.isdivergent(b):
+ pushop.ui.warn(_(b'cannot push divergent bookmark %s!\n') % b)
+ pushop.bkresult = 2
+ else:
+ pushop.outbookmarks.append((b, b'', scid))
# search for overwritten bookmark
for b, scid, dcid in list(advdst) + list(diverge) + list(differ):
if b in explicit:
--- a/relnotes/next Thu Feb 13 22:06:57 2020 -0500
+++ b/relnotes/next Thu Feb 13 22:51:17 2020 -0500
@@ -24,6 +24,7 @@
* Use `hg copy --forget --at-rev REV` to unmark already committed
copies.
+ * prevent pushes of divergent bookmarks (foo@remote)
== Bug Fixes ==
--- a/tests/test-bookmarks-pushpull.t Thu Feb 13 22:06:57 2020 -0500
+++ b/tests/test-bookmarks-pushpull.t Thu Feb 13 22:51:17 2020 -0500
@@ -328,6 +328,17 @@
#endif
+Divergent bookmark cannot be exported
+
+ $ hg book W@default
+ $ hg push -B W@default ../a
+ pushing to ../a
+ searching for changes
+ cannot push divergent bookmark W@default!
+ no changes found
+ [2]
+ $ hg book -d W@default
+
export the active bookmark
$ hg bookmark V