Rev 2241: Add tag --delete command and implementation in http://sourcefrog.net/bzr/tags

Martin Pool mbp at sourcefrog.net
Wed Feb 21 04:08:28 GMT 2007


At http://sourcefrog.net/bzr/tags

------------------------------------------------------------
revno: 2241
revision-id: mbp at sourcefrog.net-20070221040827-udbcbv0raghknyl5
parent: mbp at sourcefrog.net-20070220075000-2hz26ddu1hm28jrl
committer: Martin Pool <mbp at sourcefrog.net>
branch nick: tags
timestamp: Wed 2007-02-21 15:08:27 +1100
message:
  Add tag --delete command and implementation
modified:
  BRANCH.TODO                    BRANCH.TODO-20060103052123-79ac4969351c03a9
  bzrlib/builtins.py             builtins.py-20050830033751-fc01482b9ca23183
  bzrlib/errors.py               errors.py-20050309040759-20512168c4e14fbd
  bzrlib/tag.py                  tag.py-20070212110532-91cw79inah2cfozx-1
  bzrlib/tests/blackbox/test_tags.py test_tags.py-20070116132048-5h4qak2cm22jlb9e-1
  bzrlib/tests/branch_implementations/test_tags.py test_tags.py-20070212110545-w2s799hm2jlbsmg5-1
=== modified file 'BRANCH.TODO'
--- a/BRANCH.TODO	2007-02-20 07:50:00 +0000
+++ b/BRANCH.TODO	2007-02-21 04:08:27 +0000
@@ -44,21 +44,17 @@
  - store tags in bencode format - or nul-delimited
  - test use of unicode tags
  - rename TagStore and change to branch.tags
+ - delete tags, and mark as deleted
 
 Plan
 ----
 
- - delete tags, and mark as deleted
- - record who set tags, when, why
- - tests that -d accepts urls, etc
  - copy only selected tags
  - if tags conflict when copying
    - return them and give a warning
    - option to override this and copy anyhow
  - give a nice message when trying to copy tags if it can't be done
- - when fetching revisions, also copy tags
-   - give a warning if the tags differ, and don't override them
-   - allow this to be forced
+ - record who set tags, when, why
  - raise an exception if the tag name is unreasonable
  - refuse to add tags if the tag is already present, but allow it to 
    be forced

=== modified file 'bzrlib/builtins.py'
--- a/bzrlib/builtins.py	2007-02-20 07:50:00 +0000
+++ b/bzrlib/builtins.py	2007-02-21 04:08:27 +0000
@@ -3177,21 +3177,30 @@
             short_name='d',
             type=unicode,
             ),
+        Option('delete',
+            help='Delete this tag rather than placing it',
+            ),
         'revision',
         ]
 
-    def run(self, tag_name, directory='.', revision=None):
+    def run(self, tag_name, directory='.',
+            revision=None,
+            delete=None):
         branch, relpath = Branch.open_containing(directory)
-        if revision:
-            if len(revision) != 1:
-                raise errors.BzrCommandError(
-                    "Tags can only be placed on a single revision, "
-                    "not on a range")
-            revision_id = revision[0].in_history(branch).rev_id
+        if delete:
+            branch.tags.delete_tag(tag_name)
+            self.outf.write('deleted tag %s' % tag_name)
         else:
-            revision_id = branch.last_revision()
-        branch.tags.set_tag(tag_name, revision_id)
-        self.outf.write('created tag %s' % tag_name)
+            if revision:
+                if len(revision) != 1:
+                    raise errors.BzrCommandError(
+                        "Tags can only be placed on a single revision, "
+                        "not on a range")
+                revision_id = revision[0].in_history(branch).rev_id
+            else:
+                revision_id = branch.last_revision()
+            branch.tags.set_tag(tag_name, revision_id)
+            self.outf.write('created tag %s' % tag_name)
 
 
 # command-line interpretation helper for merge-related commands

=== modified file 'bzrlib/errors.py'
--- a/bzrlib/errors.py	2007-02-15 01:23:29 +0000
+++ b/bzrlib/errors.py	2007-02-21 04:08:27 +0000
@@ -1758,7 +1758,7 @@
 
 class TagsNotSupported(BzrError):
 
-    _fmt = "Tags not supported by repository %(repository)s"
+    _fmt = "Tags not supported by %(branch)s; you may be able to use bzr upgrade."
 
-    def __init__(self, repository):
-        self.repository = repository
+    def __init__(self, branch):
+        self.repository = branch

=== modified file 'bzrlib/tag.py'
--- a/bzrlib/tag.py	2007-02-20 07:50:00 +0000
+++ b/bzrlib/tag.py	2007-02-21 04:08:27 +0000
@@ -53,6 +53,7 @@
     get_tag_dict = _not_supported
     _set_tag_dict = _not_supported
     lookup_tag = _not_supported
