Rev 6094: (jelmer) Remove tags in `bzr uncommit`. (Jelmer Vernooij) in file:///home/pqm/archives/thelove/bzr/%2Btrunk/
Canonical.com Patch Queue Manager
pqm at pqm.ubuntu.com
Wed Aug 24 17:13:49 UTC 2011
At file:///home/pqm/archives/thelove/bzr/%2Btrunk/
------------------------------------------------------------
revno: 6094 [merge]
revision-id: pqm at pqm.ubuntu.com-20110824171334-rmma92i0w6umipi6
parent: pqm at pqm.ubuntu.com-20110823131455-25rwamcvm0il00ps
parent: jelmer at samba.org-20110824093118-ewjpuuc9onlkn3la
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Wed 2011-08-24 17:13:34 +0000
message:
(jelmer) Remove tags in `bzr uncommit`. (Jelmer Vernooij)
modified:
bzrlib/builtins.py builtins.py-20050830033751-fc01482b9ca23183
bzrlib/tests/blackbox/test_uncommit.py test_uncommit.py-20051027212835-84944b63adae51be
bzrlib/tests/test_uncommit.py test_uncommit.py-20080316104338-y3gxu67g5m2qih10-1
bzrlib/uncommit.py uncommit.py-20050626215513-5ec509fa425b305c
bzrlib/vf_repository.py vf_repository.py-20110502151858-yh9nnoxpokg86unk-1
doc/en/release-notes/bzr-2.5.txt bzr2.5.txt-20110708125756-587p0hpw7oke4h05-1
doc/en/user-guide/undoing_mistakes.txt undoing_mistakes.txt-20071121092300-8fyacngt1w98e5mp-1
=== modified file 'bzrlib/builtins.py'
--- a/bzrlib/builtins.py 2011-08-19 22:26:03 +0000
+++ b/bzrlib/builtins.py 2011-08-24 09:28:57 +0000
@@ -4979,6 +4979,8 @@
takes_options = ['verbose', 'revision',
Option('dry-run', help='Don\'t actually make changes.'),
Option('force', help='Say yes to all questions.'),
+ Option('keep-tags',
+ help='Keep tags that point to removed revisions.'),
Option('local',
help="Only remove the commits from the local branch"
" when in a checkout."
@@ -4988,9 +4990,8 @@
aliases = []
encoding_type = 'replace'
- def run(self, location=None,
- dry_run=False, verbose=False,
- revision=None, force=False, local=False):
+ def run(self, location=None, dry_run=False, verbose=False,
+ revision=None, force=False, local=False, keep_tags=False):
if location is None:
location = u'.'
control, relpath = bzrdir.BzrDir.open_containing(location)
@@ -5005,9 +5006,11 @@
self.add_cleanup(tree.lock_write().unlock)
else:
self.add_cleanup(b.lock_write().unlock)
- return self._run(b, tree, dry_run, verbose, revision, force, local=local)
+ return self._run(b, tree, dry_run, verbose, revision, force,
+ local, keep_tags)
- def _run(self, b, tree, dry_run, verbose, revision, force, local=False):
+ def _run(self, b, tree, dry_run, verbose, revision, force, local,
+ keep_tags):
from bzrlib.log import log_formatter, show_log
from bzrlib.uncommit import uncommit
@@ -5059,7 +5062,7 @@
mutter('Uncommitting from {%s} to {%s}',
last_rev_id, rev_id)
uncommit(b, tree=tree, dry_run=dry_run, verbose=verbose,
- revno=revno, local=local)
+ revno=revno, local=local, keep_tags=keep_tags)
self.outf.write('You can restore the old tip by running:\n'
' bzr pull . -r revid:%s\n' % last_rev_id)
=== modified file 'bzrlib/tests/blackbox/test_uncommit.py'
--- a/bzrlib/tests/blackbox/test_uncommit.py 2010-09-15 09:35:42 +0000
+++ b/bzrlib/tests/blackbox/test_uncommit.py 2011-08-22 10:44:29 +0000
@@ -18,9 +18,9 @@
import os
-from bzrlib import uncommit, workingtree
+from bzrlib import uncommit
from bzrlib.bzrdir import BzrDirMetaFormat1
-from bzrlib.errors import BzrError, BoundBranchOutOfDate
+from bzrlib.errors import BoundBranchOutOfDate
from bzrlib.tests import TestCaseWithTransport
from bzrlib.tests.script import (
run_script,
@@ -280,3 +280,17 @@
tree.commit(u'\u1234 message')
out, err = self.run_bzr('uncommit --force tree', encoding='ascii')
self.assertContainsRe(out, r'\? message')
+
+ def test_uncommit_removes_tags(self):
+ tree = self.make_branch_and_tree('tree')
+ revid = tree.commit('message')
+ tree.branch.tags.set_tag("atag", revid)
+ out, err = self.run_bzr('uncommit --force tree')
+ self.assertEquals({}, tree.branch.tags.get_tag_dict())
+
+ def test_uncommit_keep_tags(self):
+ tree = self.make_branch_and_tree('tree')
+ revid = tree.commit('message')
+ tree.branch.tags.set_tag("atag", revid)
+ out, err = self.run_bzr('uncommit --keep-tags --force tree')
+ self.assertEquals({"atag": revid}, tree.branch.tags.get_tag_dict())
=== modified file 'bzrlib/tests/test_uncommit.py'
--- a/bzrlib/tests/test_uncommit.py 2011-05-13 12:51:05 +0000
+++ b/bzrlib/tests/test_uncommit.py 2011-08-22 10:44:29 +0000
@@ -96,3 +96,30 @@
# If this tree isn't bound, local=True raises an exception
self.assertRaises(errors.LocalRequiresBoundBranch,
uncommit.uncommit, tree.branch, tree=tree, local=True)
+
+ def test_uncommit_remove_tags(self):
+ tree, history = self.make_linear_tree()
+ self.assertEqual(history[1], tree.last_revision())
+ self.assertEqual((2, history[1]), tree.branch.last_revision_info())
+ tree.branch.tags.set_tag(u"pointsatexisting", history[0])
+ tree.branch.tags.set_tag(u"pointsatremoved", history[1])
+ uncommit.uncommit(tree.branch, tree=tree)
+ self.assertEqual(history[0], tree.last_revision())
+ self.assertEqual((1, history[0]), tree.branch.last_revision_info())
+ self.assertEqual({
+ "pointsatexisting": history[0]
+ }, tree.branch.tags.get_tag_dict())
+
+ def test_uncommit_keep_tags(self):
+ tree, history = self.make_linear_tree()
+ self.assertEqual(history[1], tree.last_revision())
+ self.assertEqual((2, history[1]), tree.branch.last_revision_info())
+ tree.branch.tags.set_tag(u"pointsatexisting", history[0])
+ tree.branch.tags.set_tag(u"pointsatremoved", history[1])
+ uncommit.uncommit(tree.branch, tree=tree, keep_tags=True)
+ self.assertEqual(history[0], tree.last_revision())
+ self.assertEqual((1, history[0]), tree.branch.last_revision_info())
+ self.assertEqual({
+ "pointsatexisting": history[0],
+ "pointsatremoved": history[1],
+ }, tree.branch.tags.get_tag_dict())
=== modified file 'bzrlib/uncommit.py'
--- a/bzrlib/uncommit.py 2011-06-16 12:50:32 +0000
+++ b/bzrlib/uncommit.py 2011-08-22 10:53:21 +0000
@@ -26,8 +26,29 @@
from bzrlib.errors import BoundBranchOutOfDate
+def remove_tags(branch, graph, old_tip, new_tip):
+ """Remove tags on revisions between old_tip and new_tip.
+
+ :param branch: Branch to remove tags from
+ :param graph: Graph object for branch repository
+ :param old_tip: Old branch tip
+ :param new_tip: New branch tip
+ :return: Names of the removed tags
+ """
+ reverse_tags = branch.tags.get_reverse_tag_dict()
+ ancestors = graph.find_unique_ancestors(old_tip, [new_tip])
+ removed_tags = []
+ for revid, tags in reverse_tags.iteritems():
+ if not revid in ancestors:
+ continue
+ for tag in tags:
+ branch.tags.delete_tag(tag)
+ removed_tags.append(tag)
+ return removed_tags
+
+
def uncommit(branch, dry_run=False, verbose=False, revno=None, tree=None,
- local=False):
+ local=False, keep_tags=False):
"""Remove the last revision from the supplied branch.
:param dry_run: Don't actually change anything
@@ -36,6 +57,8 @@
:param local: If this branch is bound, only remove the revisions from the
local branch. If this branch is not bound, it is an error to pass
local=True.
+ :param keep_tags: Whether to keep tags pointing at the removed revisions
+ around.
"""
unlockable = []
try:
@@ -105,6 +128,8 @@
hook_new_tip = None
hook(hook_local, hook_master, old_revno, old_tip, new_revno,
hook_new_tip)
+ if branch.supports_tags() and not keep_tags:
+ remove_tags(branch, graph, old_tip, new_revision_id)
if tree is not None:
if not _mod_revision.is_null(new_revision_id):
parents = [new_revision_id]
=== modified file 'bzrlib/vf_repository.py'
--- a/bzrlib/vf_repository.py 2011-08-02 11:18:43 +0000
+++ b/bzrlib/vf_repository.py 2011-08-21 21:03:57 +0000
@@ -419,8 +419,8 @@
return None, False, None
# XXX: Friction: parent_candidates should return a list not a dict
# so that we don't have to walk the inventories again.
- parent_candiate_entries = ie.parent_candidates(parent_invs)
- head_set = self._heads(ie.file_id, parent_candiate_entries.keys())
+ parent_candidate_entries = ie.parent_candidates(parent_invs)
+ head_set = self._heads(ie.file_id, parent_candidate_entries.keys())
heads = []
for inv in parent_invs:
if inv.has_id(ie.file_id):
@@ -441,7 +441,7 @@
store = True
if not store:
# There is a single head, look it up for comparison
- parent_entry = parent_candiate_entries[heads[0]]
+ parent_entry = parent_candidate_entries[heads[0]]
# if the non-content specific data has changed, we'll be writing a
# node:
if (parent_entry.parent_id != ie.parent_id or
@@ -559,7 +559,7 @@
:param iter_changes: An iter_changes iterator with the changes to apply
to basis_revision_id. The iterator must not include any items with
a current kind of None - missing items must be either filtered out
- or errored-on beefore record_iter_changes sees the item.
+ or errored-on before record_iter_changes sees the item.
:param _entry_factory: Private method to bind entry_factory locally for
performance.
:return: A generator of (file_id, relpath, fs_hash) tuples for use with
=== modified file 'doc/en/release-notes/bzr-2.5.txt'
--- a/doc/en/release-notes/bzr-2.5.txt 2011-08-23 10:27:54 +0000
+++ b/doc/en/release-notes/bzr-2.5.txt 2011-08-24 17:13:34 +0000
@@ -100,6 +100,10 @@
Entering an empty commit message in the message editor still triggers
an error. (Jelmer Vernooij)
+* ``bzr uncommit`` will now remove tags that refer to removed revisions.
+ The ``--keep-tags`` option can be used to prevent this behaviour.
+ (Jelmer Vernooij, #605814)
+
* Locations printed by ``bzr upgrade`` are now formatted before display.
(Jelmer Vernooij)
=== modified file 'doc/en/user-guide/undoing_mistakes.txt'
--- a/doc/en/user-guide/undoing_mistakes.txt 2009-11-23 15:29:24 +0000
+++ b/doc/en/user-guide/undoing_mistakes.txt 2011-08-24 09:31:18 +0000
@@ -93,6 +93,9 @@
one or more files. Some users like to alias ``commit`` to ``commit --strict``
so that commits fail if unknown files are found in the tree.
+Tags for uncommitted revisions are removed from the branch unless
+``--keep-tags`` was specified.
+
Note: While the ``merge`` command is not introduced until the next
chapter, it is worth noting now that ``uncommit`` restores any pending
merges. (Running ``bzr status`` after ``uncommit`` will show these.)
More information about the bazaar-commits
mailing list