173
176
self.addCleanup(basis_tree.unlock)
174
177
self.assertEqual(rev_id, basis_tree.inventory.root.revision)
179
def _get_revtrees(self, tree, revision_ids):
180
trees = list(tree.branch.repository.revision_trees(revision_ids))
183
self.addCleanup(tree.unlock)
186
def test_last_modified_revision_after_commit_root_unchanged(self):
187
# commiting without changing the root does not change the
188
# last modified except on non-rich-root-repositories.
189
tree = self.make_branch_and_tree('.')
190
rev1 = tree.commit('')
191
rev2 = tree.commit('')
192
tree1, tree2 = self._get_revtrees(tree, [rev1, rev2])
193
self.assertEqual(rev1, tree1.inventory.root.revision)
194
if tree.branch.repository.supports_rich_root():
195
self.assertEqual(rev1, tree2.inventory.root.revision)
197
self.assertEqual(rev2, tree2.inventory.root.revision)
199
def _add_commit_check_unchanged(self, tree, name):
200
tree.add([name], [name + 'id'])
201
rev1 = tree.commit('')
202
rev2 = tree.commit('')
203
tree1, tree2 = self._get_revtrees(tree, [rev1, rev2])
204
self.assertEqual(rev1, tree1.inventory[name + 'id'].revision)
205
self.assertEqual(rev1, tree2.inventory[name + 'id'].revision)
206
self.assertFileAncestry([rev1], tree, name)
208
def test_last_modified_revision_after_commit_dir_unchanged(self):
209
# committing without changing a dir does not change the last modified.
210
tree = self.make_branch_and_tree('.')
211
self.build_tree(['dir/'])
212
self._add_commit_check_unchanged(tree, 'dir')
214
def test_last_modified_revision_after_commit_dir_contents_unchanged(self):
215
# committing without changing a dir does not change the last modified
216
# of the dir even the dirs contents are changed.
217
tree = self.make_branch_and_tree('.')
218
self.build_tree(['dir/'])
219
tree.add(['dir'], ['dirid'])
220
rev1 = tree.commit('')
221
self.build_tree(['dir/content'])
222
tree.add(['dir/content'], ['contentid'])
223
rev2 = tree.commit('')
224
tree1, tree2 = self._get_revtrees(tree, [rev1, rev2])
225
self.assertEqual(rev1, tree1.inventory['dirid'].revision)
226
self.assertEqual(rev1, tree2.inventory['dirid'].revision)
227
self.assertFileAncestry([rev1], tree, 'dir')
229
def test_last_modified_revision_after_commit_file_unchanged(self):
230
# committing without changing a file does not change the last modified.
231
tree = self.make_branch_and_tree('.')
232
self.build_tree(['file'])
233
self._add_commit_check_unchanged(tree, 'file')
235
def test_last_modified_revision_after_commit_link_unchanged(self):
236
# committing without changing a link does not change the last modified.
237
self.requireFeature(tests.SymlinkFeature)
238
tree = self.make_branch_and_tree('.')
239
os.symlink('target', 'link')
240
self._add_commit_check_unchanged(tree, 'link')
242
def _add_commit_renamed_check_changed(self, tree, name):
244
tree.rename_one(name, 'new_' + name)
245
self._add_commit_change_check_changed(tree, name, rename)
247
def test_last_modified_revision_after_rename_dir_changes(self):
248
# renaming a dir changes the last modified.
249
tree = self.make_branch_and_tree('.')
250
self.build_tree(['dir/'])
251
self._add_commit_renamed_check_changed(tree, 'dir')
253
def test_last_modified_revision_after_rename_file_changes(self):
254
# renaming a file changes the last modified.
255
tree = self.make_branch_and_tree('.')
256
self.build_tree(['file'])
257
self._add_commit_renamed_check_changed(tree, 'file')
259
def test_last_modified_revision_after_rename_link_changes(self):
260
# renaming a link changes the last modified.
261
self.requireFeature(tests.SymlinkFeature)
262
tree = self.make_branch_and_tree('.')
263
os.symlink('target', 'link')
264
self._add_commit_renamed_check_changed(tree, 'link')
266
def _add_commit_reparent_check_changed(self, tree, name):
267
self.build_tree(['newparent/'])
268
tree.add(['newparent'])
270
tree.rename_one(name, 'newparent/new_' + name)
271
self._add_commit_change_check_changed(tree, name, reparent)
273
def test_last_modified_revision_after_reparent_dir_changes(self):
274
# reparenting a dir changes the last modified.
275
tree = self.make_branch_and_tree('.')
276
self.build_tree(['dir/'])
277
self._add_commit_reparent_check_changed(tree, 'dir')
279
def test_last_modified_revision_after_reparent_file_changes(self):
280
# reparenting a file changes the last modified.
281
tree = self.make_branch_and_tree('.')
282
self.build_tree(['file'])
283
self._add_commit_reparent_check_changed(tree, 'file')
285
def test_last_modified_revision_after_reparent_link_changes(self):
286
# reparenting a link changes the last modified.
287
self.requireFeature(tests.SymlinkFeature)
288
tree = self.make_branch_and_tree('.')
289
os.symlink('target', 'link')
290
self._add_commit_reparent_check_changed(tree, 'link')
292
def _add_commit_change_check_changed(self, tree, name, changer):
293
tree.add([name], [name + 'id'])
294
rev1 = tree.commit('')
296
rev2 = tree.commit('')
297
tree1, tree2 = self._get_revtrees(tree, [rev1, rev2])
298
self.assertEqual(rev1, tree1.inventory[name + 'id'].revision)
299
self.assertEqual(rev2, tree2.inventory[name + 'id'].revision)
300
self.assertFileAncestry([rev1, rev2], tree, name)
302
def assertFileAncestry(self, ancestry, tree, name, alt_ancestry=None):
303
# all the changes that have occured should be in the ancestry
304
# (closest to a public per-file graph API we have today)
306
self.addCleanup(tree.unlock)
307
vw = tree.branch.repository.weave_store.get_weave(name + 'id',
308
tree.branch.repository.get_transaction())
309
result = vw.get_ancestry([ancestry[-1]])
310
if alt_ancestry is None:
311
self.assertEqual(ancestry, result)
313
self.assertSubset([tuple(result)],
314
[tuple(ancestry), tuple(alt_ancestry)])
316
def test_last_modified_revision_after_content_file_changes(self):
317
# altering a file changes the last modified.
318
tree = self.make_branch_and_tree('.')
319
self.build_tree(['file'])
321
tree.put_file_bytes_non_atomic('fileid', 'new content')
322
self._add_commit_change_check_changed(tree, 'file', change_file)
324
def test_last_modified_revision_after_content_link_changes(self):
325
# changing a link changes the last modified.
326
self.requireFeature(tests.SymlinkFeature)
327
tree = self.make_branch_and_tree('.')
328
os.symlink('target', 'link')
331
os.symlink('newtarget', 'link')
332
self._add_commit_change_check_changed(tree, 'link', change_link)
334
def _commit_sprout(self, tree, name):
335
tree.add([name], [name + 'id'])
336
rev_id = tree.commit('')
337
return rev_id, tree.bzrdir.sprout('t2').open_workingtree()
339
def _rename_in_tree(self, tree, name):
340
tree.rename_one(name, 'new_' + name)
341
return tree.commit('')
343
def _commit_sprout_rename_merge(self, tree1, name):
344
rev1, tree2 = self._commit_sprout(tree1, name)
345
# change both sides equally
346
rev2 = self._rename_in_tree(tree1, name)
347
rev3 = self._rename_in_tree(tree2, name)
348
tree1.merge_from_branch(tree2.branch)
349
rev4 = tree1.commit('')
350
tree3, = self._get_revtrees(tree1, [rev4])
351
self.assertEqual(rev4, tree3.inventory[name + 'id'].revision)
352
self.assertFileAncestry([rev1, rev2, rev3, rev4], tree1, name,
353
[rev1, rev3, rev2, rev4])
355
def test_last_modified_revision_after_merge_dir_changes(self):
356
# merge a dir changes the last modified.
357
tree1 = self.make_branch_and_tree('t1')
358
self.build_tree(['t1/dir/'])
359
self._commit_sprout_rename_merge(tree1, 'dir')
361
def test_last_modified_revision_after_merge_file_changes(self):
362
# merge a file changes the last modified.
363
tree1 = self.make_branch_and_tree('t1')
364
self.build_tree(['t1/file'])
365
self._commit_sprout_rename_merge(tree1, 'file')
367
def test_last_modified_revision_after_merge_link_changes(self):
368
# merge a link changes the last modified.
369
self.requireFeature(tests.SymlinkFeature)
370
tree1 = self.make_branch_and_tree('t1')
371
os.symlink('target', 't1/link')
372
self._commit_sprout_rename_merge(tree1, 'link')
374
def _commit_sprout_rename_merge_converged(self, tree1, name):
375
rev1, tree2 = self._commit_sprout(tree1, name)
376
# change on the other side to merge back
377
rev2 = self._rename_in_tree(tree2, name)
378
tree1.merge_from_branch(tree2.branch)
379
rev3 = tree1.commit('')
380
tree3, = self._get_revtrees(tree1, [rev2])
381
self.assertEqual(rev2, tree3.inventory[name + 'id'].revision)
382
self.assertFileAncestry([rev1, rev2], tree1, name)
384
def test_last_modified_revision_after_converged_merge_dir_changes(self):
385
# merge a dir changes the last modified.
386
tree1 = self.make_branch_and_tree('t1')
387
self.build_tree(['t1/dir/'])
388
self._commit_sprout_rename_merge_converged(tree1, 'dir')
390
def test_last_modified_revision_after_converged_merge_file_changes(self):
391
# merge a file changes the last modified.
392
tree1 = self.make_branch_and_tree('t1')
393
self.build_tree(['t1/file'])
394
self._commit_sprout_rename_merge_converged(tree1, 'file')
396
def test_last_modified_revision_after_converged_merge_link_changes(self):
397
# merge a link changes the last modified.
398
self.requireFeature(tests.SymlinkFeature)
399
tree1 = self.make_branch_and_tree('t1')
400
os.symlink('target', 't1/link')
401
self._commit_sprout_rename_merge_converged(tree1, 'link')
403
def make_dir(self, name):
404
self.build_tree([name + '/'])
406
def make_file(self, name):
407
self.build_tree([name])
409
def make_link(self, name):
410
self.requireFeature(tests.SymlinkFeature)
411
os.symlink('target', name)
413
def _check_kind_change(self, make_before, make_after):
414
tree = self.make_branch_and_tree('.')
421
if e.errno != EISDIR:
425
self._add_commit_change_check_changed(tree, path, change_kind)
427
def test_last_modified_dir_file(self):
428
self._check_kind_change(self.make_dir, self.make_file)
430
def test_last_modified_dir_link(self):
431
self._check_kind_change(self.make_dir, self.make_link)
433
def test_last_modified_link_file(self):
434
self._check_kind_change(self.make_link, self.make_file)
436
def test_last_modified_link_dir(self):
437
self._check_kind_change(self.make_link, self.make_dir)
439
def test_last_modified_file_dir(self):
440
self._check_kind_change(self.make_file, self.make_dir)
442
def test_last_modified_file_link(self):
443
self._check_kind_change(self.make_file, self.make_link)