~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_commit.py

  • Committer: John Arbash Meinel
  • Date: 2006-09-20 14:51:03 UTC
  • mfrom: (0.8.23 version_info)
  • mto: This revision was merged to the branch mainline in revision 2028.
  • Revision ID: john@arbash-meinel.com-20060920145103-02725c6d6c886040
[merge] version-info plugin, and cleanup for layout in bzr

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005-2011 Canonical Ltd
 
1
# Copyright (C) 2005, 2006 by Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
12
12
#
13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
 
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
17
17
 
18
18
import os
19
19
 
20
20
import bzrlib
21
 
from bzrlib import (
22
 
    bzrdir,
23
 
    errors,
24
 
    )
 
21
from bzrlib.tests import TestCaseWithTransport
25
22
from bzrlib.branch import Branch
26
 
from bzrlib.bzrdir import BzrDirMetaFormat1
 
23
from bzrlib.bzrdir import BzrDir, BzrDirMetaFormat1
 
24
from bzrlib.workingtree import WorkingTree
27
25
from bzrlib.commit import Commit, NullCommitReporter
28
26
from bzrlib.config import BranchConfig
29
 
from bzrlib.errors import (
30
 
    PointlessCommit,
31
 
    BzrError,
32
 
    SigningFailed,
33
 
    LockContention,
34
 
    )
35
 
from bzrlib.tests import (
36
 
    SymlinkFeature,
37
 
    TestCaseWithTransport,
38
 
    test_foreign,
39
 
    )
40
 
from bzrlib.tests.matchers import MatchesAncestry
 
27
from bzrlib.errors import (PointlessCommit, BzrError, SigningFailed, 
 
28
                           LockContention)
41
29
 
42
30
 
43
31
# TODO: Test commit with some added, and added-but-missing files
76
64
    def renamed(self, change, old_path, new_path):
77
65
        self.calls.append(('renamed', change, old_path, new_path))
78
66
 
79
 
    def is_verbose(self):
80
 
        return True
81
 
 
82
67
 
83
68
class TestCommit(TestCaseWithTransport):
84
69
 
101
86
        eq(rev.message, 'add hello')
102
87
 
103
88
        tree1 = b.repository.revision_tree(rh[0])
104
 
        tree1.lock_read()
105
89
        text = tree1.get_file_text(file_id)
106
 
        tree1.unlock()
107
 
        self.assertEqual('hello world', text)
 
90
        eq(text, 'hello world')
108
91
 
109
92
        tree2 = b.repository.revision_tree(rh[1])
110
 
        tree2.lock_read()
111
 
        text = tree2.get_file_text(file_id)
112
 
        tree2.unlock()
113
 
        self.assertEqual('version 2', text)
114
 
 
115
 
    def test_commit_lossy_native(self):
116
 
        """Attempt a lossy commit to a native branch."""
117
 
        wt = self.make_branch_and_tree('.')
118
 
        b = wt.branch
119
 
        file('hello', 'w').write('hello world')
120
 
        wt.add('hello')
121
 
        revid = wt.commit(message='add hello', rev_id='revid', lossy=True)
122
 
        self.assertEquals('revid', revid)
123
 
 
124
 
    def test_commit_lossy_foreign(self):
125
 
        """Attempt a lossy commit to a foreign branch."""
126
 
        test_foreign.register_dummy_foreign_for_test(self)
127
 
        wt = self.make_branch_and_tree('.',
128
 
            format=test_foreign.DummyForeignVcsDirFormat())
129
 
        b = wt.branch
130
 
        file('hello', 'w').write('hello world')
131
 
        wt.add('hello')
132
 
        revid = wt.commit(message='add hello', lossy=True,
133
 
            timestamp=1302659388, timezone=0)
134
 
        self.assertEquals('dummy-v1:1302659388.0-0-UNKNOWN', revid)
135
 
 
136
 
    def test_commit_bound_lossy_foreign(self):
137
 
        """Attempt a lossy commit to a bzr branch bound to a foreign branch."""
138
 
        test_foreign.register_dummy_foreign_for_test(self)
