1
# Copyright (C) 2008 Canonical Ltd
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
# GNU General Public License for more details.
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
from bzrlib import errors, pack, shelf, tests, transform
22
class TestPrepareShelf(tests.TestCaseWithTransport):
24
def test_shelve_rename(self):
25
tree = self.make_branch_and_tree('.')
26
self.build_tree(['foo'])
27
tree.add(['foo'], ['foo-id'])
29
tree.rename_one('foo', 'bar')
30
creator = shelf.ShelfCreator(tree, tree.basis_tree())
31
self.addCleanup(creator.finalize)
32
self.assertEqual([('rename', 'foo-id', 'foo', 'bar')], list(creator))
33
creator.shelve_rename('foo-id')
34
work_trans_id = creator.work_transform.trans_id_file_id('foo-id')
35
self.assertEqual('foo', creator.work_transform.final_name(
37
shelf_trans_id = creator.shelf_transform.trans_id_file_id('foo-id')
38
self.assertEqual('bar', creator.shelf_transform.final_name(
41
def test_shelve_move(self):
42
tree = self.make_branch_and_tree('.')
43
self.build_tree(['foo/', 'bar/', 'foo/baz'])
44
tree.add(['foo', 'bar', 'foo/baz'], ['foo-id', 'bar-id', 'baz-id'])
46
tree.rename_one('foo/baz', 'bar/baz')
47
creator = shelf.ShelfCreator(tree, tree.basis_tree())
48
self.addCleanup(creator.finalize)
49
self.assertEqual([('rename', 'baz-id', 'foo/baz', 'bar/baz')],
51
creator.shelve_rename('baz-id')
52
work_trans_id = creator.work_transform.trans_id_file_id('baz-id')
53
work_foo = creator.work_transform.trans_id_file_id('foo-id')
54
self.assertEqual(work_foo, creator.work_transform.final_parent(
56
shelf_trans_id = creator.shelf_transform.trans_id_file_id('baz-id')
57
shelf_bar = creator.shelf_transform.trans_id_file_id('bar-id')
58
self.assertEqual(shelf_bar, creator.shelf_transform.final_parent(
61
self.assertEqual('foo/baz', tree.id2path('baz-id'))
63
def assertShelvedFileEqual(self, expected_content, creator, file_id):
64
s_trans_id = creator.shelf_transform.trans_id_file_id(file_id)
65
shelf_file = creator.shelf_transform._limbo_name(s_trans_id)
66
self.assertFileEqual(expected_content, shelf_file)
68
def test_shelve_content_change(self):
69
tree = self.make_branch_and_tree('.')
71
self.addCleanup(tree.unlock)
72
self.build_tree_contents([('foo', 'a\n')])
73
tree.add('foo', 'foo-id')
74
tree.commit('Committed foo')
75
self.build_tree_contents([('foo', 'b\na\nc\n')])
76
creator = shelf.ShelfCreator(tree, tree.basis_tree())
77
self.addCleanup(creator.finalize)
78
self.assertEqual([('modify text', 'foo-id')], list(creator))
79
creator.shelve_lines('foo-id', ['a\n', 'c\n'])
81
self.assertFileEqual('a\nc\n', 'foo')
82
self.assertShelvedFileEqual('b\na\n', creator, 'foo-id')
84
def test_shelve_creation(self):
85
tree = self.make_branch_and_tree('.')
87
self.addCleanup(tree.unlock)
88
tree.commit('Empty tree')
89
self.build_tree_contents([('foo', 'a\n'), ('bar/',)])
90
tree.add(['foo', 'bar'], ['foo-id', 'bar-id'])
91
creator = shelf.ShelfCreator(tree, tree.basis_tree())
92
self.addCleanup(creator.finalize)
93
self.assertEqual([('add file', 'bar-id', 'directory', 'bar'),
94
('add file', 'foo-id', 'file', 'foo')],
95
sorted(list(creator)))
96
creator.shelve_creation('foo-id')
97
creator.shelve_creation('bar-id')
99
self.assertRaises(StopIteration,
100
tree.iter_entries_by_dir(['foo-id']).next)
101
s_trans_id = creator.shelf_transform.trans_id_file_id('foo-id')
102
self.assertEqual('foo-id',
103
creator.shelf_transform.final_file_id(s_trans_id))
104
self.failIfExists('foo')
105
self.failIfExists('bar')
106
self.assertShelvedFileEqual('a\n', creator, 'foo-id')
107
s_bar_trans_id = creator.shelf_transform.trans_id_file_id('bar-id')
108
self.assertEqual('directory',
109
creator.shelf_transform.final_kind(s_bar_trans_id))
111
def test_shelve_symlink_creation(self):
112
self.requireFeature(tests.SymlinkFeature)
113
tree = self.make_branch_and_tree('.')
115
self.addCleanup(tree.unlock)
116
tree.commit('Empty tree')
117
os.symlink('bar', 'foo')
118
tree.add('foo', 'foo-id')
119
creator = shelf.ShelfCreator(tree, tree.basis_tree())
120
self.addCleanup(creator.finalize)
121
self.assertEqual([('add file', 'foo-id', 'symlink', 'foo')],
123
creator.shelve_creation('foo-id')
125
s_trans_id = creator.shelf_transform.trans_id_file_id('foo-id')
126
self.failIfExists('foo')
127
limbo_name = creator.shelf_transform._limbo_name(s_trans_id)
128
self.assertEqual('bar', os.readlink(limbo_name))
130
def test_shelve_creation_no_contents(self):
131
tree = self.make_branch_and_tree('.')
133
self.addCleanup(tree.unlock)
134
tree.commit('Empty tree')
135
self.build_tree(['foo'])
136
tree.add('foo', 'foo-id')
138
creator = shelf.ShelfCreator(tree, tree.basis_tree())
139
self.addCleanup(creator.finalize)
140
self.assertEqual([('add file', 'foo-id', None, 'foo')],
141
sorted(list(creator)))
142
creator.shelve_creation('foo-id')
144
self.assertRaises(StopIteration,
145
tree.iter_entries_by_dir(['foo-id']).next)
146
self.assertShelvedFileEqual('', creator, 'foo-id')
147
s_trans_id = creator.shelf_transform.trans_id_file_id('foo-id')
148
self.assertEqual('foo-id',
149
creator.shelf_transform.final_file_id(s_trans_id))
150
self.failIfExists('foo')
152
def test_shelve_deletion(self):
153
tree = self.make_branch_and_tree('tree')
155
self.addCleanup(tree.unlock)
156
self.build_tree_contents([('tree/foo/',), ('tree/foo/bar', 'baz')])
157
tree.add(['foo', 'foo/bar'], ['foo-id', 'bar-id'])
158
tree.commit('Added file and directory')
159
tree.unversion(['foo-id', 'bar-id'])
160
os.unlink('tree/foo/bar')
162
creator = shelf.ShelfCreator(tree, tree.basis_tree())
163
self.addCleanup(creator.finalize)
164
self.assertEqual([('delete file', 'bar-id', 'file', 'foo/bar'),
165
('delete file', 'foo-id', 'directory', 'foo')],
166
sorted(list(creator)))
167
creator.shelve_deletion('foo-id')
168
creator.shelve_deletion('bar-id')
170
self.assertTrue('foo-id' in tree)
171
self.assertTrue('bar-id' in tree)
172
self.assertFileEqual('baz', 'tree/foo/bar')
174
def test_shelve_delete_contents(self):
175
tree = self.make_branch_and_tree('tree')
176
self.build_tree(['tree/foo',])
177
tree.add('foo', 'foo-id')
178
tree.commit('Added file and directory')
179
os.unlink('tree/foo')
180
creator = shelf.ShelfCreator(tree, tree.basis_tree())
181
self.addCleanup(creator.finalize)
182
self.assertEqual([('delete file', 'foo-id', 'file', 'foo')],
183
sorted(list(creator)))
184
creator.shelve_deletion('foo-id')
186
self.failUnlessExists('tree/foo')
188
def test_shelve_change_kind(self):
189
tree = self.make_branch_and_tree('tree')
190
self.build_tree_contents([('tree/foo', 'bar')])
191
tree.add('foo', 'foo-id')
192
tree.commit('Added file and directory')
193
os.unlink('tree/foo')
195
creator = shelf.ShelfCreator(tree, tree.basis_tree())
196
self.addCleanup(creator.finalize)
197
self.assertEqual([('change kind', 'foo-id', 'file', 'directory',
198
'foo')], sorted(list(creator)))
199
creator.shelve_content_change('foo-id')
201
self.assertFileEqual('bar', 'tree/foo')
202
s_trans_id = creator.shelf_transform.trans_id_file_id('foo-id')
203
self.assertEqual('directory',
204
creator.shelf_transform._new_contents[s_trans_id])
206
def test_shelve_unversion(self):
207
tree = self.make_branch_and_tree('tree')
208
self.build_tree(['tree/foo',])
209
tree.add('foo', 'foo-id')
210
tree.commit('Added file and directory')
211
tree.unversion(['foo-id'])
212
creator = shelf.ShelfCreator(tree, tree.basis_tree())
213
self.addCleanup(creator.finalize)
214
self.assertEqual([('delete file', 'foo-id', 'file', 'foo')],
215
sorted(list(creator)))
216
creator.shelve_deletion('foo-id')
218
self.failUnlessExists('tree/foo')
220
def test_write_shelf(self):
221
tree = self.make_branch_and_tree('tree')
222
self.build_tree(['tree/foo'])
223
tree.add('foo', 'foo-id')
224
creator = shelf.ShelfCreator(tree, tree.basis_tree())
225
self.addCleanup(creator.finalize)
227
creator.shelve_creation('foo-id')
228
shelf_file = open('shelf', 'wb')
230
creator.write_shelf(shelf_file)
233
parser = pack.ContainerPushParser()
234
shelf_file = open('shelf', 'rb')
236
parser.accept_bytes(shelf_file.read())
239
tt = transform.TransformPreview(tree)
240
self.addCleanup(tt.finalize)
241
records = iter(parser.read_pending_records())
244
tt.deserialize(records)
247
class TestUnshelver(tests.TestCaseWithTransport):
249
def test_make_merger(self):
250
tree = self.make_branch_and_tree('tree')
251
tree.commit('first commit')
252
self.build_tree_contents([('tree/foo', 'bar')])
254
self.addCleanup(tree.unlock)
255
tree.add('foo', 'foo-id')
256
creator = shelf.ShelfCreator(tree, tree.basis_tree())
257
self.addCleanup(creator.finalize)
259
creator.shelve_creation('foo-id')
260
shelf_file = open('shelf-file', 'w+b')
262
creator.write_shelf(shelf_file)
265
unshelver = shelf.Unshelver.from_tree_and_shelf(tree, shelf_file)
266
unshelver.make_merger().do_merge()
267
self.assertFileEqual('bar', 'tree/foo')
271
def test_unshelve_changed(self):
272
tree = self.make_branch_and_tree('tree')
274
self.addCleanup(tree.unlock)
275
self.build_tree_contents([('tree/foo', 'a\nb\nc\n')])
276
tree.add('foo', 'foo-id')
277
tree.commit('first commit')
278
self.build_tree_contents([('tree/foo', 'a\nb\nd\n')])
279
creator = shelf.ShelfCreator(tree, tree.basis_tree())
280
self.addCleanup(creator.finalize)
282
creator.shelve_lines('foo-id', ['a\n', 'b\n', 'c\n'])
283
shelf_file = open('shelf', 'w+b')
284
self.addCleanup(shelf_file.close)
285
creator.write_shelf(shelf_file)
287
self.build_tree_contents([('tree/foo', 'z\na\nb\nc\n')])
289
unshelver = shelf.Unshelver.from_tree_and_shelf(tree, shelf_file)
290
unshelver.make_merger().do_merge()
291
self.assertFileEqual('z\na\nb\nd\n', 'tree/foo')
293
def test_unshelve_base(self):
294
tree = self.make_branch_and_tree('tree')
296
self.addCleanup(tree.unlock)
297
tree.commit('rev1', rev_id='rev1')
298
creator = shelf.ShelfCreator(tree, tree.basis_tree())
299
self.addCleanup(creator.finalize)
300
manager = tree.get_shelf_manager()
301
shelf_id, shelf_file = manager.new_shelf()
303
creator.write_shelf(shelf_file)
306
tree.commit('rev2', rev_id='rev2')
307
shelf_file = manager.read_shelf(1)
308
self.addCleanup(shelf_file.close)
309
unshelver = shelf.Unshelver.from_tree_and_shelf(tree, shelf_file)
310
self.addCleanup(unshelver.finalize)
311
self.assertEqual('rev1', unshelver.base_tree.get_revision_id())
314
class TestShelfManager(tests.TestCaseWithTransport):
316
def test_get_shelf_manager(self):
317
tree = self.make_branch_and_tree('.')
318
manager = tree.get_shelf_manager()
319
self.assertEqual(tree._transport.base + 'shelf/',
320
manager.transport.base)
322
def get_manager(self):
323
return self.make_branch_and_tree('.').get_shelf_manager()
325
def test_new_shelf(self):
326
manager = self.get_manager()
327
shelf_id, shelf_file = manager.new_shelf()
329
self.assertEqual(1, shelf_id)
330
shelf_id, shelf_file = manager.new_shelf()
332
self.assertEqual(2, shelf_id)
333
manager.delete_shelf(1)
334
shelf_id, shelf_file = manager.new_shelf()
336
self.assertEqual(3, shelf_id)
338
def test_active_shelves(self):
339
manager = self.get_manager()
340
self.assertEqual([], manager.active_shelves())
341
shelf_id, shelf_file = manager.new_shelf()
343
self.assertEqual([1], manager.active_shelves())
345
def test_delete_shelf(self):
346
manager = self.get_manager()
347
shelf_id, shelf_file = manager.new_shelf()
349
self.assertEqual([1], manager.active_shelves())
350
manager.delete_shelf(1)
351
self.assertEqual([], manager.active_shelves())
353
def test_last_shelf(self):
354
manager = self.get_manager()
355
self.assertIs(None, manager.last_shelf())
356
shelf_id, shelf_file = manager.new_shelf()
358
self.assertEqual(1, manager.last_shelf())
360
def test_read_shelf(self):
361
manager = self.get_manager()
362
shelf_id, shelf_file = manager.new_shelf()
364
shelf_file.write('foo')
367
shelf_id, shelf_file = manager.new_shelf()
369
shelf_file.write('bar')
372
shelf_file = manager.read_shelf(1)
374
self.assertEqual('foo', shelf_file.read())
377
shelf_file = manager.read_shelf(2)
379
self.assertEqual('bar', shelf_file.read())
383
def test_read_non_existant(self):
384
manager = self.get_manager()
385
e = self.assertRaises(errors.NoSuchShelfId, manager.read_shelf, 1)
386
self.assertEqual('No changes are shelved with id "1".', str(e))
388
def test_shelve_changes(self):
389
tree = self.make_branch_and_tree('tree')
390
tree.commit('no-change commit')
392
self.addCleanup(tree.unlock)
393
self.build_tree_contents([('tree/foo', 'bar')])
394
self.assertFileEqual('bar', 'tree/foo')
395
tree.add('foo', 'foo-id')
396
creator = shelf.ShelfCreator(tree, tree.basis_tree())
397
self.addCleanup(creator.finalize)
399
creator.shelve_creation('foo-id')
400
shelf_manager = tree.get_shelf_manager()
401
shelf_id = shelf_manager.shelve_changes(creator)
402
self.failIfExists('tree/foo')
403
unshelver = shelf_manager.get_unshelver(shelf_id)
404
unshelver.make_merger().do_merge()
405
self.assertFileEqual('bar', 'tree/foo')