update: warn about other topological heads on bare update
authorPierre-Yves David <pierre-yves.david@fb.com>
Tue, 02 Feb 2016 14:49:02 +0000
changeset 28029 72072cfc7e91
parent 28028 ac49ecb2a897
child 28030 ca2a0a654f54
update: warn about other topological heads on bare update A concern around the user experience of Mercurial is user getting stuck on there own topological branch forever. For example, someone pulling another topological branch, missing that message in pull asking them to merge and getting stuck on there own local branch. The current way to "address" this concern was for bare 'hg update' to target the tipmost (also latest pulled) changesets and complain when the update was not linear. That way, failure to merge newly pulled changesets would result in some kind of failure. Yet the failure was quite obscure, not working in all cases (eg: commit right after pull) and the behavior was very impractical in the common case (eg: issue4673). To be able to change that behavior, we need to provide other ways to alert a user stucks on one of many topological head. We do so with an extra message after bare update: 1 other heads for branch "default" Bookmark get its own special version: 1 other divergent bookmarks for "foobar" There is significant room to improve the message itself, and we should augment it with hint about how to see theses other heads or handle the situation (see in-line comment). But having "a" message is already a significant improvement compared to the existing situation. Once we have it we can iterate on a better version of it. As having such message is an important step toward changing the default destination for update and other nicety, I would like to move forward quickly on getting such message. This was discussed during London - October 2015 Sprint.
mercurial/commands.py
mercurial/destutil.py
tests/test-bisect2.t
tests/test-blackbox.t
tests/test-bookmarks.t
tests/test-conflict.t
tests/test-largefiles-cache.t
tests/test-largefiles-update.t
tests/test-merge-changedelete.t
tests/test-merge-default.t
tests/test-merge-types.t
tests/test-merge5.t
tests/test-strip.t
tests/test-subrepo.t
tests/test-transplant.t
tests/test-update-branches.t
--- a/mercurial/commands.py	Wed Feb 03 04:37:04 2016 +0000
+++ b/mercurial/commands.py	Tue Feb 02 14:49:02 2016 +0000
@@ -6955,6 +6955,8 @@
     if rev is None or rev == '':
         rev = node
 
+    warndest = False
+
     with repo.wlock():
         cmdutil.clearunfinished(repo)
 
@@ -6976,6 +6978,7 @@
         if rev is None:
             updata = destutil.destupdate(repo, clean=clean, check=check)
             rev, movemarkfrom, brev = updata
+            warndest = True
 
         repo.ui.setconfig('ui', 'forcemerge', tool, 'update')
 
@@ -7002,7 +7005,8 @@
                 ui.status(_("(leaving bookmark %s)\n") %
                           repo._activebookmark)
             bookmarks.deactivate(repo)
-
+        if warndest:
+            destutil.statusotherdests(ui, repo)
     return ret
 
 @command('verify', [])
--- a/mercurial/destutil.py	Wed Feb 03 04:37:04 2016 +0000
+++ b/mercurial/destutil.py	Tue Feb 02 14:49:02 2016 +0000
@@ -218,3 +218,34 @@
             return revs.first()
 
     return None
+
+def _statusotherbook(ui, repo):
+    bmheads = repo.bookmarkheads(repo._activebookmark)
+    curhead = repo[repo._activebookmark].node()
+    if repo.revs('%n and parents()', curhead):
+        # we are on the active bookmark
+        bmheads = [b for b in bmheads if curhead != b]
+        if bmheads:
+            msg = _('%i other divergent bookmarks for "%s"\n')
+            ui.status(msg % (len(bmheads), repo._activebookmark))
+
+def _statusotherbranchheads(ui, repo):
+    currentbranch = repo.dirstate.branch()
+    heads = repo.branchheads(currentbranch)
+    l = len(heads)
+    if repo.revs('%ln and parents()', heads):
+        # we are on a head
+        heads = repo.revs('%ln - parents()', heads)
+        if heads and l != len(heads):
+            ui.status(_('%i other heads for branch "%s"\n') %
+                      (len(heads), currentbranch))
+
+def statusotherdests(ui, repo):
+    """Print message about other head"""
+    # XXX we should probably include a hint:
+    # - about what to do
+    # - how to see such heads
+    if repo._activebookmark:
+        _statusotherbook(ui, repo)
+    else:
+        _statusotherbranchheads(ui, repo)
--- a/tests/test-bisect2.t	Wed Feb 03 04:37:04 2016 +0000
+++ b/tests/test-bisect2.t	Tue Feb 02 14:49:02 2016 +0000
@@ -244,6 +244,7 @@
 
   $ hg up -C
   0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  3 other heads for branch "default"
 
 complex bisect test 1  # first bad rev is 9
 
