[PATCH 2 of 2 V3] tag: abort if not at a branch head (issue2552)

Kevin Bullock kbullock+mercurial at ringworld.org
Tue Dec 14 01:00:32 CST 2010


# HG changeset patch
# User Kevin Bullock <kbullock at ringworld.org>
# Date 1291694650 21600
# Node ID 71ed64eceeabf151256055ae475e6ccfc1d1216b
# Parent  9ad83ab524cfd48bec0b8783182af9bf68ff5ee3
tag: abort if not at a branch head (issue2552)

Since it's usually only desirable to make tag commits on top of branch
heads, abort if the working dir parent is not a branch head. -f/--force
may be passed to commit at a non-head anyway.

Does not abort if working dir parent is a named branch head but not a
topological head.

diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -3665,16 +3665,23 @@
 
     Tags are used to name particular revisions of the repository and are
     very useful to compare different revisions, to go back to significant
-    earlier versions or to mark branch points as releases, etc.
+    earlier versions or to mark branch points as releases, etc. Changing
+    an existing tag is normally disallowed; use -f/--force to override.
 
     If no revision is given, the parent of the working directory is
     used, or tip if no revision is checked out.
 
     To facilitate version control, distribution, and merging of tags,
-    they are stored as a file named ".hgtags" which is managed
-    similarly to other project files and can be hand-edited if
-    necessary. The file '.hg/localtags' is used for local tags (not
-    shared among repositories).
+    they are stored as a file named ".hgtags" which is managed similarly
+    to other project files and can be hand-edited if necessary. This
+    also means that tagging creates a new commit. The file
+    ".hg/localtags" is used for local tags (not shared among
+    repositories).
+
+    Tag commits are usually made at the head of a branch. If the parent
+    of the working directory is not a branch head, :hg:`tag` aborts; use
+    -f/--force to force the tag commit to be based on a non-head
+    changeset.
 
     See :hg:`help dates` for a list of formats valid for -d/--date.
 
@@ -3717,8 +3724,13 @@
             if n in repo.tags():
                 raise util.Abort(_('tag \'%s\' already exists '
                                    '(use -f to force)') % n)
-    if not opts.get('local') and repo.dirstate.parents()[1] != nullid:
-        raise util.Abort(_('uncommitted merge'))
+    if not opts.get('local'):
+        p1, p2 = repo.dirstate.parents()
+        if p2 != nullid:
+            raise util.Abort(_('uncommitted merge'))
+        bheads = repo.branchheads()
+        if not opts.get('force') and bheads and p1 not in bheads:
+            raise util.Abort(_('not at a branch head (use -f to force)'))
     r = cmdutil.revsingle(repo, rev_).node()
 
     if not message:
@@ -4480,7 +4492,7 @@
          _('[OPTION]... [FILE]...')),
     "tag":
         (tag,
-         [('f', 'force', None, _('replace existing tag')),
+         [('f', 'force', None, _('force tag')),
           ('l', 'local', None, _('make the tag local')),
           ('r', 'rev', '',
            _('revision to tag'), _('REV')),
diff --git a/tests/test-1102.t b/tests/test-1102.t
--- a/tests/test-1102.t
+++ b/tests/test-1102.t
@@ -9,7 +9,7 @@
 
   $ hg co 1
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  $ hg tag -r0 t1
+  $ hg tag -f -r0 t1
   $ hg tags
   tip                                3:a49829c4fc11
   t1                                 0:f7b1eb17ad24
diff --git a/tests/test-tag.t b/tests/test-tag.t
--- a/tests/test-tag.t
+++ b/tests/test-tag.t
@@ -78,13 +78,20 @@
   $ cat .hg/localtags
   d4f0d2909abc9290e2773c08837d70c1794e3f5a bleah1
 
+tagging on a non-head revision
+
   $ hg update 0
   0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ hg tag -l localblah
   $ hg tag "foobar"
+  abort: not at a branch head (use -f to force)
+  [255]
+  $ hg tag -f "foobar"
   $ cat .hgtags
   acb14030fe0a21b60322c440ad2d20cf7685a376 foobar
   $ cat .hg/localtags
   d4f0d2909abc9290e2773c08837d70c1794e3f5a bleah1
+  acb14030fe0a21b60322c440ad2d20cf7685a376 localblah
 
   $ hg tag -l 'xx
   > newline'
@@ -102,6 +109,7 @@
   tag:         bleah
   tag:         bleah0
   tag:         foobar
+  tag:         localblah
   user:        test
   date:        Thu Jan 01 00:00:00 1970 +0000
   summary:     test
@@ -156,10 +164,10 @@
   > f = file('.hg/localtags', 'w'); f.write(last); f.close()
   > EOF
   $ cat .hg/localtags; echo
-  d4f0d2909abc9290e2773c08837d70c1794e3f5a bleah1
+  acb14030fe0a21b60322c440ad2d20cf7685a376 localblah
   $ hg tag -l localnewline
   $ cat .hg/localtags; echo
-  d4f0d2909abc9290e2773c08837d70c1794e3f5a bleah1
+  acb14030fe0a21b60322c440ad2d20cf7685a376 localblah
   c2899151f4e76890c602a2597a650a72666681bf localnewline
   
 
@@ -197,6 +205,7 @@
   custom tag message
   second line
 
+
 local tag with .hgtags modified
 
   $ hg tag hgtags-modified
@@ -209,7 +218,8 @@
   $ hg tag --local baz
   $ hg revert --no-backup .hgtags
 
-tagging with a uncommitted merge
+
+tagging on an uncommitted merge
 
   $ hg heads -q
   11:7d32ded1f932
@@ -243,7 +253,31 @@
   localnewline                       6:c2899151f4e7 local
   gawk                               2:336fccc858a4
   t3                                 1:d4f0d2909abc local
-  bleah1                             1:d4f0d2909abc local
+  localblah                          0:acb14030fe0a local
   foobar                             0:acb14030fe0a
   bleah0                             0:acb14030fe0a
   bleah                              0:acb14030fe0a
+  $ hg up -C .
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+
+tagging when at named-branch-head that's not a topo-head
+
+  $ hg up default
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg merge -t internal:local
+  0 files updated, 1 files merged, 0 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+  $ hg ci -m 'merge named branch'
+  $ hg up 11
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg tag new-topo-head
+
+
+tagging on null rev
+
+  $ hg up null
+  0 files updated, 0 files merged, 2 files removed, 0 files unresolved
+  $ hg tag nullrev
+  abort: not at a branch head (use -f to force)
+  [255]


More information about the Mercurial-devel mailing list