+    delete_tag = _not_supported
 
 
 class BasicTags(_Tags):
@@ -67,8 +68,6 @@
 
         Behaviour if the tag is already present is not defined (yet).
         """
-        if isinstance(tag_name, unicode):
-            tag_name = tag_name.encode('utf-8')
         # all done with a write lock held, so this looks atomic
         self.branch.lock_write()
         try:
@@ -80,8 +79,6 @@
 
     def lookup_tag(self, tag_name):
         """Return the referent string of a tag"""
-        if isinstance(tag_name, unicode):
-            tag_name = tag_name.encode('utf-8')
         td = self.get_tag_dict()
         try:
             return td[tag_name]
@@ -96,6 +93,20 @@
         finally:
             self.branch.unlock()
 
+    def delete_tag(self, tag_name):
+        """Delete a tag definition.
+        """
+        self.branch.lock_write()
+        try:
+            d = self.get_tag_dict()
+            try:
+                del d[tag_name]
+            except KeyError:
+                raise errors.NoSuchTag(tag_name)
+            self._set_tag_dict(d)
+        finally:
+            self.branch.unlock()
+
     def _set_tag_dict(self, new_dict):
         """Replace all tag definitions
 
@@ -109,7 +120,9 @@
             self.branch.unlock()
 
     def _serialize_tag_dict(self, tag_dict):
-        return bencode.bencode(tag_dict)
+        td = dict((k.encode('utf-8'), v)
+                for k,v in tag_dict.items())
+        return bencode.bencode(td)
 
     def _deserialize_tag_dict(self, tag_content):
         """Convert the tag file into a dictionary of tags"""
@@ -118,6 +131,10 @@
         if tag_content == '':
             return {}
         try:
-            return bencode.bdecode(tag_content)
-        except ValueError:
-            raise ValueError("failed to deserialize tag dictionary %r" % tag_content)
+            r = {}
+            for k, v in bencode.bdecode(tag_content).items():
+                r[k.decode('utf-8')] = v
+            return r
+        except ValueError, e:
+            raise ValueError("failed to deserialize tag dictionary %r: %s"
+                    % (tag_content, e))

=== modified file 'bzrlib/tests/blackbox/test_tags.py'
--- a/bzrlib/tests/blackbox/test_tags.py	2007-02-20 07:50:00 +0000
+++ b/bzrlib/tests/blackbox/test_tags.py	2007-02-21 04:08:27 +0000
@@ -64,6 +64,8 @@
         # can also create tags using -r
         self.run_bzr('tag', '-d', 'branch', 'tag2', '-r1')
         self.assertEquals(t.branch.tags.lookup_tag('tag2'), 'first-revid')
+        # can also delete an existing tag
+        self.run_bzr('tag', '--delete', '-d', 'branch', 'tag2')
 
     def test_branch_push_pull_merge_copies_tags(self):
         t = self.make_branch_and_tree('branch1')

=== modified file 'bzrlib/tests/branch_implementations/test_tags.py'
--- a/bzrlib/tests/branch_implementations/test_tags.py	2007-02-20 07:50:00 +0000
+++ b/bzrlib/tests/branch_implementations/test_tags.py	2007-02-21 04:08:27 +0000
@@ -94,6 +94,25 @@
         b1.tags.set_tag(tag_name, revid)
         self.assertEquals(b1.tags.lookup_tag(tag_name), revid)
 
+    def test_delete_tag(self):
+        b = self.make_branch('b')
+        tag_name = u'\N{GREEK SMALL LETTER ALPHA}'
+        revid = ('revid' + tag_name).encode('utf-8')
+        b.tags.set_tag(tag_name, revid)
+        # now try to delete it
+        b.tags.delete_tag(tag_name)
+        # now you can't look it up
+        self.assertRaises(errors.NoSuchTag,
+            b.tags.lookup_tag, tag_name)
+        # and it's not in the dictionary
+        self.assertEquals(b.tags.get_tag_dict(), {})
+        # and you can't remove it a second time
+        self.assertRaises(errors.NoSuchTag,
+            b.tags.delete_tag, tag_name)
+        # or remove a tag that never existed
+        self.assertRaises(errors.NoSuchTag,
+            b.tags.delete_tag, tag_name + '2')
+
 
 class TestUnsupportedTags(TestCaseWithBranch):
     """Formats that don't support tags should give reasonable errors."""
@@ -119,5 +138,5 @@
             b.tags.lookup_tag, 'foo')
         self.assertRaises(errors.TagsNotSupported,
             b.tags.set_tag, 'foo', 'bar')
-
-
+        self.assertRaises(errors.TagsNotSupported,
+            b.tags.delete_tag, 'foo')




More information about the bazaar-commits mailing list