--- a/tests/test-blackbox.t	Wed Feb 03 04:37:04 2016 +0000
+++ b/tests/test-blackbox.t	Tue Feb 02 14:49:02 2016 +0000
@@ -123,6 +123,7 @@
   $ hg update
   hooked
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  1 other heads for branch "default"
   $ hg blackbox -l 6
   1970/01/01 00:00:00 bob (*)> update (glob)
   1970/01/01 00:00:00 bob (*)> writing .hg/cache/tags2-visible with 0 tags (glob)
--- a/tests/test-bookmarks.t	Wed Feb 03 04:37:04 2016 +0000
+++ b/tests/test-bookmarks.t	Tue Feb 02 14:49:02 2016 +0000
@@ -573,6 +573,7 @@
   $ hg bookmark -r3 Y
   moving bookmark 'Y' forward from db815d6d32e6
   $ cp -r  ../cloned-bookmarks-update ../cloned-bookmarks-manual-update
+  $ cp -r  ../cloned-bookmarks-update ../cloned-bookmarks-manual-update-with-divergence
 
 (manual version)
 
@@ -617,6 +618,34 @@
   updating to active bookmark Y
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
 
+We warn about divergent during bare update to the active bookmark
+
+  $ hg -R ../cloned-bookmarks-manual-update-with-divergence update Y
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  (activating bookmark Y)
+  $ hg -R ../cloned-bookmarks-manual-update-with-divergence bookmarks -r X2 Y@1
+  $ hg -R ../cloned-bookmarks-manual-update-with-divergence bookmarks
+     X2                        1:925d80f479bb
+   * Y                         2:db815d6d32e6
+     Y@1                       1:925d80f479bb
+     Z                         2:db815d6d32e6
+     x  y                      2:db815d6d32e6
+  $ hg -R ../cloned-bookmarks-manual-update-with-divergence pull
+  pulling from $TESTTMP
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 2 changesets with 2 changes to 2 files (+1 heads)
+  updating bookmark Y
+  updating bookmark Z
+  (run 'hg heads' to see heads, 'hg merge' to merge)
+  $ hg -R ../cloned-bookmarks-manual-update-with-divergence update
+  updating to active bookmark Y
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  (activating bookmark Y)
+  1 other divergent bookmarks for "Y"
+
 test wrongly formated bookmark
 
   $ echo '' >> .hg/bookmarks
@@ -715,6 +744,7 @@
   $ hg up -C
   1 files updated, 0 files merged, 1 files removed, 0 files unresolved
   (leaving bookmark drop)
+  1 other heads for branch "default"
   $ hg sum
   parent: 2:db815d6d32e6 
    2
--- a/tests/test-conflict.t	Wed Feb 03 04:37:04 2016 +0000
+++ b/tests/test-conflict.t	Tue Feb 02 14:49:02 2016 +0000
@@ -232,6 +232,7 @@
 
   $ hg up -C
   2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  1 other heads for branch "default"
   $ printf "\n\nEnd of file\n" >> a
   $ hg ci -m "Add some stuff at the end"
   $ hg up -r 1
@@ -269,6 +270,7 @@
 
   $ hg up -C
   1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  1 other heads for branch "default"
   $ hg merge --tool :merge-local
   merging a
   2 files updated, 0 files merged, 0 files removed, 0 files unresolved
--- a/tests/test-largefiles-cache.t	Wed Feb 03 04:37:04 2016 +0000
+++ b/tests/test-largefiles-cache.t	Tue Feb 02 14:49:02 2016 +0000
@@ -202,6 +202,7 @@
   large: data corruption in $TESTTMP/src/.hg/largefiles/e2fb5f2139d086ded2cb600d5a91a196e76bf020 with hash 6a7bb2556144babe3899b25e5428123735bb1e27 (glob)
   0 largefiles updated, 0 removed
   0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  2 other heads for branch "default"
   $ hg st
   ! large
   ? z
--- a/tests/test-largefiles-update.t	Wed Feb 03 04:37:04 2016 +0000
+++ b/tests/test-largefiles-update.t	Tue Feb 02 14:49:02 2016 +0000
@@ -68,6 +68,7 @@
 
   $ hg up
   0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  1 other heads for branch "default"
   $ hg debugdirstate --large --nodate
   n 644          7 set                 large1
   n 644         13 set                 large2
@@ -82,6 +83,7 @@
   n 644         13 set                 large2
   $ hg up
   0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  1 other heads for branch "default"
   $ hg debugdirstate --large --nodate
   n 644          7 set                 large1
   n 644         13 set                 large2
--- a/tests/test-merge-changedelete.t	Wed Feb 03 04:37:04 2016 +0000
+++ b/tests/test-merge-changedelete.t	Tue Feb 02 14:49:02 2016 +0000
@@ -111,6 +111,7 @@
 
   $ hg co -C
   1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  1 other heads for branch "default"
 
   $ hg merge --config ui.interactive=true <<EOF
   > c
@@ -171,6 +172,7 @@
 
   $ hg co -C
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  1 other heads for branch "default"
 
   $ hg merge --config ui.interactive=true <<EOF
   > foo