139
 
        foreign_branch = self.make_branch('foreign',
140
 
            format=test_foreign.DummyForeignVcsDirFormat())
141
 
        wt = foreign_branch.create_checkout("local")
142
 
        b = wt.branch
143
 
        file('local/hello', 'w').write('hello world')
144
 
        wt.add('hello')
145
 
        revid = wt.commit(message='add hello', lossy=True,
146
 
            timestamp=1302659388, timezone=0)
147
 
        self.assertEquals('dummy-v1:1302659388.0-0-0', revid)
148
 
        self.assertEquals('dummy-v1:1302659388.0-0-0',
149
 
            foreign_branch.last_revision())
150
 
        self.assertEquals('dummy-v1:1302659388.0-0-0',
151
 
            wt.branch.last_revision())
152
 
 
153
 
    def test_missing_commit(self):
154
 
        """Test a commit with a missing file"""
 
93
        eq(tree2.get_file_text(file_id), 'version 2')
 
94
 
 
95
    def test_delete_commit(self):
 
96
        """Test a commit with a deleted file"""
155
97
        wt = self.make_branch_and_tree('.')
156
98
        b = wt.branch
157
99
        file('hello', 'w').write('hello world')
164
106
        tree = b.repository.revision_tree('rev2')
165
107
        self.assertFalse(tree.has_id('hello-id'))
166
108
 
167
 
    def test_partial_commit_move(self):
168
 
        """Test a partial commit where a file was renamed but not committed.
169
 
 
170
 
        https://bugs.launchpad.net/bzr/+bug/83039
171
 
 
172
 
        If not handled properly, commit will try to snapshot
173
 
        dialog.py with olive/ as a parent, while
174
 
        olive/ has not been snapshotted yet.
175
 
        """
176
 
        wt = self.make_branch_and_tree('.')
177
 
        b = wt.branch
178
 
        self.build_tree(['annotate/', 'annotate/foo.py',
179
 
                         'olive/', 'olive/dialog.py'
180
 
                        ])
181
 
        wt.add(['annotate', 'olive', 'annotate/foo.py', 'olive/dialog.py'])
182
 
        wt.commit(message='add files')
183
 
        wt.rename_one("olive/dialog.py", "aaa")
184
 
        self.build_tree_contents([('annotate/foo.py', 'modified\n')])
185
 
        wt.commit('renamed hello', specific_files=["annotate"])
186
 
 
187
109
    def test_pointless_commit(self):
188
110
        """Commit refuses unless there are changes or it's forced."""
189
111
        wt = self.make_branch_and_tree('.')
197
119
                          message='fails',
198
120
                          allow_pointless=False)
199
121
        self.assertEquals(b.revno(), 1)
200
 
 
 
122
        
201
123
    def test_commit_empty(self):
202
124
        """Commiting an empty tree works."""
203
125
        wt = self.make_branch_and_tree('.')
220
142
              ['hello-id', 'buongia-id'])
221
143
        wt.commit(message='add files',
222
144
                 rev_id='test@rev-1')
223
 
 
 
145
        
224
146
        os.remove('hello')
225
147
        file('buongia', 'w').write('new text')
