# HG changeset patch
# User Kevin Bullock <kbullock@ringworld.org>
# Date 2013-01-21 19:47:10
# Node ID 2096e025a728792c93e2f2cad005d43342a548f1
# Parent  28b3d669295e5210666de983ff058ab781916997

update: update to current bookmark if it moved out from under us (issue3682)

If the current bookmark (the one listed in .hg/bookmarks.current)
doesn't point to a parent of the working directory, e.g. if it was moved
by a pull, use that as the update target instead of the tipmost
descendent.

A small predicate is (finally) added to the bookmarks module to check
whether the current bookmark is also active.

diff --git a/mercurial/bookmarks.py b/mercurial/bookmarks.py
--- a/mercurial/bookmarks.py
+++ b/mercurial/bookmarks.py
@@ -134,6 +134,19 @@ def unsetcurrent(repo):
     finally:
         wlock.release()
 
+def iscurrent(repo, mark=None, parents=None):
+    '''Tell whether the current bookmark is also active
+
+    I.e., the bookmark listed in .hg/bookmarks.current also points to a
+    parent of the working directory.
+    '''
+    if not mark:
+        mark = repo._bookmarkcurrent
+    if not parents:
+        parents = [p.node() for p in repo[None].parents()]
+    marks = repo._bookmarks
+    return (mark in marks and marks[mark] in parents)
+
 def updatecurrentbookmark(repo, oldnode, curbranch):
     try:
         return update(repo, oldnode, repo.branchtip(curbranch))
diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -5961,7 +5961,12 @@ def update(ui, repo, node=None, rev=None
     # with no argument, we also move the current bookmark, if any
     movemarkfrom = None
     if rev is None:
-        movemarkfrom = repo['.'].node()
+        curmark = repo._bookmarkcurrent
+        if bookmarks.iscurrent(repo):
+            movemarkfrom = repo['.'].node()
+        elif curmark:
+            ui.status(_("updating to active bookmark %s\n") % curmark)
+            rev = curmark
 
     # if we defined a bookmark, we have to remember the original bookmark name
     brev = rev
diff --git a/tests/test-bookmarks.t b/tests/test-bookmarks.t
--- a/tests/test-bookmarks.t
+++ b/tests/test-bookmarks.t
@@ -458,7 +458,11 @@ create bundle with two heads
   adding file changes
   added 2 changesets with 2 changes to 2 files (+1 heads)
   (run 'hg heads' to see heads, 'hg merge' to merge)
+
+update to current bookmark if it's not the parent
+
   $ hg update
+  updating to active bookmark Z
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ hg bookmarks
      X2                        1:925d80f479bb