198
215
self.assertFalse(wt.has_filename('b/c'))
199
216
self.assertFalse(wt.has_filename('d'))
219
def test_commit_deleted_subtree_with_removed(self):
220
wt = self.make_branch_and_tree('.')
221
self.build_tree(['a', 'b/', 'b/c', 'd'])
222
wt.add(['a', 'b', 'b/c'], ['a-id', 'b-id', 'c-id'])
225
this_dir = self.get_transport()
226
this_dir.delete_tree('b')
228
wt.commit('commit deleted rename')
229
self.assertTrue(wt.has_id('a-id'))
230
self.assertFalse(wt.has_or_had_id('b-id'))
231
self.assertFalse(wt.has_or_had_id('c-id'))
232
self.assertTrue(wt.has_filename('a'))
233
self.assertFalse(wt.has_filename('b'))
234
self.assertFalse(wt.has_filename('b/c'))
237
def test_commit_move_new(self):
238
wt = self.make_branch_and_tree('first')
240
wt2 = wt.bzrdir.sprout('second').open_workingtree()
241
self.build_tree(['second/name1'])
242
wt2.add('name1', 'name1-id')
244
wt.merge_from_branch(wt2.branch)
245
wt.rename_one('name1', 'name2')
247
wt.path2id('name1-id')
249
def test_nested_commit(self):
250
"""Commit in multiply-nested trees"""
251
tree = self.make_branch_and_tree('.')
252
if not tree.supports_tree_reference():
255
subtree = self.make_branch_and_tree('subtree')
256
subsubtree = self.make_branch_and_tree('subtree/subtree')
257
subtree.add(['subtree'])
258
tree.add(['subtree'])
259
# use allow_pointless=False to ensure that the deepest tree, which
260
# has no commits made to it, does not get a pointless commit.
261
rev_id = tree.commit('added reference', allow_pointless=False)
263
self.addCleanup(tree.unlock)
264
# the deepest subtree has not changed, so no commit should take place.
265
self.assertEqual(None, subsubtree.last_revision())
266
# the intermediate tree should have committed a pointer to the current
268
sub_basis = subtree.basis_tree()
269
sub_basis.lock_read()
270
self.addCleanup(sub_basis.unlock)
271
self.assertEqual(subsubtree.last_revision(),
272
sub_basis.get_reference_revision(sub_basis.path2id('subtree')))
273
# the intermediate tree has changed, so should have had a commit
275
self.assertNotEqual(None, subtree.last_revision())
276
# the outer tree should have committed a pointer to the current
278
basis = tree.basis_tree()
280
self.addCleanup(basis.unlock)
281
self.assertEqual(subtree.last_revision(),
282
basis.get_reference_revision(basis.path2id('subtree')))
283
# the outer tree must have have changed too.
284
self.assertNotEqual(None, rev_id)
286
def test_nested_commit_second_commit_detects_changes(self):
287
"""Commit with a nested tree picks up the correct child revid."""
288
tree = self.make_branch_and_tree('.')
289
if not tree.supports_tree_reference():
292
subtree = self.make_branch_and_tree('subtree')
293
tree.add(['subtree'])
294
self.build_tree(['subtree/file'])
295
subtree.add(['file'], ['file-id'])
296
rev_id = tree.commit('added reference', allow_pointless=False)
297
child_revid = subtree.last_revision()
298
# now change the child tree
299
self.build_tree_contents([('subtree/file', 'new-content')])
300
# and commit in the parent should commit the child and grab its revid,
301
# we test with allow_pointless=False here so that we are simulating
302
# what users will see.
303
rev_id2 = tree.commit('changed subtree only', allow_pointless=False)
304
# the child tree has changed, so should have had a commit
306
self.assertNotEqual(None, subtree.last_revision())
307
self.assertNotEqual(child_revid, subtree.last_revision())
308
# the outer tree should have committed a pointer to the current
310
basis = tree.basis_tree()
312
self.addCleanup(basis.unlock)
313
self.assertEqual(subtree.last_revision(),
314
basis.get_reference_revision(basis.path2id('subtree')))
315
self.assertNotEqual(rev_id, rev_id2)
203
318
class TestCommitProgress(TestCaseWithWorkingTree):
230
345
# into the factory for this test - just make the test ui factory
231
346
# pun as a reporter. Then we can check the ordering is right.
232
347
tree.commit('second post', specific_files=['b'])
233
# 9 steps: 1 for rev, 2 for inventory, 1 for finishing. 2 for root
234
# and 6 for inventory files.
235
# 2 steps don't trigger an update, as 'a' and 'c' are not
348
# 4 steps, the first of which is reported 5 times, once per file
349
# 2 files don't trigger an update, as 'a' and 'c' are not
237
351
self.assertEqual(
352
[('update', 1, 4, 'Collecting changes [Entry 0/?] - Stage'),
353
('update', 1, 4, 'Collecting changes [Entry 1/4] - Stage'),
354
('update', 1, 4, 'Collecting changes [Entry 2/4] - Stage'),
355
('update', 1, 4, 'Collecting changes [Entry 3/4] - Stage'),
356
('update', 1, 4, 'Collecting changes [Entry 4/4] - Stage'),
357
('update', 2, 4, 'Saving data locally - Stage'),
358
('update', 3, 4, 'Updating the working tree - Stage'),
359
('update', 4, 4, 'Running post commit hooks - Stage')],
363
def test_commit_progress_shows_hook_names(self):
364
tree = self.make_branch_and_tree('.')
365
# set a progress bar that captures the calls so we can see what is
367
self.old_ui_factory = ui.ui_factory
368
self.addCleanup(self.restoreDefaults)
369
factory = CapturingUIFactory()
370
ui.ui_factory = factory
371
def a_hook(_, _2, _3, _4, _5, _6):
373
branch.Branch.hooks.install_hook('post_commit', a_hook)
374
branch.Branch.hooks.name_hook(a_hook, 'hook name')
375
tree.commit('first post')
377
[('update', 1, 4, 'Collecting changes [Entry 0/?] - Stage'),
378
('update', 1, 4, 'Collecting changes [Entry 1/1] - Stage'),
379
('update', 2, 4, 'Saving data locally - Stage'),
380
('update', 3, 4, 'Updating the working tree - Stage'),
381
('update', 4, 4, 'Running post commit hooks - Stage'),
382
('update', 4, 4, 'Running post commit hooks [hook name] - Stage'),