226
148
        wt.commit(message='update text',
237
159
        eq(b.revno(), 3)
238
160
 
239
161
        tree2 = b.repository.revision_tree('test@rev-2')
240
 
        tree2.lock_read()
241
 
        self.addCleanup(tree2.unlock)
242
162
        self.assertTrue(tree2.has_filename('hello'))
243
163
        self.assertEquals(tree2.get_file_text('hello-id'), 'hello')
244
164
        self.assertEquals(tree2.get_file_text('buongia-id'), 'new text')
245
 
 
 
165
        
246
166
        tree3 = b.repository.revision_tree('test@rev-3')
247
 
        tree3.lock_read()
248
 
        self.addCleanup(tree3.unlock)
249
167
        self.assertFalse(tree3.has_filename('hello'))
250
168
        self.assertEquals(tree3.get_file_text('buongia-id'), 'new text')
251
169
 
262
180
 
263
181
        eq = self.assertEquals
264
182
        tree1 = b.repository.revision_tree('test@rev-1')
265
 
        tree1.lock_read()
266
 
        self.addCleanup(tree1.unlock)
267
183
        eq(tree1.id2path('hello-id'), 'hello')
268
184
        eq(tree1.get_file_text('hello-id'), 'contents of hello\n')
269
185
        self.assertFalse(tree1.has_filename('fruity'))
270
 
        self.check_tree_shape(tree1, ['hello'])
271
 
        eq(tree1.get_file_revision('hello-id'), 'test@rev-1')
 
186
        self.check_inventory_shape(tree1.inventory, ['hello'])
 
187
        ie = tree1.inventory['hello-id']
 
188
        eq(ie.revision, 'test@rev-1')
272
189
 
273
190
        tree2 = b.repository.revision_tree('test@rev-2')
274
 
        tree2.lock_read()
275
 
        self.addCleanup(tree2.unlock)
276
191
        eq(tree2.id2path('hello-id'), 'fruity')
277
192
        eq(tree2.get_file_text('hello-id'), 'contents of hello\n')
278
 
        self.check_tree_shape(tree2, ['fruity'])
279
 
        eq(tree2.get_file_revision('hello-id'), 'test@rev-2')
 
193
        self.check_inventory_shape(tree2.inventory, ['fruity'])
 
194
        ie = tree2.inventory['hello-id']
 
195
        eq(ie.revision, 'test@rev-2')
280
196
 
281
197
    def test_reused_rev_id(self):
282
198
        """Test that a revision id cannot be reused in a branch"""
301
217
        wt.move(['hello'], 'a')
302
218
        r2 = 'test@rev-2'
303
219
        wt.commit('two', rev_id=r2, allow_pointless=False)
304
 
        wt.lock_read()
305
 
        try:
306
 
            self.check_tree_shape(wt, ['a/', 'a/hello', 'b/'])
307
 
        finally:
308
 
            wt.unlock()
 
220
        self.check_inventory_shape(wt.read_working_inventory(),
 
221
                                   ['a', 'a/hello', 'b'])
309
222
 
310
223
        wt.move(['b'], 'a')
311
224
        r3 = 'test@rev-3'
312
225
        wt.commit('three', rev_id=r3, allow_pointless=False)
313
 
        wt.lock_read()
314
 
        try:
315
 
            self.check_tree_shape(wt,
316
 
                                       ['a/', 'a/hello', 'a/b/'])
317
 
            self.check_tree_shape(b.repository.revision_tree(r3),
318
 
                                       ['a/', 'a/hello', 'a/b/'])
319
 
        finally:
320
 
            wt.unlock()
 
226
        self.check_inventory_shape(wt.read_working_inventory(),
 
227
                                   ['a', 'a/hello', 'a/b'])
 
228
        self.check_inventory_shape(b.repository.get_revision_inventory(r3),
 
229
                                   ['a', 'a/hello', 'a/b'])
321
230
 
322
231
        wt.move(['a/hello'], 'a/b')
323
232
        r4 = 'test@rev-4'
324
233
        wt.commit('four', rev_id=r4, allow_pointless=False)
325
 
        wt.lock_read()
326
 
        try:
327
 
            self.check_tree_shape(wt, ['a/', 'a/b/hello', 'a/b/'])
328
 
        finally:
329
 
            wt.unlock()
 
234
        self.check_inventory_shape(wt.read_working_inventory(),
 
235
                                   ['a', 'a/b/hello', 'a/b'])
330
236
 
331
 
        inv = b.repository.get_inventory(r4)
 
237
        inv = b.repository.get_revision_inventory(r4)
332
238
        eq(inv['hello-id'].revision, r4)
333
239
        eq(inv['a-id'].revision, r1)
334
240
        eq(inv['b-id'].revision, r3)
335
 
 
 
241
        
336
242
    def test_removed_commit(self):
337
243
        """Commit with a removed file"""
338
244
        wt = self.make_branch_and_tree('.')
362
268
        eq = self.assertEquals
363
269
        eq(b.revision_history(), rev_ids)
364
270
        for i in range(4):
365
 
            self.assertThat(rev_ids[:i+1],
366
 
                MatchesAncestry(b.repository, rev_ids[i]))
 
271
            anc = b.repository.get_ancestry(rev_ids[i])
 
272
            eq(anc, [None] + rev_ids[:i+1])
367
273
 
368
274
    def test_commit_new_subdir_child_selective(self):
369
275
        wt = self.make_branch_and_tree('.')
392
298
    def test_strict_commit_without_unknowns(self):
393
299
        """Try and commit with no unknown files and strict = True,
394
300
        should work."""
 
301
        from bzrlib.errors import StrictCommitFailed
395
302
        wt = self.make_branch_and_tree('.')
396
303
        b = wt.branch
397
304
        file('hello', 'w').write('hello world')
423
330
        wt = self.make_branch_and_tree('.')
424
331
        branch = wt.branch
425
332
        wt.commit("base", allow_pointless=True, rev_id='A')
426
 
        self.assertFalse(branch.repository.has_signature_for_revision_id('A'))
 
333
        self.failIf(branch.repository.has_signature_for_revision_id('A'))
427
334
        try:
428
335
            from bzrlib.testament import Testament
429
336
            # monkey patch gpg signing mechanism
432
339
                                                      allow_pointless=True,
433
340
                                                      rev_id='B',
434
341
                                                      working_tree=wt)
