Rev 4599: [cherrypick revno 4650 from bzr.dev] Fix shelve on windows. (Robert Collins, #305006) in file:///net/bigmamac.local/Volumes/home/vila/src/bzr/integration/1.18/
Vincent Ladeuil
v.ladeuil+lp at free.fr
Thu Aug 27 16:21:59 BST 2009
At file:///net/bigmamac.local/Volumes/home/vila/src/bzr/integration/1.18/
------------------------------------------------------------
revno: 4599 [merge]
revision-id: v.ladeuil+lp at free.fr-20090827152157-r8rro9gusnqgopqh
parent: pqm at pqm.ubuntu.com-20090826065732-vfdtucqt5og7kwr1
parent: bialix at ukr.net-20090827073031-dgm9i4kx8610p8tq
committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
branch nick: 1.18
timestamp: Thu 2009-08-27 17:21:57 +0200
message:
[cherrypick revno 4650 from bzr.dev] Fix shelve on windows. (Robert Collins, #305006)
modified:
NEWS NEWS-20050323055033-4e00b5db738777ff
bzrlib/builtins.py builtins.py-20050830033751-fc01482b9ca23183
bzrlib/merge.py merge.py-20050513021216-953b65a438527106
bzrlib/shelf.py prepare_shelf.py-20081005181341-n74qe6gu1e65ad4v-1
bzrlib/shelf_ui.py shelver.py-20081005210102-33worgzwrtdw0yrm-1
bzrlib/tests/per_workingtree/test_executable.py test_executable.py-20060628162557-tr7h57kl80l3ma8i-1
bzrlib/tests/per_workingtree/test_set_root_id.py test_set_root_id.py-20061004073850-0r1c7qikmnkb8m9k-1
bzrlib/tests/test_merge.py testmerge.py-20050905070950-c1b5aa49ff911024
bzrlib/tests/test_shelf.py test_prepare_shelf.p-20081005181341-n74qe6gu1e65ad4v-2
bzrlib/tests/test_shelf_ui.py test_shelf_ui.py-20081027155203-wtcuazg85wp9u4fv-1
-------------- next part --------------
=== modified file 'NEWS'
--- a/NEWS 2009-08-25 05:32:07 +0000
+++ b/NEWS 2009-08-27 07:30:31 +0000
@@ -17,9 +17,22 @@
conversion will commit too many copies a file.
(Martin Pool, #415508)
+Improvements
+************
+
+* ``bzr push`` locally on windows will no longer give a locking error with
+ dirstate based formats. (Robert Collins)
+
+* ``bzr shelve`` and ``bzr unshelve`` now work on windows.
+ (Robert Collins, #305006)
+
API Changes
***********
+* ``bzrlib.shelf_ui`` has had the ``from_args`` convenience methods of its
+ classes changed to manage lock lifetime of the trees they open in a way
+ consistent with reader-exclusive locks. (Robert Collins, #305006)
+
* ``Tree.path_content_summary`` may return a size of None, when called on
a tree with content filtering where the size of the canonical form
cannot be cheaply determined. (Martin Pool)
=== modified file 'bzrlib/builtins.py'
--- a/bzrlib/builtins.py 2009-07-27 06:22:57 +0000
+++ b/bzrlib/builtins.py 2009-08-27 07:30:31 +0000
@@ -120,6 +120,15 @@
def _get_one_revision_tree(command_name, revisions, branch=None, tree=None):
+ """Get a revision tree. Not suitable for commands that change the tree.
+
+ Specifically, the basis tree in dirstate trees is coupled to the dirstate
+ and doing a commit/uncommit/pull will at best fail due to changing the
+ basis revision data.
+
+ If tree is passed in, it should be already locked, for lifetime management
+ of the trees internal cached state.
+ """
if branch is None:
branch = tree.branch
if revisions is None:
@@ -5627,8 +5636,12 @@
if writer is None:
writer = bzrlib.option.diff_writer_registry.get()
try:
- Shelver.from_args(writer(sys.stdout), revision, all, file_list,
- message, destroy=destroy).run()
+ shelver = Shelver.from_args(writer(sys.stdout), revision, all,
+ file_list, message, destroy=destroy)
+ try:
+ shelver.run()
+ finally:
+ shelver.work_tree.unlock()
except errors.UserAbort:
return 0
@@ -5673,7 +5686,11 @@
def run(self, shelf_id=None, action='apply'):
from bzrlib.shelf_ui import Unshelver
- Unshelver.from_args(shelf_id, action).run()
+ unshelver = Unshelver.from_args(shelf_id, action)
+ try:
+ unshelver.run()
+ finally:
+ unshelver.tree.unlock()
class cmd_clean_tree(Command):
=== modified file 'bzrlib/merge.py'
--- a/bzrlib/merge.py 2009-07-02 13:07:14 +0000
+++ b/bzrlib/merge.py 2009-08-27 07:30:31 +0000
@@ -64,8 +64,12 @@
def transform_tree(from_tree, to_tree, interesting_ids=None):
- merge_inner(from_tree.branch, to_tree, from_tree, ignore_zero=True,
- interesting_ids=interesting_ids, this_tree=from_tree)
+ from_tree.lock_tree_write()
+ try:
+ merge_inner(from_tree.branch, to_tree, from_tree, ignore_zero=True,
+ interesting_ids=interesting_ids, this_tree=from_tree)
+ finally:
+ from_tree.unlock()
class Merger(object):
@@ -102,6 +106,17 @@
self._is_criss_cross = None
self._lca_trees = None
+ def cache_trees_with_revision_ids(self, trees):
+ """Cache any tree in trees if it has a revision_id."""
+ for maybe_tree in trees:
+ if maybe_tree is None:
+ continue
+ try:
+ rev_id = maybe_tree.get_revision_id()
+ except AttributeError:
+ continue
+ self._cached_trees[rev_id] = maybe_tree
+
@property
def revision_graph(self):
if self._revision_graph is None:
@@ -1516,6 +1531,7 @@
get_revision_id = getattr(base_tree, 'get_revision_id', None)
if get_revision_id is None:
get_revision_id = base_tree.last_revision
+ merger.cache_trees_with_revision_ids([other_tree, base_tree, this_tree])
merger.set_base_revision(get_revision_id(), this_branch)
return merger.do_merge()
=== modified file 'bzrlib/shelf.py'
--- a/bzrlib/shelf.py 2009-07-13 17:35:09 +0000
+++ b/bzrlib/shelf.py 2009-08-27 07:30:31 +0000
@@ -37,8 +37,10 @@
def __init__(self, work_tree, target_tree, file_list=None):
"""Constructor.
- :param work_tree: The working tree to apply changes to
+ :param work_tree: The working tree to apply changes to. This is not
+ required to be locked - a tree_write lock will be taken out.
:param target_tree: The tree to make the working tree more similar to.
+ This is not required to be locked - a read_lock will be taken out.
:param file_list: The files to make more similar to the target.
"""
self.work_tree = work_tree
=== modified file 'bzrlib/shelf_ui.py'
--- a/bzrlib/shelf_ui.py 2009-07-13 13:00:27 +0000
+++ b/bzrlib/shelf_ui.py 2009-08-27 07:30:31 +0000
@@ -149,6 +149,9 @@
message=None, directory='.', destroy=False):
"""Create a shelver from commandline arguments.
+ The returned shelver wil have a work_tree that is locked and should
+ be unlocked.
+
:param revision: RevisionSpec of the revision to compare to.
:param all: If True, shelve all changes without prompting.
:param file_list: If supplied, only files in this list may be shelved.
@@ -158,9 +161,16 @@
changes.
"""
tree, path = workingtree.WorkingTree.open_containing(directory)
- target_tree = builtins._get_one_revision_tree('shelf2', revision,
- tree.branch, tree)
- files = builtins.safe_relpath_files(tree, file_list)
+ # Ensure that tree is locked for the lifetime of target_tree, as
+ # target tree may be reading from the same dirstate.
+ tree.lock_tree_write()
+ try:
+ target_tree = builtins._get_one_revision_tree('shelf2', revision,
+ tree.branch, tree)
+ files = builtins.safe_relpath_files(tree, file_list)
+ except:
+ tree.unlock()
+ raise
return klass(tree, target_tree, diff_writer, all, all, files, message,
destroy)
@@ -313,32 +323,40 @@
def from_args(klass, shelf_id=None, action='apply', directory='.'):
"""Create an unshelver from commandline arguments.
+ The returned shelver wil have a tree that is locked and should
+ be unlocked.
+
:param shelf_id: Integer id of the shelf, as a string.
:param action: action to perform. May be 'apply', 'dry-run',
'delete'.
:param directory: The directory to unshelve changes into.
"""
tree, path = workingtree.WorkingTree.open_containing(directory)
- manager = tree.get_shelf_manager()
- if shelf_id is not None:
- try:
- shelf_id = int(shelf_id)
- except ValueError:
- raise errors.InvalidShelfId(shelf_id)
- else:
- shelf_id = manager.last_shelf()
- if shelf_id is None:
- raise errors.BzrCommandError('No changes are shelved.')
- trace.note('Unshelving changes with id "%d".' % shelf_id)
- apply_changes = True
- delete_shelf = True
- read_shelf = True
- if action == 'dry-run':
- apply_changes = False
- delete_shelf = False
- if action == 'delete-only':
- apply_changes = False
- read_shelf = False
+ tree.lock_tree_write()
+ try:
+ manager = tree.get_shelf_manager()
+ if shelf_id is not None:
+ try:
+ shelf_id = int(shelf_id)
+ except ValueError:
+ raise errors.InvalidShelfId(shelf_id)
+ else:
+ shelf_id = manager.last_shelf()
+ if shelf_id is None:
+ raise errors.BzrCommandError('No changes are shelved.')
+ trace.note('Unshelving changes with id "%d".' % shelf_id)
+ apply_changes = True
+ delete_shelf = True
+ read_shelf = True
+ if action == 'dry-run':
+ apply_changes = False
+ delete_shelf = False
+ if action == 'delete-only':
+ apply_changes = False
+ read_shelf = False
+ except:
+ tree.unlock()
+ raise
return klass(tree, manager, shelf_id, apply_changes, delete_shelf,
read_shelf)
@@ -364,7 +382,7 @@
def run(self):
"""Perform the unshelving operation."""
- self.tree.lock_write()
+ self.tree.lock_tree_write()
cleanups = [self.tree.unlock]
try:
if self.read_shelf:
=== modified file 'bzrlib/tests/per_workingtree/test_executable.py'
--- a/bzrlib/tests/per_workingtree/test_executable.py 2009-07-10 07:14:02 +0000
+++ b/bzrlib/tests/per_workingtree/test_executable.py 2009-08-27 07:25:22 +0000
@@ -30,7 +30,6 @@
def setUp(self):
super(TestExecutable, self).setUp()
-
self.a_id = "a-20051208024829-849e76f7968d7a86"
self.b_id = "b-20051208024829-849e76f7968d7a86"
wt = self.make_branch_and_tree('b1')
=== modified file 'bzrlib/tests/per_workingtree/test_set_root_id.py'
--- a/bzrlib/tests/per_workingtree/test_set_root_id.py 2009-07-10 07:14:02 +0000
+++ b/bzrlib/tests/per_workingtree/test_set_root_id.py 2009-08-27 07:25:22 +0000
@@ -23,6 +23,8 @@
class TestSetRootId(TestCaseWithWorkingTree):
def test_set_and_read_unicode(self):
+ # This test tests that setting the root doesn't flush, so it
+ # deliberately tests concurrent access that isn't possible on windows.
tree = self.make_branch_and_tree('a-tree')
# setting the root id allows it to be read via get_root_id.
root_id = u'\xe5n-id'.encode('utf8')
=== modified file 'bzrlib/tests/test_merge.py'
--- a/bzrlib/tests/test_merge.py 2009-04-29 17:02:36 +0000
+++ b/bzrlib/tests/test_merge.py 2009-08-27 07:30:31 +0000
@@ -218,13 +218,15 @@
tree_a.add('file')
tree_a.commit('commit base')
# basis_tree() is only guaranteed to be valid as long as it is actually
- # the basis tree. This mutates the tree after grabbing basis, so go to
- # the repository.
+ # the basis tree. This test commits to the tree after grabbing basis,
+ # so we go to the repository.
base_tree = tree_a.branch.repository.revision_tree(tree_a.last_revision())
tree_b = tree_a.bzrdir.sprout('tree_b').open_workingtree()
self.build_tree_contents([('tree_a/file', 'content_2')])
tree_a.commit('commit other')
other_tree = tree_a.basis_tree()
+ # 'file' is now missing but isn't altered in any commit in b so no
+ # change should be applied.
os.unlink('tree_b/file')
merge_inner(tree_b.branch, other_tree, base_tree, this_tree=tree_b)
@@ -1232,6 +1234,27 @@
class TestMergerInMemory(TestMergerBase):
+ def test_cache_trees_with_revision_ids_None(self):
+ merger = self.make_Merger(self.setup_simple_graph(), 'C-id')
+ original_cache = dict(merger._cached_trees)
+ merger.cache_trees_with_revision_ids([None])
+ self.assertEqual(original_cache, merger._cached_trees)
+
+ def test_cache_trees_with_revision_ids_no_revision_id(self):
+ merger = self.make_Merger(self.setup_simple_graph(), 'C-id')
+ original_cache = dict(merger._cached_trees)
+ tree = self.make_branch_and_memory_tree('tree')
+ merger.cache_trees_with_revision_ids([tree])
+ self.assertEqual(original_cache, merger._cached_trees)
+
+ def test_cache_trees_with_revision_ids_having_revision_id(self):
+ merger = self.make_Merger(self.setup_simple_graph(), 'C-id')
+ original_cache = dict(merger._cached_trees)
+ tree = merger.this_branch.repository.revision_tree('B-id')
+ original_cache['B-id'] = tree
+ merger.cache_trees_with_revision_ids([tree])
+ self.assertEqual(original_cache, merger._cached_trees)
+
def test_find_base(self):
merger = self.make_Merger(self.setup_simple_graph(), 'C-id')
self.assertEqual('A-id', merger.base_rev_id)
=== modified file 'bzrlib/tests/test_shelf.py'
--- a/bzrlib/tests/test_shelf.py 2009-07-13 17:35:09 +0000
+++ b/bzrlib/tests/test_shelf.py 2009-08-27 07:30:31 +0000
@@ -46,6 +46,8 @@
tree.add(['foo'], ['foo-id'])
tree.commit('foo')
tree.rename_one('foo', 'bar')
+ tree.lock_tree_write()
+ self.addCleanup(tree.unlock)
creator = shelf.ShelfCreator(tree, tree.basis_tree())
self.addCleanup(creator.finalize)
self.assertEqual([('rename', 'foo-id', 'foo', 'bar')],
@@ -76,6 +78,8 @@
tree.add(['foo', 'bar', 'foo/baz'], ['foo-id', 'bar-id', 'baz-id'])
tree.commit('foo')
tree.rename_one('foo/baz', 'bar/baz')
+ tree.lock_tree_write()
+ self.addCleanup(tree.unlock)
creator = shelf.ShelfCreator(tree, tree.basis_tree())
self.addCleanup(creator.finalize)
self.assertEqual([('rename', 'baz-id', 'foo/baz', 'bar/baz')],
@@ -310,6 +314,8 @@
tree.add('foo', 'foo-id')
tree.commit('Added file and directory')
os.unlink('tree/foo')
+ tree.lock_tree_write()
+ self.addCleanup(tree.unlock)
creator = shelf.ShelfCreator(tree, tree.basis_tree())
self.addCleanup(creator.finalize)
self.assertEqual([('delete file', 'foo-id', 'file', 'foo')],
@@ -325,6 +331,8 @@
tree.commit('Added file and directory')
os.unlink('tree/foo')
os.mkdir('tree/foo')
+ tree.lock_tree_write()
+ self.addCleanup(tree.unlock)
creator = shelf.ShelfCreator(tree, tree.basis_tree())
self.addCleanup(creator.finalize)
self.assertEqual([('change kind', 'foo-id', 'file', 'directory',
@@ -352,6 +360,8 @@
def test_shelve_change_unknown_change(self):
tree = self.make_branch_and_tree('tree')
+ tree.lock_tree_write()
+ self.addCleanup(tree.unlock)
creator = shelf.ShelfCreator(tree, tree.basis_tree())
self.addCleanup(creator.finalize)
e = self.assertRaises(ValueError, creator.shelve_change, ('unknown',))
@@ -363,6 +373,8 @@
tree.add('foo', 'foo-id')
tree.commit('Added file and directory')
tree.unversion(['foo-id'])
+ tree.lock_tree_write()
+ self.addCleanup(tree.unlock)
creator = shelf.ShelfCreator(tree, tree.basis_tree())
self.addCleanup(creator.finalize)
self.assertEqual([('delete file', 'foo-id', 'file', 'foo')],
@@ -373,6 +385,8 @@
def test_shelve_serialization(self):
tree = self.make_branch_and_tree('.')
+ tree.lock_tree_write()
+ self.addCleanup(tree.unlock)
creator = shelf.ShelfCreator(tree, tree.basis_tree())
self.addCleanup(creator.finalize)
shelf_file = open('shelf', 'wb')
@@ -387,6 +401,8 @@
tree = self.make_branch_and_tree('tree')
self.build_tree(['tree/foo'])
tree.add('foo', 'foo-id')
+ tree.lock_tree_write()
+ self.addCleanup(tree.unlock)
creator = shelf.ShelfCreator(tree, tree.basis_tree())
self.addCleanup(creator.finalize)
list(creator.iter_shelvable())
@@ -411,8 +427,12 @@
def test_shelve_unversioned(self):
tree = self.make_branch_and_tree('tree')
- self.assertRaises(errors.PathsNotVersionedError,
- shelf.ShelfCreator, tree, tree.basis_tree(), ['foo'])
+ tree.lock_tree_write()
+ try:
+ self.assertRaises(errors.PathsNotVersionedError,
+ shelf.ShelfCreator, tree, tree.basis_tree(), ['foo'])
+ finally:
+ tree.unlock()
# We should be able to lock/unlock the tree if ShelfCreator cleaned
# after itself.
wt = workingtree.WorkingTree.open('tree')
@@ -420,8 +440,15 @@
wt.unlock()
# And a second tentative should raise the same error (no
# limbo/pending_deletion leftovers).
- self.assertRaises(errors.PathsNotVersionedError,
- shelf.ShelfCreator, tree, tree.basis_tree(), ['foo'])
+ tree.lock_tree_write()
+ try:
+ self.assertRaises(errors.PathsNotVersionedError,
+ shelf.ShelfCreator, tree, tree.basis_tree(), ['foo'])
+ finally:
+ tree.unlock()
+
+ tree.lock_tree_write()
+ self.addCleanup(tree.unlock)
class TestUnshelver(tests.TestCaseWithTransport):
@@ -525,6 +552,7 @@
shelf_file = open('shelf', 'rb')
self.addCleanup(shelf_file.close)
unshelver = shelf.Unshelver.from_tree_and_shelf(tree, shelf_file)
+ unshelver.finalize()
def test_corrupt_shelf(self):
tree = self.make_branch_and_tree('.')
@@ -644,7 +672,10 @@
def test_get_metadata(self):
tree = self.make_branch_and_tree('.')
+ tree.lock_tree_write()
+ self.addCleanup(tree.unlock)
creator = shelf.ShelfCreator(tree, tree.basis_tree())
+ self.addCleanup(creator.finalize)
shelf_manager = tree.get_shelf_manager()
shelf_id = shelf_manager.shelve_changes(creator, 'foo')
metadata = shelf_manager.get_metadata(shelf_id)
=== modified file 'bzrlib/tests/test_shelf_ui.py'
--- a/bzrlib/tests/test_shelf_ui.py 2009-07-14 13:19:52 +0000
+++ b/bzrlib/tests/test_shelf_ui.py 2009-08-27 07:30:31 +0000
@@ -68,12 +68,16 @@
def test_unexpected_prompt_failure(self):
tree = self.create_shelvable_tree()
+ tree.lock_tree_write()
+ self.addCleanup(tree.unlock)
shelver = ExpectShelver(tree, tree.basis_tree())
e = self.assertRaises(AssertionError, shelver.run)
self.assertEqual('Unexpected prompt: Shelve? [yNfq?]', str(e))
def test_wrong_prompt_failure(self):
tree = self.create_shelvable_tree()
+ tree.lock_tree_write()
+ self.addCleanup(tree.unlock)
shelver = ExpectShelver(tree, tree.basis_tree())
shelver.expect('foo', 'y')
e = self.assertRaises(AssertionError, shelver.run)
@@ -81,6 +85,8 @@
def test_shelve_not_diff(self):
tree = self.create_shelvable_tree()
+ tree.lock_tree_write()
+ self.addCleanup(tree.unlock)
shelver = ExpectShelver(tree, tree.basis_tree())
shelver.expect('Shelve? [yNfq?]', 'n')
shelver.expect('Shelve? [yNfq?]', 'n')
@@ -90,6 +96,8 @@
def test_shelve_diff_no(self):
tree = self.create_shelvable_tree()
+ tree.lock_tree_write()
+ self.addCleanup(tree.unlock)
shelver = ExpectShelver(tree, tree.basis_tree())
shelver.expect('Shelve? [yNfq?]', 'y')
shelver.expect('Shelve? [yNfq?]', 'y')
@@ -99,6 +107,8 @@
def test_shelve_diff(self):
tree = self.create_shelvable_tree()
+ tree.lock_tree_write()
+ self.addCleanup(tree.unlock)
shelver = ExpectShelver(tree, tree.basis_tree())
shelver.expect('Shelve? [yNfq?]', 'y')
shelver.expect('Shelve? [yNfq?]', 'y')
@@ -108,6 +118,8 @@
def test_shelve_one_diff(self):
tree = self.create_shelvable_tree()
+ tree.lock_tree_write()
+ self.addCleanup(tree.unlock)
shelver = ExpectShelver(tree, tree.basis_tree())
shelver.expect('Shelve? [yNfq?]', 'y')
shelver.expect('Shelve? [yNfq?]', 'n')
@@ -118,6 +130,8 @@
def test_shelve_binary_change(self):
tree = self.create_shelvable_tree()
self.build_tree_contents([('tree/foo', '\x00')])
+ tree.lock_tree_write()
+ self.addCleanup(tree.unlock)
shelver = ExpectShelver(tree, tree.basis_tree())
shelver.expect('Shelve binary changes? [yNfq?]', 'y')
shelver.expect('Shelve 1 change(s)? [yNfq?]', 'y')
@@ -127,6 +141,8 @@
def test_shelve_rename(self):
tree = self.create_shelvable_tree()
tree.rename_one('foo', 'bar')
+ tree.lock_tree_write()
+ self.addCleanup(tree.unlock)
shelver = ExpectShelver(tree, tree.basis_tree())
shelver.expect('Shelve renaming "foo" => "bar"? [yNfq?]', 'y')
shelver.expect('Shelve? [yNfq?]', 'y')
@@ -138,6 +154,8 @@
def test_shelve_deletion(self):
tree = self.create_shelvable_tree()
os.unlink('tree/foo')
+ tree.lock_tree_write()
+ self.addCleanup(tree.unlock)
shelver = ExpectShelver(tree, tree.basis_tree())
shelver.expect('Shelve removing file "foo"? [yNfq?]', 'y')
shelver.expect('Shelve 1 change(s)? [yNfq?]', 'y')
@@ -149,6 +167,8 @@
tree.commit('add tree root')
self.build_tree(['tree/foo'])
tree.add('foo')
+ tree.lock_tree_write()
+ self.addCleanup(tree.unlock)
shelver = ExpectShelver(tree, tree.basis_tree())
shelver.expect('Shelve adding file "foo"? [yNfq?]', 'y')
shelver.expect('Shelve 1 change(s)? [yNfq?]', 'y')
@@ -159,6 +179,8 @@
tree = self.create_shelvable_tree()
os.unlink('tree/foo')
os.mkdir('tree/foo')
+ tree.lock_tree_write()
+ self.addCleanup(tree.unlock)
shelver = ExpectShelver(tree, tree.basis_tree())
shelver.expect('Shelve changing "foo" from file to directory? [yNfq?]',
'y')
@@ -172,6 +194,8 @@
tree.commit("Add symlink")
os.unlink('tree/baz')
os.symlink('vax', 'tree/baz')
+ tree.lock_tree_write()
+ self.addCleanup(tree.unlock)
shelver = ExpectShelver(tree, tree.basis_tree())
shelver.expect('Shelve changing target of "baz" from "bar" to '
'"vax"? [yNfq?]', 'y')
@@ -181,6 +205,8 @@
def test_shelve_finish(self):
tree = self.create_shelvable_tree()
+ tree.lock_tree_write()
+ self.addCleanup(tree.unlock)
shelver = ExpectShelver(tree, tree.basis_tree())
shelver.expect('Shelve? [yNfq?]', 'f')
shelver.expect('Shelve 2 change(s)? [yNfq?]', 'y')
@@ -189,6 +215,8 @@
def test_shelve_quit(self):
tree = self.create_shelvable_tree()
+ tree.lock_tree_write()
+ self.addCleanup(tree.unlock)
shelver = ExpectShelver(tree, tree.basis_tree())
shelver.expect('Shelve? [yNfq?]', 'q')
self.assertRaises(errors.UserAbort, shelver.run)
@@ -196,13 +224,20 @@
def test_shelve_all(self):
tree = self.create_shelvable_tree()
- ExpectShelver.from_args(sys.stdout, all=True, directory='tree').run()
+ shelver = ExpectShelver.from_args(sys.stdout, all=True,
+ directory='tree')
+ try:
+ shelver.run()
+ finally:
+ shelver.work_tree.unlock()
self.assertFileEqual(LINES_AJ, 'tree/foo')
def test_shelve_filename(self):
tree = self.create_shelvable_tree()
self.build_tree(['tree/bar'])
tree.add('bar')
+ tree.lock_tree_write()
+ self.addCleanup(tree.unlock)
shelver = ExpectShelver(tree, tree.basis_tree(), file_list=['bar'])
shelver.expect('Shelve adding file "bar"? [yNfq?]', 'y')
shelver.expect('Shelve 1 change(s)? [yNfq?]', 'y')
@@ -210,6 +245,8 @@
def test_shelve_help(self):
tree = self.create_shelvable_tree()
+ tree.lock_tree_write()
+ self.addCleanup(tree.unlock)
shelver = ExpectShelver(tree, tree.basis_tree())
shelver.expect('Shelve? [yNfq?]', '?')
shelver.expect('Shelve? [(y)es, (N)o, (f)inish, or (q)uit]', 'f')
@@ -220,7 +257,10 @@
tree = self.create_shelvable_tree()
shelver = shelf_ui.Shelver.from_args(sys.stdout, all=True,
directory='tree', destroy=True)
- shelver.run()
+ try:
+ shelver.run()
+ finally:
+ shelver.work_tree.unlock()
self.assertIs(None, tree.get_shelf_manager().last_shelf())
self.assertFileEqual(LINES_AJ, 'tree/foo')
@@ -229,6 +269,8 @@
def test_shelve_not_diff(self):
tree = self.create_shelvable_tree()
+ tree.lock_tree_write()
+ self.addCleanup(tree.unlock)
shelver = ExpectShelver(tree, tree.basis_tree(),
reporter=shelf_ui.ApplyReporter())
shelver.expect('Apply change? [yNfq?]', 'n')
@@ -239,6 +281,8 @@
def test_shelve_diff_no(self):
tree = self.create_shelvable_tree()
+ tree.lock_tree_write()
+ self.addCleanup(tree.unlock)
shelver = ExpectShelver(tree, tree.basis_tree(),
reporter=shelf_ui.ApplyReporter())
shelver.expect('Apply change? [yNfq?]', 'y')
@@ -249,6 +293,8 @@
def test_shelve_diff(self):
tree = self.create_shelvable_tree()
+ tree.lock_tree_write()
+ self.addCleanup(tree.unlock)
shelver = ExpectShelver(tree, tree.basis_tree(),
reporter=shelf_ui.ApplyReporter())
shelver.expect('Apply change? [yNfq?]', 'y')
@@ -260,6 +306,8 @@
def test_shelve_binary_change(self):
tree = self.create_shelvable_tree()
self.build_tree_contents([('tree/foo', '\x00')])
+ tree.lock_tree_write()
+ self.addCleanup(tree.unlock)
shelver = ExpectShelver(tree, tree.basis_tree(),
reporter=shelf_ui.ApplyReporter())
shelver.expect('Apply binary changes? [yNfq?]', 'y')
@@ -270,6 +318,8 @@
def test_shelve_rename(self):
tree = self.create_shelvable_tree()
tree.rename_one('foo', 'bar')
+ tree.lock_tree_write()
+ self.addCleanup(tree.unlock)
shelver = ExpectShelver(tree, tree.basis_tree(),
reporter=shelf_ui.ApplyReporter())
shelver.expect('Rename "bar" => "foo"? [yNfq?]', 'y')
@@ -282,6 +332,8 @@
def test_shelve_deletion(self):
tree = self.create_shelvable_tree()
os.unlink('tree/foo')
+ tree.lock_tree_write()
+ self.addCleanup(tree.unlock)
shelver = ExpectShelver(tree, tree.basis_tree(),
reporter=shelf_ui.ApplyReporter())
shelver.expect('Add file "foo"? [yNfq?]', 'y')
@@ -294,6 +346,8 @@
tree.commit('add tree root')
self.build_tree(['tree/foo'])
tree.add('foo')
+ tree.lock_tree_write()
+ self.addCleanup(tree.unlock)
shelver = ExpectShelver(tree, tree.basis_tree(),
reporter=shelf_ui.ApplyReporter())
shelver.expect('Delete file "foo"? [yNfq?]', 'y')
@@ -305,6 +359,8 @@
tree = self.create_shelvable_tree()
os.unlink('tree/foo')
os.mkdir('tree/foo')
+ tree.lock_tree_write()
+ self.addCleanup(tree.unlock)
shelver = ExpectShelver(tree, tree.basis_tree(),
reporter=shelf_ui.ApplyReporter())
shelver.expect('Change "foo" from directory to a file? [yNfq?]', 'y')
@@ -318,6 +374,8 @@
tree.commit("Add symlink")
os.unlink('tree/baz')
os.symlink('vax', 'tree/baz')
+ tree.lock_tree_write()
+ self.addCleanup(tree.unlock)
shelver = ExpectShelver(tree, tree.basis_tree(),
reporter=shelf_ui.ApplyReporter())
shelver.expect('Change target of "baz" from "vax" to "bar"? [yNfq?]',
@@ -331,12 +389,16 @@
def create_tree_with_shelf(self):
tree = self.make_branch_and_tree('tree')
- self.build_tree_contents([('tree/foo', LINES_AJ)])
- tree.add('foo', 'foo-id')
- tree.commit('added foo')
- self.build_tree_contents([('tree/foo', LINES_ZY)])
- shelf_ui.Shelver(tree, tree.basis_tree(), auto_apply=True,
- auto=True).run()
+ tree.lock_write()
+ try:
+ self.build_tree_contents([('tree/foo', LINES_AJ)])
+ tree.add('foo', 'foo-id')
+ tree.commit('added foo')
+ self.build_tree_contents([('tree/foo', LINES_ZY)])
+ shelf_ui.Shelver(tree, tree.basis_tree(), auto_apply=True,
+ auto=True).run()
+ finally:
+ tree.unlock()
return tree
def test_unshelve(self):
@@ -349,13 +411,22 @@
def test_unshelve_args(self):
tree = self.create_tree_with_shelf()
- shelf_ui.Unshelver.from_args(directory='tree').run()
+ unshelver = shelf_ui.Unshelver.from_args(directory='tree')
+ try:
+ unshelver.run()
+ finally:
+ unshelver.tree.unlock()
self.assertFileEqual(LINES_ZY, 'tree/foo')
self.assertIs(None, tree.get_shelf_manager().last_shelf())
def test_unshelve_args_dry_run(self):
tree = self.create_tree_with_shelf()
- shelf_ui.Unshelver.from_args(directory='tree', action='dry-run').run()
+ unshelver = shelf_ui.Unshelver.from_args(directory='tree',
+ action='dry-run')
+ try:
+ unshelver.run()
+ finally:
+ unshelver.tree.unlock()
self.assertFileEqual(LINES_AJ, 'tree/foo')
self.assertEqual(1, tree.get_shelf_manager().last_shelf())
@@ -369,7 +440,10 @@
shelf_file.close()
unshelver = shelf_ui.Unshelver.from_args(directory='tree',
action='delete-only')
- unshelver.run()
+ try:
+ unshelver.run()
+ finally:
+ unshelver.tree.unlock()
self.assertIs(None, manager.last_shelf())
def test_unshelve_args_invalid_shelf_id(self):
More information about the bazaar-commits
mailing list