Patchwork [4,of,4] bookmark: warn about using revsets as bookmark/branch/tag names [RFC] (BC)

login
register
mail settings
Submitter timeless@mozdev.org
Date Jan. 14, 2016, 6:26 p.m.
Message ID <f30f44074df03066d01a.1452795972@waste.org>
Download mbox | patch
Permalink /patch/12761/
State Changes Requested
Delegated to: Yuya Nishihara
Headers show

Comments

timeless@mozdev.org - Jan. 14, 2016, 6:26 p.m.
# HG changeset patch
# User timeless <timeless@mozdev.org>
# Date 1451260878 0
#      Mon Dec 28 00:01:18 2015 +0000
# Node ID f30f44074df03066d01a97653360fc6a521e388e
# Parent  e2bca0913d73fb31fb6c5a9249ea984b80a7d71c
bookmark: warn about using revsets as bookmark/branch/tag names [RFC] (BC)

Eventually this could be switched to be aware of force and
default to abort. Or we could just do it straight away.
If we did it straight away, it'd be a behavior change...

Patch

diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -1103,6 +1103,7 @@ 
                 checkconflict(repo, mark, cur, force)
                 if mark not in repo._bookmarks:
                     scmutil.checknewlabel(repo, mark, 'bookmark')
+                    scmutil.checklabelisrevset(repo, mark, 'bookmark')
                 marks[mark] = marks[rename]
                 if repo._activebookmark == rename and not inactive:
                     bookmarks.activate(repo, mark)
@@ -1123,6 +1124,7 @@ 
                     checkconflict(repo, mark, cur, force, tgt)
                     if not mark in repo._bookmarks:
                         scmutil.checknewlabel(repo, mark, 'bookmark')
+                        scmutil.checklabelisrevset(repo, mark, 'bookmark')
                     marks[mark] = tgt
                 if not inactive and cur == marks[newact] and not rev:
                     bookmarks.activate(repo, newact)
@@ -1221,6 +1223,7 @@ 
                             hint=_("use 'hg update' to switch to it"))
             else:
                 scmutil.checknewlabel(repo, label, 'branch')
+                scmutil.checklabelisrevset(repo, label, 'branch')
             repo.dirstate.setbranch(label)
             ui.status(_('marked working directory as branch %s\n') % label)
 
@@ -6753,6 +6756,7 @@ 
                 if n in repo.tags():
                     raise error.Abort(_("tag '%s' already exists "
                                        "(use -f to force)") % n)
+                scmutil.checklabelisrevset(repo, n, 'tag')
         if not opts.get('local'):
             p1, p2 = repo.dirstate.parents()
             if p2 != nullid:
diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py
--- a/mercurial/scmutil.py
+++ b/mercurial/scmutil.py
@@ -150,6 +150,40 @@ 
     except ValueError:
         pass
 
+def checklabelisrevset(repo, lbl, kind):
+    # Do not use the "kind" parameter in ui output.
+    # It makes strings difficult to translate.
+    if re.search("^[a-f0-9]{1,16}$", lbl):
+        # technically, a label named `a` does interfere with a changeset
+        # a...,
+        # and a label named 10f interfers with a changeset named
+        # 10f...,
+        # but, we'll let that slide for now.
+        return
+    try:
+        m = revset.matchany(repo.ui, [lbl], repo)
+        items = []
+        for rev in m(repo):
+            items.append(rev)
+            if len(items) > 1:
+                break
+        if items:
+            if len(items) > 1:
+                items = _("%s, %s, ...") % (items[0], items[1])
+            else:
+                items = items[0]
+            repo.ui.warn(_(
+                "warning: name %s conflicts with a revset matching %s\n") %
+                (lbl, items))
+    except error.Abort:
+        pass
+    except error.LookupError:
+        pass
+    except error.ParseError:
+        pass
+    except error.RepoLookupError:
+        pass
+
 def checkfilename(f):
     '''Check that the filename f is an acceptable filename for a tracked file'''
     if '\r' in f or '\n' in f:
diff --git a/tests/test-1993.t b/tests/test-1993.t
--- a/tests/test-1993.t
+++ b/tests/test-1993.t
@@ -7,6 +7,7 @@ 
   $ hg ci -Am1
   adding b
   $ hg tag -r0 default
+  warning: name default conflicts with a revset matching 1
   warning: tag default conflicts with existing branch name
   $ hg log
   changeset:   2:30a83d1e4a1e
diff --git a/tests/test-bookmarks.t b/tests/test-bookmarks.t
--- a/tests/test-bookmarks.t
+++ b/tests/test-bookmarks.t
@@ -487,6 +487,7 @@ 
 test clone with a bookmark named "default" (issue3677)
 
   $ hg bookmark -r 1 -f -i default
+  warning: name default conflicts with a revset matching 2
   $ hg clone . cloned-bookmark-default
   updating to branch default
   2 files updated, 0 files merged, 0 files removed, 0 files unresolved
@@ -781,3 +782,8 @@ 
      foo@2                     2:db815d6d32e6
      four                      3:9ba5f110a0b3
      should-end-on-two         2:db815d6d32e6
+
+test collision with revset
+
+  $ hg bookmark something .^
+  warning: name .^ conflicts with a revset matching 2
diff --git a/tests/test-branch-tag-confict.t b/tests/test-branch-tag-confict.t
--- a/tests/test-branch-tag-confict.t
+++ b/tests/test-branch-tag-confict.t
@@ -13,6 +13,7 @@ 
 Create a branch with the same name as the tag.
 
   $ hg branch branchortag
+  warning: name branchortag conflicts with a revset matching 0
   marked working directory as branch branchortag
   (branches are permanent and global, did you want a bookmark?)
   $ hg ci -m 'Create a branch with the same name as a tag.'
diff --git a/tests/test-commandserver.t b/tests/test-commandserver.t
--- a/tests/test-commandserver.t
+++ b/tests/test-commandserver.t
@@ -340,6 +340,7 @@ 
   ...     os.system('hg branch default')
   *** runcommand branch
   default
+  warning: name foo conflicts with a revset matching 0
   marked working directory as branch foo
   (branches are permanent and global, did you want a bookmark?)
   *** runcommand branch
diff --git a/tests/test-encoding-align.t b/tests/test-encoding-align.t
--- a/tests/test-encoding-align.t
+++ b/tests/test-encoding-align.t
@@ -117,14 +117,17 @@ 
   (branches are permanent and global, did you want a bookmark?)
   $ hg tag $S
   $ hg book -f $S
+  warning: name \xe7\x9f\xad\xe5\x90\x8d conflicts with a revset matching 2 (esc)
   $ hg branch $M
   marked working directory as branch MIDDLE_
   $ hg tag $M
   $ hg book -f $M
+  warning: name MIDDLE_ conflicts with a revset matching 3
   $ hg branch $L
   marked working directory as branch \xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d (esc)
   $ hg tag $L
   $ hg book -f $L
+  warning: name \xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d conflicts with a revset matching 4 (esc)
 
 check alignment of branches
 
diff --git a/tests/test-encoding.t b/tests/test-encoding.t
--- a/tests/test-encoding.t
+++ b/tests/test-encoding.t
@@ -41,6 +41,7 @@ 
   $ HGENCODING=utf-8 hg ci -l utf-8
   $ HGENCODING=latin-1 hg tag `cat latin-1-tag`
   $ HGENCODING=latin-1 hg branch `cat latin-1-tag`
+  warning: name \xe9 conflicts with a revset matching 3 (esc)
   marked working directory as branch \xe9 (esc)
   (branches are permanent and global, did you want a bookmark?)
   $ HGENCODING=latin-1 hg ci -m 'latin1 branch'
diff --git a/tests/test-tag.t b/tests/test-tag.t
--- a/tests/test-tag.t
+++ b/tests/test-tag.t
@@ -233,6 +233,7 @@ 
   (branches are permanent and global, did you want a bookmark?)
   $ hg ci -m"discouraged"
   $ hg tag tag-and-branch-same-name
+  warning: name tag-and-branch-same-name conflicts with a revset matching 11
   warning: tag tag-and-branch-same-name conflicts with existing branch name
 
 test custom commit messages