435
 
            def sign(text):
436
 
                return bzrlib.gpg.LoopbackGPGStrategy(None).sign(text)
437
 
            self.assertEqual(sign(Testament.from_revision(branch.repository,
438
 
                             'B').as_short_text()),
 
342
            self.assertEqual(Testament.from_revision(branch.repository,
 
343
                             'B').as_short_text(),
439
344
                             branch.repository.get_signature_text('B'))
440
345
        finally:
441
346
            bzrlib.gpg.GPGStrategy = oldstrategy
447
352
        wt = self.make_branch_and_tree('.')
448
353
        branch = wt.branch
449
354
        wt.commit("base", allow_pointless=True, rev_id='A')
450
 
        self.assertFalse(branch.repository.has_signature_for_revision_id('A'))
 
355
        self.failIf(branch.repository.has_signature_for_revision_id('A'))
451
356
        try:
 
357
            from bzrlib.testament import Testament
452
358
            # monkey patch gpg signing mechanism
453
359
            bzrlib.gpg.GPGStrategy = bzrlib.gpg.DisabledGPGStrategy
454
360
            config = MustSignConfig(branch)
460
366
                              working_tree=wt)
461
367
            branch = Branch.open(self.get_url('.'))
462
368
            self.assertEqual(branch.revision_history(), ['A'])
463
 
            self.assertFalse(branch.repository.has_revision('B'))
 
369
            self.failIf(branch.repository.has_revision('B'))
464
370
        finally:
465
371
            bzrlib.gpg.GPGStrategy = oldstrategy
466
372
 
521
427
        other_bzrdir = master_branch.bzrdir.sprout('other')
522
428
        other_tree = other_bzrdir.open_workingtree()
523
429
 
524
 
        # do a commit to the other branch changing the content file so
 
430
        # do a commit to the the other branch changing the content file so
525
431
        # that our commit after merging will have a merged revision in the
526
432
        # content file history.
527
433
        self.build_tree_contents([('other/content_file', 'change in other\n')])
538
444
        bound_tree.commit(message='commit of merge in bound tree')
539
445
 
540
446
    def test_commit_reporting_after_merge(self):
541
 
        # when doing a commit of a merge, the reporter needs to still
 
447
        # when doing a commit of a merge, the reporter needs to still 
542
448
        # be called for each item that is added/removed/deleted.
543
449
        this_tree = self.make_branch_and_tree('this')
544
450
        # we need a bunch of files and dirs, to perform one action on each.
587
493
        this_tree.merge_from_branch(other_tree.branch)
588
494
        reporter = CapturingReporter()
589
495
        this_tree.commit('do the commit', reporter=reporter)
