Rev 4650: Support shelve and unshelve on windows - bug 305006. in http://bazaar.launchpad.net/~lifeless/bzr/shelve-locks
Robert Collins
robertc at robertcollins.net
Tue Aug 25 22:09:28 BST 2009
At http://bazaar.launchpad.net/~lifeless/bzr/shelve-locks
------------------------------------------------------------
revno: 4650
revision-id: robertc at robertcollins.net-20090825210917-dq2i8k6n4z63pneh
parent: robertc at robertcollins.net-20090825195832-oz7fisc4vhxw6xpz
committer: Robert Collins <robertc at robertcollins.net>
branch nick: shelve-locks
timestamp: Wed 2009-08-26 07:09:17 +1000
message:
Support shelve and unshelve on windows - bug 305006.
=== modified file 'NEWS'
--- a/NEWS 2009-08-25 08:16:44 +0000
+++ b/NEWS 2009-08-25 21:09:17 +0000
@@ -63,6 +63,9 @@
* ``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)
+
Documentation
*************
@@ -72,6 +75,10 @@
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)
+
Internals
*********
=== modified file 'bzrlib/builtins.py'
--- a/bzrlib/builtins.py 2009-08-24 22:32:53 +0000
+++ b/bzrlib/builtins.py 2009-08-25 21:09:17 +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:
@@ -5634,8 +5643,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
@@ -5680,7 +5693,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/shelf.py'
--- a/bzrlib/shelf.py 2009-08-21 04:07:06 +0000
+++ b/bzrlib/shelf.py 2009-08-25 21:09:17 +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-25 21:09:17 +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/test_shelf.py'
--- a/bzrlib/tests/test_shelf.py 2009-08-21 04:07:06 +0000
+++ b/bzrlib/tests/test_shelf.py 2009-08-25 21:09:17 +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')],
@@ -61,13 +63,11 @@
shelf_trans_id))
def test_shelve_rename(self):
- self.thisFailsStrictLockCheck()
creator = self.prepare_shelve_rename()
creator.shelve_rename('foo-id')
self.check_shelve_rename(creator)
def test_shelve_change_handles_rename(self):
- self.thisFailsStrictLockCheck()
creator = self.prepare_shelve_rename()
creator.shelve_change(('rename', 'foo-id', 'foo', 'bar'))
self.check_shelve_rename(creator)
@@ -78,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')],
@@ -97,13 +99,11 @@
self.assertEqual('foo/baz', tree.id2path('baz-id'))
def test_shelve_move(self):
- self.thisFailsStrictLockCheck()
creator, tree = self.prepare_shelve_move()
creator.shelve_rename('baz-id')
self.check_shelve_move(creator, tree)
def test_shelve_change_handles_move(self):
- self.thisFailsStrictLockCheck()
creator, tree = self.prepare_shelve_move()
creator.shelve_change(('rename', 'baz-id', 'foo/baz', 'bar/baz'))
self.check_shelve_move(creator, tree)
@@ -114,7 +114,6 @@
self.assertFileEqual(expected_content, shelf_file)
def prepare_content_change(self):
- self.thisFailsStrictLockCheck()
tree = self.make_branch_and_tree('.')
tree.lock_write()
self.addCleanup(tree.unlock)
@@ -177,7 +176,6 @@
creator.shelf_transform.final_kind(s_bar_trans_id))
def test_shelve_creation(self):
- self.thisFailsStrictLockCheck()
creator, tree = self.prepare_shelve_creation()
creator.shelve_creation('foo-id')
creator.shelve_creation('bar-id')
@@ -185,7 +183,6 @@
self.check_shelve_creation(creator, tree)
def test_shelve_change_handles_creation(self):
- self.thisFailsStrictLockCheck()
creator, tree = self.prepare_shelve_creation()
creator.shelve_change(('add file', 'foo-id', 'file', 'foo'))
creator.shelve_change(('add file', 'bar-id', 'directory', 'bar'))
@@ -218,17 +215,14 @@
self.assertEqual(link_target, ptree.get_symlink_target('foo-id'))
def test_shelve_symlink_creation(self):
- self.thisFailsStrictLockCheck()
self._test_shelve_symlink_creation('foo', 'bar')
def test_shelve_unicode_symlink_creation(self):
self.requireFeature(tests.UnicodeFilenameFeature)
- self.thisFailsStrictLockCheck()
self._test_shelve_symlink_creation(u'fo\N{Euro Sign}o',
u'b\N{Euro Sign}ar')
def test_shelve_change_handles_symlink_creation(self):
- self.thisFailsStrictLockCheck()
self._test_shelve_symlink_creation('foo', 'bar', shelve_change=True)
def _test_shelve_symlink_target_change(self, link_name,
@@ -262,22 +256,18 @@
self.assertEqual(new_target, ptree.get_symlink_target('foo-id'))
def test_shelve_symlink_target_change(self):
- self.thisFailsStrictLockCheck()
self._test_shelve_symlink_target_change('foo', 'bar', 'baz')
def test_shelve_unicode_symlink_target_change(self):
- self.thisFailsStrictLockCheck()
self.requireFeature(tests.UnicodeFilenameFeature)
self._test_shelve_symlink_target_change(
u'fo\N{Euro Sign}o', u'b\N{Euro Sign}ar', u'b\N{Euro Sign}az')
def test_shelve_change_handles_symlink_target_change(self):
- self.thisFailsStrictLockCheck()
self._test_shelve_symlink_target_change('foo', 'bar', 'baz',
shelve_change=True)
def test_shelve_creation_no_contents(self):
- self.thisFailsStrictLockCheck()
tree = self.make_branch_and_tree('.')
tree.lock_write()
self.addCleanup(tree.unlock)
@@ -322,7 +312,6 @@
self.assertFileEqual('baz', 'tree/foo/bar')
def test_shelve_deletion(self):
- self.thisFailsStrictLockCheck()
creator, tree = self.prepare_shelve_deletion()
creator.shelve_deletion('foo-id')
creator.shelve_deletion('bar-id')
@@ -330,7 +319,6 @@
self.check_shelve_deletion(tree)
def test_shelve_change_handles_deletion(self):
- self.thisFailsStrictLockCheck()
creator, tree = self.prepare_shelve_deletion()
creator.shelve_change(('delete file', 'foo-id', 'directory', 'foo'))
creator.shelve_change(('delete file', 'bar-id', 'file', 'foo/bar'))
@@ -338,12 +326,13 @@
self.check_shelve_deletion(tree)
def test_shelve_delete_contents(self):
- self.thisFailsStrictLockCheck()
tree = self.make_branch_and_tree('tree')
self.build_tree(['tree/foo',])
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')],
@@ -359,6 +348,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',
@@ -372,14 +363,12 @@
creator.shelf_transform._new_contents[s_trans_id])
def test_shelve_change_kind(self):
- self.thisFailsStrictLockCheck()
creator = self.prepare_shelve_change_kind()
creator.shelve_content_change('foo-id')
creator.transform()
self.check_shelve_change_kind(creator)
def test_shelve_change_handles_change_kind(self):
- self.thisFailsStrictLockCheck()
creator = self.prepare_shelve_change_kind()
creator.shelve_change(('change kind', 'foo-id', 'file', 'directory',
'foo'))
@@ -387,20 +376,22 @@
self.check_shelve_change_kind(creator)
def test_shelve_change_unknown_change(self):
- self.thisFailsStrictLockCheck()
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',))
self.assertEqual('Unknown change kind: "unknown"', str(e))
def test_shelve_unversion(self):
- self.thisFailsStrictLockCheck()
tree = self.make_branch_and_tree('tree')
self.build_tree(['tree/foo',])
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')],
@@ -410,8 +401,9 @@
self.failUnlessExists('tree/foo')
def test_shelve_serialization(self):
- self.thisFailsStrictLockCheck()
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')
@@ -423,10 +415,11 @@
self.assertFileEqual(EMPTY_SHELF, 'shelf')
def test_write_shelf(self):
- self.thisFailsStrictLockCheck()
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())
@@ -450,10 +443,13 @@
tt.deserialize(records)
def test_shelve_unversioned(self):
- self.thisFailsStrictLockCheck()
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')
@@ -461,12 +457,18 @@
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()
def test_shelve_skips_added_root(self):
"""Skip adds of the root when iterating through shelvable changes."""
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)
self.assertEqual([], list(creator.iter_shelvable()))
@@ -475,7 +477,6 @@
class TestUnshelver(tests.TestCaseWithTransport):
def test_make_merger(self):
- self.thisFailsStrictLockCheck()
tree = self.make_branch_and_tree('tree')
tree.commit('first commit')
self.build_tree_contents([('tree/foo', 'bar')])
@@ -498,7 +499,6 @@
shelf_file.close()
def test_unshelve_changed(self):
- self.thisFailsStrictLockCheck()
tree = self.make_branch_and_tree('tree')
tree.lock_write()
self.addCleanup(tree.unlock)
@@ -521,7 +521,6 @@
self.assertFileEqual('z\na\nb\nd\n', 'tree/foo')
def test_unshelve_deleted(self):
- self.thisFailsStrictLockCheck()
tree = self.make_branch_and_tree('tree')
tree.lock_write()
self.addCleanup(tree.unlock)
@@ -551,7 +550,6 @@
self.assertFalse('bar-id' in tree)
def test_unshelve_base(self):
- self.thisFailsStrictLockCheck()
tree = self.make_branch_and_tree('tree')
tree.lock_write()
self.addCleanup(tree.unlock)
@@ -572,15 +570,14 @@
self.assertEqual('rev1', unshelver.base_tree.get_revision_id())
def test_unshelve_serialization(self):
- self.thisFailsStrictLockCheck()
tree = self.make_branch_and_tree('.')
self.build_tree_contents([('shelf', EMPTY_SHELF)])
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):
- self.thisFailsStrictLockCheck()
tree = self.make_branch_and_tree('.')
self.build_tree_contents([('shelf', EMPTY_SHELF.replace('metadata',
'foo'))])
@@ -698,7 +695,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-08-24 16:56:26 +0000
+++ b/bzrlib/tests/test_shelf_ui.py 2009-08-25 21:09:17 +0000
@@ -72,23 +72,26 @@
return tree
def test_unexpected_prompt_failure(self):
- self.thisFailsStrictLockCheck()
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):
- self.thisFailsStrictLockCheck()
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)
self.assertEqual('Wrong prompt: Shelve? [yNfq?]', str(e))
def test_shelve_not_diff(self):
- self.thisFailsStrictLockCheck()
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')
@@ -97,8 +100,9 @@
self.assertFileEqual(LINES_ZY, 'tree/foo')
def test_shelve_diff_no(self):
- self.thisFailsStrictLockCheck()
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')
@@ -107,8 +111,9 @@
self.assertFileEqual(LINES_ZY, 'tree/foo')
def test_shelve_diff(self):
- self.thisFailsStrictLockCheck()
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')
@@ -117,8 +122,9 @@
self.assertFileEqual(LINES_AJ, 'tree/foo')
def test_shelve_one_diff(self):
- self.thisFailsStrictLockCheck()
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')
@@ -127,9 +133,10 @@
self.assertFileEqual(LINES_AY, 'tree/foo')
def test_shelve_binary_change(self):
- self.thisFailsStrictLockCheck()
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')
@@ -137,9 +144,10 @@
self.assertFileEqual(LINES_AJ, 'tree/foo')
def test_shelve_rename(self):
- self.thisFailsStrictLockCheck()
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')
@@ -149,9 +157,10 @@
self.assertFileEqual(LINES_AJ, 'tree/foo')
def test_shelve_deletion(self):
- self.thisFailsStrictLockCheck()
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')
@@ -159,11 +168,12 @@
self.assertFileEqual(LINES_AJ, 'tree/foo')
def test_shelve_creation(self):
- self.thisFailsStrictLockCheck()
tree = self.make_branch_and_tree('tree')
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')
@@ -171,17 +181,17 @@
self.failIfExists('tree/foo')
def test_shelve_kind_change(self):
- self.thisFailsStrictLockCheck()
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')
shelver.expect('Shelve 1 change(s)? [yNfq?]', 'y')
def test_shelve_modify_target(self):
- self.thisFailsStrictLockCheck()
self.requireFeature(tests.SymlinkFeature)
tree = self.create_shelvable_tree()
os.symlink('bar', 'tree/baz')
@@ -189,6 +199,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')
@@ -197,8 +209,9 @@
self.assertEqual('bar', os.readlink('tree/baz'))
def test_shelve_finish(self):
- self.thisFailsStrictLockCheck()
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')
@@ -206,32 +219,39 @@
self.assertFileEqual(LINES_AJ, 'tree/foo')
def test_shelve_quit(self):
- self.thisFailsStrictLockCheck()
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)
self.assertFileEqual(LINES_ZY, 'tree/foo')
def test_shelve_all(self):
- self.thisFailsStrictLockCheck()
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):
- self.thisFailsStrictLockCheck()
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')
shelver.run()
def test_shelve_help(self):
- self.thisFailsStrictLockCheck()
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')
@@ -239,11 +259,13 @@
shelver.run()
def test_shelve_distroy(self):
- self.thisFailsStrictLockCheck()
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')
@@ -289,8 +311,9 @@
class TestApplyReporter(TestShelver):
def test_shelve_not_diff(self):
- self.thisFailsStrictLockCheck()
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')
@@ -300,8 +323,9 @@
self.assertFileEqual(LINES_ZY, 'tree/foo')
def test_shelve_diff_no(self):
- self.thisFailsStrictLockCheck()
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')
@@ -311,8 +335,9 @@
self.assertFileEqual(LINES_ZY, 'tree/foo')
def test_shelve_diff(self):
- self.thisFailsStrictLockCheck()
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')
@@ -322,9 +347,10 @@
self.assertFileEqual(LINES_AJ, 'tree/foo')
def test_shelve_binary_change(self):
- self.thisFailsStrictLockCheck()
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')
@@ -333,9 +359,10 @@
self.assertFileEqual(LINES_AJ, 'tree/foo')
def test_shelve_rename(self):
- self.thisFailsStrictLockCheck()
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')
@@ -346,9 +373,10 @@
self.assertFileEqual(LINES_AJ, 'tree/foo')
def test_shelve_deletion(self):
- self.thisFailsStrictLockCheck()
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')
@@ -357,11 +385,12 @@
self.assertFileEqual(LINES_AJ, 'tree/foo')
def test_shelve_creation(self):
- self.thisFailsStrictLockCheck()
tree = self.make_branch_and_tree('tree')
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')
@@ -370,17 +399,17 @@
self.failIfExists('tree/foo')
def test_shelve_kind_change(self):
- self.thisFailsStrictLockCheck()
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')
shelver.expect('Apply 1 change(s)? [yNfq?]', 'y')
def test_shelve_modify_target(self):
- self.thisFailsStrictLockCheck()
self.requireFeature(tests.SymlinkFeature)
tree = self.create_shelvable_tree()
os.symlink('bar', 'tree/baz')
@@ -388,6 +417,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?]',
@@ -401,16 +432,19 @@
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):
- self.thisFailsStrictLockCheck()
tree = self.create_tree_with_shelf()
tree.lock_write()
self.addCleanup(tree.unlock)
@@ -419,21 +453,27 @@
self.assertFileEqual(LINES_ZY, 'tree/foo')
def test_unshelve_args(self):
- self.thisFailsStrictLockCheck()
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):
- self.thisFailsStrictLockCheck()
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())
def test_unshelve_args_delete_only(self):
- self.thisFailsStrictLockCheck()
tree = self.make_branch_and_tree('tree')
manager = tree.get_shelf_manager()
shelf_file = manager.new_shelf()[1]
@@ -443,11 +483,13 @@
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):
- self.thisFailsStrictLockCheck()
tree = self.make_branch_and_tree('tree')
manager = tree.get_shelf_manager()
shelf_file = manager.new_shelf()[1]
More information about the bazaar-commits
mailing list