@@ -243,6 +245,7 @@
 
   $ hg co -C
   2 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  1 other heads for branch "default"
 
   $ hg merge --config ui.interactive=true <<EOF
   > d
@@ -301,6 +304,7 @@
 
   $ hg co -C
   2 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  1 other heads for branch "default"
 
   $ hg merge --tool :local
   0 files updated, 3 files merged, 0 files removed, 0 files unresolved
@@ -345,6 +349,7 @@
 
   $ hg co -C
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  1 other heads for branch "default"
 
   $ hg merge --tool :other
   0 files updated, 2 files merged, 1 files removed, 0 files unresolved
@@ -389,6 +394,7 @@
 
   $ hg co -C
   2 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  1 other heads for branch "default"
 
   $ hg merge --tool :fail
   0 files updated, 0 files merged, 0 files removed, 3 files unresolved
@@ -436,6 +442,7 @@
 
   $ hg co -C
   1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  1 other heads for branch "default"
 
   $ hg merge --config ui.interactive=True --tool :prompt
   local changed file1 which remote deleted
@@ -491,6 +498,7 @@
 
   $ hg co -C
   1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  1 other heads for branch "default"
 
   $ hg merge --tool :prompt
   local changed file1 which remote deleted
@@ -544,6 +552,7 @@
 
   $ hg co -C
   1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  1 other heads for branch "default"
 
   $ hg merge --tool :merge3
   local changed file1 which remote deleted
--- a/tests/test-merge-default.t	Wed Feb 03 04:37:04 2016 +0000
+++ b/tests/test-merge-default.t	Tue Feb 02 14:49:02 2016 +0000
@@ -33,6 +33,7 @@
 
   $ hg up
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  2 other heads for branch "default"
 
 Should fail because > 2 heads:
 
--- a/tests/test-merge-types.t	Wed Feb 03 04:37:04 2016 +0000
+++ b/tests/test-merge-types.t	Tue Feb 02 14:49:02 2016 +0000
@@ -155,6 +155,7 @@
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ hg up
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  1 other heads for branch "default"
   $ hg st
   ? a.orig
 
@@ -175,6 +176,7 @@
   keep (l)ocal, take (o)ther, or leave (u)nresolved? u
   0 files updated, 0 files merged, 0 files removed, 1 files unresolved
   use 'hg resolve' to retry unresolved file merges
+  1 other heads for branch "default"
   [1]
   $ hg diff --git
   diff --git a/a b/a
--- a/tests/test-merge5.t	Wed Feb 03 04:37:04 2016 +0000
+++ b/tests/test-merge5.t	Tue Feb 02 14:49:02 2016 +0000
@@ -24,6 +24,7 @@
   $ hg revert b
   $ hg update -c
   0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  1 other heads for branch "default"
   $ mv a c
 
 Should abort:
--- a/tests/test-strip.t	Wed Feb 03 04:37:04 2016 +0000
+++ b/tests/test-strip.t	Tue Feb 02 14:49:02 2016 +0000
@@ -287,6 +287,7 @@
 
   $ hg up
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  1 other heads for branch "default"
   $ hg log -G
   @  changeset:   4:264128213d29
   |  tag:         tip
--- a/tests/test-subrepo.t	Wed Feb 03 04:37:04 2016 +0000
+++ b/tests/test-subrepo.t	Tue Feb 02 14:49:02 2016 +0000
@@ -664,6 +664,7 @@
   $ cd ../t
   $ hg up -C # discard our earlier merge
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  2 other heads for branch "default"
   $ echo blah > t/t
   $ hg ci -m13
   committing subrepository t
@@ -677,6 +678,7 @@
 
   $ hg up -C # discard changes
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  2 other heads for branch "default"
 
 pull
 
@@ -718,6 +720,7 @@
   adding file changes
   added 1 changesets with 1 changes to 1 files
   0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  2 other heads for branch "default"
   $ cat t/t
   blah
 
@@ -1185,6 +1188,7 @@
   ? s/c
   $ hg update -C
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  2 other heads for branch "default"
   $ hg status -S
   ? s/b
   ? s/c
--- a/tests/test-transplant.t	Wed Feb 03 04:37:04 2016 +0000
+++ b/tests/test-transplant.t	Tue Feb 02 14:49:02 2016 +0000
@@ -409,6 +409,7 @@
 
   $ hg up -C
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  1 other heads for branch "default"
   $ rm added
   $ hg transplant --continue
   abort: no transplant to continue
--- a/tests/test-update-branches.t	Wed Feb 03 04:37:04 2016 +0000
+++ b/tests/test-update-branches.t	Tue Feb 02 14:49:02 2016 +0000
@@ -167,6 +167,7 @@
 
   $ norevtest '-c clean same'   clean 2 -c
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  1 other heads for branch "default"
   parent=3
 
   $ revtest '-cC dirty linear'  dirty 1 2 -cC