590
 
        expected = set([
 
496
        self.assertEqual([
 
497
            ('change', 'unchanged', ''),
 
498
            ('change', 'unchanged', 'dirtoleave'),
 
499
            ('change', 'unchanged', 'filetoleave'),
591
500
            ('change', 'modified', 'filetomodify'),
592
501
            ('change', 'added', 'newdir'),
593
502
            ('change', 'added', 'newfile'),
594
503
            ('renamed', 'renamed', 'dirtorename', 'renameddir'),
595
 
            ('renamed', 'renamed', 'filetorename', 'renamedfile'),
596
504
            ('renamed', 'renamed', 'dirtoreparent', 'renameddir/reparenteddir'),
597
505
            ('renamed', 'renamed', 'filetoreparent', 'renameddir/reparentedfile'),
 
506
            ('renamed', 'renamed', 'filetorename', 'renamedfile'),
598
507
            ('deleted', 'dirtoremove'),
599
508
            ('deleted', 'filetoremove'),
600
 
            ])
601
 
        result = set(reporter.calls)
602
 
        missing = expected - result
603
 
        new = result - expected
604
 
        self.assertEqual((set(), set()), (missing, new))
 
509
            ],
 
510
            reporter.calls)
605
511
 
606
512
    def test_commit_removals_respects_filespec(self):
607
513
        """Commit respects the specified_files for removals."""
611
517
        tree.commit('added a, b')
612
518
        tree.remove(['a', 'b'])
613
519
        tree.commit('removed a', specific_files='a')
614
 
        basis = tree.basis_tree()
615
 
        tree.lock_read()
616
 
        try:
617
 
            self.assertIs(None, basis.path2id('a'))
618
 
            self.assertFalse(basis.path2id('b') is None)
619
 
        finally:
620
 
            tree.unlock()
 
520
        basis = tree.basis_tree().inventory
 
521
        self.assertIs(None, basis.path2id('a'))
 
522
        self.assertFalse(basis.path2id('b') is None)
621
523
 
622
524
    def test_commit_saves_1ms_timestamp(self):
623
525
        """Passing in a timestamp is saved with 1ms resolution"""
641
543
        timestamp = rev.timestamp
642
544
        timestamp_1ms = round(timestamp, 3)
643
545
        self.assertEqual(timestamp_1ms, timestamp)
644
 
 
645
 
    def assertBasisTreeKind(self, kind, tree, file_id):
646
 
        basis = tree.basis_tree()
647
 
        basis.lock_read()
648
 
        try:
649
 
            self.assertEqual(kind, basis.kind(file_id))
650
 
        finally:
651
 
            basis.unlock()
652
 
 
653
 
    def test_commit_kind_changes(self):
654
 
        self.requireFeature(SymlinkFeature)
655
 
        tree = self.make_branch_and_tree('.')
656
 
        os.symlink('target', 'name')
657
 
        tree.add('name', 'a-file-id')
658
 
        tree.commit('Added a symlink')
659
 
        self.assertBasisTreeKind('symlink', tree, 'a-file-id')
660
 
 
661
 
        os.unlink('name')
662
 
        self.build_tree(['name'])
663
 
        tree.commit('Changed symlink to file')
664
 
        self.assertBasisTreeKind('file', tree, 'a-file-id')
665
 
 
666
 
        os.unlink('name')
667
 
        os.symlink('target', 'name')
668
 
        tree.commit('file to symlink')
669
 
        self.assertBasisTreeKind('symlink', tree, 'a-file-id')
670
 
 
671
 
        os.unlink('name')
672
 
        os.mkdir('name')
673
 
        tree.commit('symlink to directory')
674
 
        self.assertBasisTreeKind('directory', tree, 'a-file-id')
675
 
 
676
 
        os.rmdir('name')
677
 
        os.symlink('target', 'name')
678
 
        tree.commit('directory to symlink')
679
 
        self.assertBasisTreeKind('symlink', tree, 'a-file-id')
680
 
 
681
 
        # prepare for directory <-> file tests
682
 
        os.unlink('name')
683
 
        os.mkdir('name')
684
 
        tree.commit('symlink to directory')
