490
517
other_tree.commit('modify all sample files and dirs.')
492
519
other_tree.unlock()
493
self.merge(other_tree.branch, this_tree)
520
this_tree.merge_from_branch(other_tree.branch)
494
521
reporter = CapturingReporter()
495
522
this_tree.commit('do the commit', reporter=reporter)
496
523
self.assertEqual([
524
('change', 'unchanged', ''),
497
525
('change', 'unchanged', 'dirtoleave'),
498
526
('change', 'unchanged', 'filetoleave'),
499
527
('change', 'modified', 'filetomodify'),
500
528
('change', 'added', 'newdir'),
501
529
('change', 'added', 'newfile'),
502
530
('renamed', 'renamed', 'dirtorename', 'renameddir'),
531
('renamed', 'renamed', 'filetorename', 'renamedfile'),
503
532
('renamed', 'renamed', 'dirtoreparent', 'renameddir/reparenteddir'),
504
533
('renamed', 'renamed', 'filetoreparent', 'renameddir/reparentedfile'),
505
('renamed', 'renamed', 'filetorename', 'renamedfile'),
506
534
('deleted', 'dirtoremove'),
507
535
('deleted', 'filetoremove'),
539
def test_commit_removals_respects_filespec(self):
540
"""Commit respects the specified_files for removals."""
541
tree = self.make_branch_and_tree('.')
542
self.build_tree(['a', 'b'])
544
tree.commit('added a, b')
545
tree.remove(['a', 'b'])
546
tree.commit('removed a', specific_files='a')
547
basis = tree.basis_tree()
550
self.assertIs(None, basis.path2id('a'))
551
self.assertFalse(basis.path2id('b') is None)
555
def test_commit_saves_1ms_timestamp(self):
556
"""Passing in a timestamp is saved with 1ms resolution"""
557
tree = self.make_branch_and_tree('.')
558
self.build_tree(['a'])
560
tree.commit('added a', timestamp=1153248633.4186721, timezone=0,
563
rev = tree.branch.repository.get_revision('a1')
564
self.assertEqual(1153248633.419, rev.timestamp)
566
def test_commit_has_1ms_resolution(self):
567
"""Allowing commit to generate the timestamp also has 1ms resolution"""
568
tree = self.make_branch_and_tree('.')
569
self.build_tree(['a'])
571
tree.commit('added a', rev_id='a1')
573
rev = tree.branch.repository.get_revision('a1')
574
timestamp = rev.timestamp
575
timestamp_1ms = round(timestamp, 3)
576
self.assertEqual(timestamp_1ms, timestamp)
578
def assertBasisTreeKind(self, kind, tree, file_id):
579
basis = tree.basis_tree()
582
self.assertEqual(kind, basis.kind(file_id))
586
def test_commit_kind_changes(self):
587
if not osutils.has_symlinks():
588
raise tests.TestSkipped('Test requires symlink support')
589
tree = self.make_branch_and_tree('.')
590
os.symlink('target', 'name')
591
tree.add('name', 'a-file-id')
592
tree.commit('Added a symlink')
593
self.assertBasisTreeKind('symlink', tree, 'a-file-id')
596
self.build_tree(['name'])
597
tree.commit('Changed symlink to file')
598
self.assertBasisTreeKind('file', tree, 'a-file-id')
601
os.symlink('target', 'name')
602
tree.commit('file to symlink')
603
self.assertBasisTreeKind('symlink', tree, 'a-file-id')
607
tree.commit('symlink to directory')
608
self.assertBasisTreeKind('directory', tree, 'a-file-id')
611
os.symlink('target', 'name')
612
tree.commit('directory to symlink')
613
self.assertBasisTreeKind('symlink', tree, 'a-file-id')
615
# prepare for directory <-> file tests
618
tree.commit('symlink to directory')
619
self.assertBasisTreeKind('directory', tree, 'a-file-id')
622
self.build_tree(['name'])
623
tree.commit('Changed directory to file')
624
self.assertBasisTreeKind('file', tree, 'a-file-id')
628
tree.commit('file to directory')
629
self.assertBasisTreeKind('directory', tree, 'a-file-id')
631
def test_commit_unversioned_specified(self):
632
"""Commit should raise if specified files isn't in basis or worktree"""
633
tree = self.make_branch_and_tree('.')
634
self.assertRaises(errors.PathsNotVersionedError, tree.commit,
635
'message', specific_files=['bogus'])
637
class Callback(object):
639
def __init__(self, message, testcase):
641
self.message = message
642
self.testcase = testcase
644
def __call__(self, commit_obj):
646
self.testcase.assertTrue(isinstance(commit_obj, Commit))
649
def test_commit_callback(self):
650
"""Commit should invoke a callback to get the message"""
652
tree = self.make_branch_and_tree('.')
656
self.assertTrue(isinstance(e, BzrError))
657
self.assertEqual('The message or message_callback keyword'
658
' parameter is required for commit().', str(e))
660
self.fail('exception not raised')
661
cb = self.Callback(u'commit 1', self)
662
tree.commit(message_callback=cb)
663
self.assertTrue(cb.called)
664
repository = tree.branch.repository
665
message = repository.get_revision(tree.last_revision()).message
666
self.assertEqual('commit 1', message)
668
def test_no_callback_pointless(self):
669
"""Callback should not be invoked for pointless commit"""
670
tree = self.make_branch_and_tree('.')
671
cb = self.Callback(u'commit 2', self)
672
self.assertRaises(PointlessCommit, tree.commit, message_callback=cb,
673
allow_pointless=False)
674
self.assertFalse(cb.called)
676
def test_no_callback_netfailure(self):
677
"""Callback should not be invoked if connectivity fails"""
678
tree = self.make_branch_and_tree('.')
679
cb = self.Callback(u'commit 2', self)
680
repository = tree.branch.repository
681
# simulate network failure
682
def raise_(self, arg, arg2):
683
raise errors.NoSuchFile('foo')
684
repository.add_inventory = raise_
685
self.assertRaises(errors.NoSuchFile, tree.commit, message_callback=cb)
686
self.assertFalse(cb.called)
688
def test_selected_file_merge_commit(self):
689
"""Ensure the correct error is raised"""
690
tree = self.make_branch_and_tree('foo')
691
# pending merge would turn into a left parent
692
tree.commit('commit 1')
693
tree.add_parent_tree_id('example')
694
self.build_tree(['foo/bar', 'foo/baz'])
695
tree.add(['bar', 'baz'])
696
err = self.assertRaises(errors.CannotCommitSelectedFileMerge,
697
tree.commit, 'commit 2', specific_files=['bar', 'baz'])
698
self.assertEqual(['bar', 'baz'], err.files)
699
self.assertEqual('Selected-file commit of merges is not supported'
700
' yet: files bar, baz', str(err))
702
def test_commit_ordering(self):
703
"""Test of corner-case commit ordering error"""
704
tree = self.make_branch_and_tree('.')
705
self.build_tree(['a/', 'a/z/', 'a/c/', 'a/z/x', 'a/z/y'])
706
tree.add(['a/', 'a/z/', 'a/c/', 'a/z/x', 'a/z/y'])
708
self.build_tree(['a/c/d/'])
710
tree.rename_one('a/z/x', 'a/c/d/x')
711
tree.commit('test', specific_files=['a/z/y'])
713
def test_commit_no_author(self):
714
"""The default kwarg author in MutableTree.commit should not add
715
the 'author' revision property.
717
tree = self.make_branch_and_tree('foo')
718
rev_id = tree.commit('commit 1')
719
rev = tree.branch.repository.get_revision(rev_id)
720
self.assertFalse('author' in rev.properties)
722
def test_commit_author(self):
723
"""Passing a non-empty author kwarg to MutableTree.commit should add
724
the 'author' revision property.
726
tree = self.make_branch_and_tree('foo')
727
rev_id = tree.commit('commit 1', author='John Doe <jdoe@example.com>')
728
rev = tree.branch.repository.get_revision(rev_id)
729
self.assertEqual('John Doe <jdoe@example.com>',
730
rev.properties['author'])