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