685
 
        self.assertBasisTreeKind('directory', tree, 'a-file-id')
686
 
 
687
 
        os.rmdir('name')
688
 
        self.build_tree(['name'])
689
 
        tree.commit('Changed directory to file')
690
 
        self.assertBasisTreeKind('file', tree, 'a-file-id')
691
 
 
692
 
        os.unlink('name')
693
 
        os.mkdir('name')
694
 
        tree.commit('file to directory')
695
 
        self.assertBasisTreeKind('directory', tree, 'a-file-id')
696
 
 
697
 
    def test_commit_unversioned_specified(self):
698
 
        """Commit should raise if specified files isn't in basis or worktree"""
699
 
        tree = self.make_branch_and_tree('.')
700
 
        self.assertRaises(errors.PathsNotVersionedError, tree.commit,
701
 
                          'message', specific_files=['bogus'])
702
 
 
703
 
    class Callback(object):
704
 
 
705
 
        def __init__(self, message, testcase):
706
 
            self.called = False
707
 
            self.message = message
708
 
            self.testcase = testcase
709
 
 
710
 
        def __call__(self, commit_obj):
711
 
            self.called = True
712
 
            self.testcase.assertTrue(isinstance(commit_obj, Commit))
713
 
            return self.message
714
 
 
715
 
    def test_commit_callback(self):
716
 
        """Commit should invoke a callback to get the message"""
717
 
 
718
 
        tree = self.make_branch_and_tree('.')
719
 
        try:
720
 
            tree.commit()
721
 
        except Exception, e:
722
 
            self.assertTrue(isinstance(e, BzrError))
723
 
            self.assertEqual('The message or message_callback keyword'
724
 
                             ' parameter is required for commit().', str(e))
725
 
        else:
726
 
            self.fail('exception not raised')
727
 
        cb = self.Callback(u'commit 1', self)
728
 
        tree.commit(message_callback=cb)
729
 
        self.assertTrue(cb.called)
730
 
        repository = tree.branch.repository
731
 
        message = repository.get_revision(tree.last_revision()).message
732
 
        self.assertEqual('commit 1', message)
733
 
 
734
 
    def test_no_callback_pointless(self):
735
 
        """Callback should not be invoked for pointless commit"""
736
 
        tree = self.make_branch_and_tree('.')
737
 
        cb = self.Callback(u'commit 2', self)
738
 
        self.assertRaises(PointlessCommit, tree.commit, message_callback=cb,
739
 
                          allow_pointless=False)
740
 
        self.assertFalse(cb.called)
741
 
 
742
 
    def test_no_callback_netfailure(self):
743
 
        """Callback should not be invoked if connectivity fails"""
744
 
        tree = self.make_branch_and_tree('.')
745
 
        cb = self.Callback(u'commit 2', self)
746
 
        repository = tree.branch.repository
747
 
        # simulate network failure
748
 
        def raise_(self, arg, arg2, arg3=None, arg4=None):
749
 
            raise errors.NoSuchFile('foo')
750
 
        repository.add_inventory = raise_
751
 
        repository.add_inventory_by_delta = raise_
752
 
        self.assertRaises(errors.NoSuchFile, tree.commit, message_callback=cb)
753
 
        self.assertFalse(cb.called)
754
 
 
755
 
    def test_selected_file_merge_commit(self):
756
 
        """Ensure the correct error is raised"""
757
 
        tree = self.make_branch_and_tree('foo')
758
 
        # pending merge would turn into a left parent
759
 
        tree.commit('commit 1')
760
 
        tree.add_parent_tree_id('example')
761
 
        self.build_tree(['foo/bar', 'foo/baz'])
762
 
        tree.add(['bar', 'baz'])
763
 
        err = self.assertRaises(errors.CannotCommitSelectedFileMerge,
764
 
            tree.commit, 'commit 2', specific_files=['bar', 'baz'])
765
 
        self.assertEqual(['bar', 'baz'], err.files)
766
 
        self.assertEqual('Selected-file commit of merges is not supported'
767
 
                         ' yet: files bar, baz', str(err))
768
 
 
769
 
    def test_commit_ordering(self):
770
 
        """Test of corner-case commit ordering error"""
771
 
        tree = self.make_branch_and_tree('.')
772
 
        self.build_tree(['a/', 'a/z/', 'a/c/', 'a/z/x', 'a/z/y'])
773
 
        tree.add(['a/', 'a/z/', 'a/c/', 'a/z/x', 'a/z/y'])
774
 
        tree.commit('setup')
775
 
        self.build_tree(['a/c/d/'])
776
 
        tree.add('a/c/d')
777
 
        tree.rename_one('a/z/x', 'a/c/d/x')
778
 
        tree.commit('test', specific_files=['a/z/y'])
779
 
 
780
 
    def test_commit_no_author(self):
781
 
        """The default kwarg author in MutableTree.commit should not add
782
 
        the 'author' revision property.
783
 
        """
784
 
        tree = self.make_branch_and_tree('foo')
785
 
        rev_id = tree.commit('commit 1')
786
 
        rev = tree.branch.repository.get_revision(rev_id)
787
 
        self.assertFalse('author' in rev.properties)
788
 
        self.assertFalse('authors' in rev.properties)
789
 
 
790
 
    def test_commit_author(self):
791
 
        """Passing a non-empty author kwarg to MutableTree.commit should add
792
 
        the 'author' revision property.
793
 
        """
794
 
        tree = self.make_branch_and_tree('foo')
795
 
        rev_id = self.callDeprecated(['The parameter author was '
796
 
                'deprecated in version 1.13. Use authors instead'],
797
 
                tree.commit, 'commit 1', author='John Doe <jdoe@example.com>')
798
 
        rev = tree.branch.repository.get_revision(rev_id)
799
 
        self.assertEqual('John Doe <jdoe@example.com>',
800
 
                         rev.properties['authors'])
801
 
        self.assertFalse('author' in rev.properties)
802
 
 
803
 
    def test_commit_empty_authors_list(self):
804
 
        """Passing an empty list to authors shouldn't add the property."""
805
 
        tree = self.make_branch_and_tree('foo')
806
 
        rev_id = tree.commit('commit 1', authors=[])
807
 
        rev = tree.branch.repository.get_revision(rev_id)
808
 
        self.assertFalse('author' in rev.properties)
809
 
        self.assertFalse('authors' in rev.properties)
810
 
 
811
 
    def test_multiple_authors(self):
812
 
        tree = self.make_branch_and_tree('foo')
813
 
        rev_id = tree.commit('commit 1',
814
 
                authors=['John Doe <jdoe@example.com>',
815
 
                         'Jane Rey <jrey@example.com>'])
816
 
        rev = tree.branch.repository.get_revision(rev_id)
817
 
        self.assertEqual('John Doe <jdoe@example.com>\n'
818
 
                'Jane Rey <jrey@example.com>', rev.properties['authors'])
819
 
        self.assertFalse('author' in rev.properties)
820
 
 
821
 
    def test_author_and_authors_incompatible(self):
822
 
        tree = self.make_branch_and_tree('foo')
823
 
        self.assertRaises(AssertionError, tree.commit, 'commit 1',
824
 
                authors=['John Doe <jdoe@example.com>',
825
 
                         'Jane Rey <jrey@example.com>'],
826
 
                author="Jack Me <jme@example.com>")
827
 
 
828
 
    def test_author_with_newline_rejected(self):
829
 
        tree = self.make_branch_and_tree('foo')
830
 
        self.assertRaises(AssertionError, tree.commit, 'commit 1',
831
 
                authors=['John\nDoe <jdoe@example.com>'])
832
 
 
833
 
    def test_commit_with_checkout_and_branch_sharing_repo(self):
834
 
        repo = self.make_repository('repo', shared=True)
835
 
        # make_branch_and_tree ignores shared repos
836
 
        branch = bzrdir.BzrDir.create_branch_convenience('repo/branch')
837
 
        tree2 = branch.create_checkout('repo/tree2')
838
 
        tree2.commit('message', rev_id='rev1')
839
 
        self.assertTrue(tree2.branch.repository.has_revision('rev1'))