~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_commit.py

(vila) Fix test failures blocking package builds. (Vincent Ladeuil)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006, 2008 Canonical Ltd
 
1
# Copyright (C) 2005-2011 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
17
17
 
18
18
import os
19
19
 
20
20
import bzrlib
21
21
from bzrlib import (
22
 
    bzrdir,
 
22
    config,
 
23
    controldir,
23
24
    errors,
24
 
    lockdir,
25
 
    osutils,
26
 
    tests,
27
25
    )
28
26
from bzrlib.branch import Branch
29
 
from bzrlib.bzrdir import BzrDir, BzrDirMetaFormat1
 
27
from bzrlib.bzrdir import BzrDirMetaFormat1
30
28
from bzrlib.commit import Commit, NullCommitReporter
31
 
from bzrlib.config import BranchConfig
32
 
from bzrlib.errors import (PointlessCommit, BzrError, SigningFailed, 
33
 
                           LockContention)
34
 
from bzrlib.tests import SymlinkFeature, TestCaseWithTransport
35
 
from bzrlib.workingtree import WorkingTree
 
29
from bzrlib.errors import (
 
30
    PointlessCommit,
 
31
    BzrError,
 
32
    SigningFailed,
 
33
    LockContention,
 
34
    )
 
35
from bzrlib.tests import (
 
36
    TestCaseWithTransport,
 
37
    test_foreign,
 
38
    )
 
39
from bzrlib.tests.features import (
 
40
    SymlinkFeature,
 
41
    )
 
42
from bzrlib.tests.matchers import MatchesAncestry
36
43
 
37
44
 
38
45
# TODO: Test commit with some added, and added-but-missing files
39
46
 
40
 
class MustSignConfig(BranchConfig):
41
 
 
42
 
    def signature_needed(self):
43
 
        return True
44
 
 
45
 
    def gpg_signing_command(self):
46
 
        return ['cat', '-']
47
 
 
48
 
 
49
 
class BranchWithHooks(BranchConfig):
50
 
 
51
 
    def post_commit(self):
52
 
        return "bzrlib.ahook bzrlib.ahook"
 
47
class MustSignConfig(config.MemoryStack):
 
48
 
 
49
    def __init__(self):
 
50
        super(MustSignConfig, self).__init__('''
 
51
gpg_signing_command=cat -
 
52
create_signatures=always
 
53
''')
53
54
 
54
55
 
55
56
class CapturingReporter(NullCommitReporter):
81
82
        """Commit and check two versions of a single file."""
82
83
        wt = self.make_branch_and_tree('.')
83
84
        b = wt.branch
84
 
        file('hello', 'w').write('hello world')
 
85
        with file('hello', 'w') as f: f.write('hello world')
85
86
        wt.add('hello')
86
 
        wt.commit(message='add hello')
 
87
        rev1 = wt.commit(message='add hello')
87
88
        file_id = wt.path2id('hello')
88
89
 
89
 
        file('hello', 'w').write('version 2')
90
 
        wt.commit(message='commit 2')
 
90
        with file('hello', 'w') as f: f.write('version 2')
 
91
        rev2 = wt.commit(message='commit 2')
91
92
 
92
93
        eq = self.assertEquals
93
94
        eq(b.revno(), 2)
94
 
        rh = b.revision_history()
95
 
        rev = b.repository.get_revision(rh[0])
 
95
        rev = b.repository.get_revision(rev1)
96
96
        eq(rev.message, 'add hello')
97
97
 
98
 
        tree1 = b.repository.revision_tree(rh[0])
 
98
        tree1 = b.repository.revision_tree(rev1)
99
99
        tree1.lock_read()
100
100
        text = tree1.get_file_text(file_id)
101
101
        tree1.unlock()
102
102
        self.assertEqual('hello world', text)
103
103
 
104
 
        tree2 = b.repository.revision_tree(rh[1])
 
104
        tree2 = b.repository.revision_tree(rev2)
105
105
        tree2.lock_read()
106
106
        text = tree2.get_file_text(file_id)
107
107
        tree2.unlock()
108
108
        self.assertEqual('version 2', text)
109
109
 
110
 
    def test_delete_commit(self):
111
 
        """Test a commit with a deleted file"""
112
 
        wt = self.make_branch_and_tree('.')
113
 
        b = wt.branch
114
 
        file('hello', 'w').write('hello world')
 
110
    def test_commit_lossy_native(self):
 
111
        """Attempt a lossy commit to a native branch."""
 
112
        wt = self.make_branch_and_tree('.')
 
113
        b = wt.branch
 
114
        with file('hello', 'w') as f: f.write('hello world')
 
115
        wt.add('hello')
 
116
        revid = wt.commit(message='add hello', rev_id='revid', lossy=True)
 
117
        self.assertEquals('revid', revid)
 
118
 
 
119
    def test_commit_lossy_foreign(self):
 
120
        """Attempt a lossy commit to a foreign branch."""
 
121
        test_foreign.register_dummy_foreign_for_test(self)
 
122
        wt = self.make_branch_and_tree('.',
 
123
            format=test_foreign.DummyForeignVcsDirFormat())
 
124
        b = wt.branch
 
125
        with file('hello', 'w') as f: f.write('hello world')
 
126
        wt.add('hello')
 
127
        revid = wt.commit(message='add hello', lossy=True,
 
128
            timestamp=1302659388, timezone=0)
 
129
        self.assertEquals('dummy-v1:1302659388.0-0-UNKNOWN', revid)
 
130
 
 
131
    def test_commit_bound_lossy_foreign(self):
 
132
        """Attempt a lossy commit to a bzr branch bound to a foreign branch."""
 
133
        test_foreign.register_dummy_foreign_for_test(self)
 
134
        foreign_branch = self.make_branch('foreign',
 
135
            format=test_foreign.DummyForeignVcsDirFormat())
 
136
        wt = foreign_branch.create_checkout("local")
 
137
        b = wt.branch
 
138
        with file('local/hello', 'w') as f: f.write('hello world')
 
139
        wt.add('hello')
 
140
        revid = wt.commit(message='add hello', lossy=True,
 
141
            timestamp=1302659388, timezone=0)
 
142
        self.assertEquals('dummy-v1:1302659388.0-0-0', revid)
 
143
        self.assertEquals('dummy-v1:1302659388.0-0-0',
 
144
            foreign_branch.last_revision())
 
145
        self.assertEquals('dummy-v1:1302659388.0-0-0',
 
146
            wt.branch.last_revision())
 
147
 
 
148
    def test_missing_commit(self):
 
149
        """Test a commit with a missing file"""
 
150
        wt = self.make_branch_and_tree('.')
 
151
        b = wt.branch
 
152
        with file('hello', 'w') as f: f.write('hello world')
115
153
        wt.add(['hello'], ['hello-id'])
116
154
        wt.commit(message='add hello')
117
155
 
118
156
        os.remove('hello')
119
 
        wt.commit('removed hello', rev_id='rev2')
 
157
        reporter = CapturingReporter()
 
158
        wt.commit('removed hello', rev_id='rev2', reporter=reporter)
 
159
        self.assertEquals(
 
160
            [('missing', u'hello'), ('deleted', u'hello')],
 
161
            reporter.calls)
120
162
 
121
163
        tree = b.repository.revision_tree('rev2')
122
164
        self.assertFalse(tree.has_id('hello-id'))
125
167
        """Test a partial commit where a file was renamed but not committed.
126
168
 
127
169
        https://bugs.launchpad.net/bzr/+bug/83039
128
 
        
 
170
 
129
171
        If not handled properly, commit will try to snapshot
130
 
        dialog.py with olive/ as a parent, while 
 
172
        dialog.py with olive/ as a parent, while
131
173
        olive/ has not been snapshotted yet.
132
174
        """
133
175
        wt = self.make_branch_and_tree('.')
145
187
        """Commit refuses unless there are changes or it's forced."""
146
188
        wt = self.make_branch_and_tree('.')
147
189
        b = wt.branch
148
 
        file('hello', 'w').write('hello')
 
190
        with file('hello', 'w') as f: f.write('hello')
149
191
        wt.add(['hello'])
150
192
        wt.commit(message='add hello')
151
193
        self.assertEquals(b.revno(), 1)
154
196
                          message='fails',
155
197
                          allow_pointless=False)
156
198
        self.assertEquals(b.revno(), 1)
157
 
        
 
199
 
158
200
    def test_commit_empty(self):
159
201
        """Commiting an empty tree works."""
160
202
        wt = self.make_branch_and_tree('.')
171
213
        """Selective commit in tree with deletions"""
172
214
        wt = self.make_branch_and_tree('.')
173
215
        b = wt.branch
174
 
        file('hello', 'w').write('hello')
175
 
        file('buongia', 'w').write('buongia')
 
216
        with file('hello', 'w') as f: f.write('hello')
 
217
        with file('buongia', 'w') as f: f.write('buongia')
176
218
        wt.add(['hello', 'buongia'],
177
219
              ['hello-id', 'buongia-id'])
178
220
        wt.commit(message='add files',
179
221
                 rev_id='test@rev-1')
180
 
        
 
222
 
181
223
        os.remove('hello')
182
 
        file('buongia', 'w').write('new text')
 
224
        with file('buongia', 'w') as f: f.write('new text')
183
225
        wt.commit(message='update text',
184
226
                 specific_files=['buongia'],
185
227
                 allow_pointless=False,
199
241
        self.assertTrue(tree2.has_filename('hello'))
200
242
        self.assertEquals(tree2.get_file_text('hello-id'), 'hello')
201
243
        self.assertEquals(tree2.get_file_text('buongia-id'), 'new text')
202
 
        
 
244
 
203
245
        tree3 = b.repository.revision_tree('test@rev-3')
204
246
        tree3.lock_read()
205
247
        self.addCleanup(tree3.unlock)
224
266
        eq(tree1.id2path('hello-id'), 'hello')
225
267
        eq(tree1.get_file_text('hello-id'), 'contents of hello\n')
226
268
        self.assertFalse(tree1.has_filename('fruity'))
227
 
        self.check_inventory_shape(tree1.inventory, ['hello'])
228
 
        ie = tree1.inventory['hello-id']
229
 
        eq(ie.revision, 'test@rev-1')
 
269
        self.check_tree_shape(tree1, ['hello'])
 
270
        eq(tree1.get_file_revision('hello-id'), 'test@rev-1')
230
271
 
231
272
        tree2 = b.repository.revision_tree('test@rev-2')
232
273
        tree2.lock_read()
233
274
        self.addCleanup(tree2.unlock)
234
275
        eq(tree2.id2path('hello-id'), 'fruity')
235
276
        eq(tree2.get_file_text('hello-id'), 'contents of hello\n')
236
 
        self.check_inventory_shape(tree2.inventory, ['fruity'])
237
 
        ie = tree2.inventory['hello-id']
238
 
        eq(ie.revision, 'test@rev-2')
 
277
        self.check_tree_shape(tree2, ['fruity'])
 
278
        eq(tree2.get_file_revision('hello-id'), 'test@rev-2')
239
279
 
240
280
    def test_reused_rev_id(self):
241
281
        """Test that a revision id cannot be reused in a branch"""
262
302
        wt.commit('two', rev_id=r2, allow_pointless=False)
263
303
        wt.lock_read()
264
304
        try:
265
 
            self.check_inventory_shape(wt.read_working_inventory(),
266
 
                                       ['a/', 'a/hello', 'b/'])
 
305
            self.check_tree_shape(wt, ['a/', 'a/hello', 'b/'])
267
306
        finally:
268
307
            wt.unlock()
269
308
 
272
311
        wt.commit('three', rev_id=r3, allow_pointless=False)
273
312
        wt.lock_read()
274
313
        try:
275
 
            self.check_inventory_shape(wt.read_working_inventory(),
 
314
            self.check_tree_shape(wt,
276
315
                                       ['a/', 'a/hello', 'a/b/'])
277
 
            self.check_inventory_shape(b.repository.get_revision_inventory(r3),
 
316
            self.check_tree_shape(b.repository.revision_tree(r3),
278
317
                                       ['a/', 'a/hello', 'a/b/'])
279
318
        finally:
280
319
            wt.unlock()
284
323
        wt.commit('four', rev_id=r4, allow_pointless=False)
285
324
        wt.lock_read()
286
325
        try:
287
 
            self.check_inventory_shape(wt.read_working_inventory(),
288
 
                                       ['a/', 'a/b/hello', 'a/b/'])
 
326
            self.check_tree_shape(wt, ['a/', 'a/b/hello', 'a/b/'])
289
327
        finally:
290
328
            wt.unlock()
291
329
 
292
 
        inv = b.repository.get_revision_inventory(r4)
 
330
        inv = b.repository.get_inventory(r4)
293
331
        eq(inv['hello-id'].revision, r4)
294
332
        eq(inv['a-id'].revision, r1)
295
333
        eq(inv['b-id'].revision, r3)
298
336
        """Commit with a removed file"""
299
337
        wt = self.make_branch_and_tree('.')
300
338
        b = wt.branch
301
 
        file('hello', 'w').write('hello world')
 
339
        with file('hello', 'w') as f: f.write('hello world')
302
340
        wt.add(['hello'], ['hello-id'])
303
341
        wt.commit(message='add hello')
304
342
        wt.remove('hello')
313
351
        b = wt.branch
314
352
        rev_ids = []
315
353
        for i in range(4):
316
 
            file('hello', 'w').write((str(i) * 4) + '\n')
 
354
            with file('hello', 'w') as f: f.write((str(i) * 4) + '\n')
317
355
            if i == 0:
318
356
                wt.add(['hello'], ['hello-id'])
319
357
            rev_id = 'test@rev-%d' % (i+1)
320
358
            rev_ids.append(rev_id)
321
359
            wt.commit(message='rev %d' % (i+1),
322
360
                     rev_id=rev_id)
323
 
        eq = self.assertEquals
324
 
        eq(b.revision_history(), rev_ids)
325
361
        for i in range(4):
326
 
            anc = b.repository.get_ancestry(rev_ids[i])
327
 
            eq(anc, [None] + rev_ids[:i+1])
 
362
            self.assertThat(rev_ids[:i+1],
 
363
                MatchesAncestry(b.repository, rev_ids[i]))
328
364
 
329
365
    def test_commit_new_subdir_child_selective(self):
330
366
        wt = self.make_branch_and_tree('.')
344
380
        from bzrlib.errors import StrictCommitFailed
345
381
        wt = self.make_branch_and_tree('.')
346
382
        b = wt.branch
347
 
        file('hello', 'w').write('hello world')
 
383
        with file('hello', 'w') as f: f.write('hello world')
348
384
        wt.add('hello')
349
 
        file('goodbye', 'w').write('goodbye cruel world!')
 
385
        with file('goodbye', 'w') as f: f.write('goodbye cruel world!')
350
386
        self.assertRaises(StrictCommitFailed, wt.commit,
351
387
            message='add hello but not goodbye', strict=True)
352
388
 
353
389
    def test_strict_commit_without_unknowns(self):
354
390
        """Try and commit with no unknown files and strict = True,
355
391
        should work."""
356
 
        from bzrlib.errors import StrictCommitFailed
357
392
        wt = self.make_branch_and_tree('.')
358
393
        b = wt.branch
359
 
        file('hello', 'w').write('hello world')
 
394
        with file('hello', 'w') as f: f.write('hello world')
360
395
        wt.add('hello')
361
396
        wt.commit(message='add hello', strict=True)
362
397
 
364
399
        """Try and commit with unknown files and strict = False, should work."""
365
400
        wt = self.make_branch_and_tree('.')
366
401
        b = wt.branch
367
 
        file('hello', 'w').write('hello world')
 
402
        with file('hello', 'w') as f: f.write('hello world')
368
403
        wt.add('hello')
369
 
        file('goodbye', 'w').write('goodbye cruel world!')
 
404
        with file('goodbye', 'w') as f: f.write('goodbye cruel world!')
370
405
        wt.commit(message='add hello but not goodbye', strict=False)
371
406
 
372
407
    def test_nonstrict_commit_without_unknowns(self):
374
409
        should work."""
375
410
        wt = self.make_branch_and_tree('.')
376
411
        b = wt.branch
377
 
        file('hello', 'w').write('hello world')
 
412
        with file('hello', 'w') as f: f.write('hello world')
378
413
        wt.add('hello')
379
414
        wt.commit(message='add hello', strict=False)
380
415
 
385
420
        wt = self.make_branch_and_tree('.')
386
421
        branch = wt.branch
387
422
        wt.commit("base", allow_pointless=True, rev_id='A')
388
 
        self.failIf(branch.repository.has_signature_for_revision_id('A'))
 
423
        self.assertFalse(branch.repository.has_signature_for_revision_id('A'))
389
424
        try:
390
425
            from bzrlib.testament import Testament
391
426
            # monkey patch gpg signing mechanism
392
427
            bzrlib.gpg.GPGStrategy = bzrlib.gpg.LoopbackGPGStrategy
393
 
            commit.Commit(config=MustSignConfig(branch)).commit(message="base",
394
 
                                                      allow_pointless=True,
395
 
                                                      rev_id='B',
396
 
                                                      working_tree=wt)
 
428
            conf = config.MemoryStack('''
 
429
gpg_signing_command=cat -
 
430
create_signatures=always
 
431
''')
 
432
            commit.Commit(config_stack=conf).commit(
 
433
                message="base", allow_pointless=True, rev_id='B',
 
434
                working_tree=wt)
397
435
            def sign(text):
398
436
                return bzrlib.gpg.LoopbackGPGStrategy(None).sign(text)
399
437
            self.assertEqual(sign(Testament.from_revision(branch.repository,
400
 
                             'B').as_short_text()),
 
438
                                                          'B').as_short_text()),
401
439
                             branch.repository.get_signature_text('B'))
402
440
        finally:
403
441
            bzrlib.gpg.GPGStrategy = oldstrategy
409
447
        wt = self.make_branch_and_tree('.')
410
448
        branch = wt.branch
411
449
        wt.commit("base", allow_pointless=True, rev_id='A')
412
 
        self.failIf(branch.repository.has_signature_for_revision_id('A'))
 
450
        self.assertFalse(branch.repository.has_signature_for_revision_id('A'))
413
451
        try:
414
 
            from bzrlib.testament import Testament
415
452
            # monkey patch gpg signing mechanism
416
453
            bzrlib.gpg.GPGStrategy = bzrlib.gpg.DisabledGPGStrategy
417
 
            config = MustSignConfig(branch)
 
454
            conf = config.MemoryStack('''
 
455
gpg_signing_command=cat -
 
456
create_signatures=always
 
457
''')
418
458
            self.assertRaises(SigningFailed,
419
 
                              commit.Commit(config=config).commit,
 
459
                              commit.Commit(config_stack=conf).commit,
420
460
                              message="base",
421
461
                              allow_pointless=True,
422
462
                              rev_id='B',
423
463
                              working_tree=wt)
424
464
            branch = Branch.open(self.get_url('.'))
425
 
            self.assertEqual(branch.revision_history(), ['A'])
426
 
            self.failIf(branch.repository.has_revision('B'))
 
465
            self.assertEqual(branch.last_revision(), 'A')
 
466
            self.assertFalse(branch.repository.has_revision('B'))
427
467
        finally:
428
468
            bzrlib.gpg.GPGStrategy = oldstrategy
429
469
 
436
476
            calls.append('called')
437
477
        bzrlib.ahook = called
438
478
        try:
439
 
            config = BranchWithHooks(branch)
440
 
            commit.Commit(config=config).commit(
441
 
                            message = "base",
442
 
                            allow_pointless=True,
443
 
                            rev_id='A', working_tree = wt)
 
479
            conf = config.MemoryStack('post_commit=bzrlib.ahook bzrlib.ahook')
 
480
            commit.Commit(config_stack=conf).commit(
 
481
                message = "base", allow_pointless=True, rev_id='A',
 
482
                working_tree = wt)
444
483
            self.assertEqual(['called', 'called'], calls)
445
484
        finally:
446
485
            del bzrlib.ahook
484
523
        other_bzrdir = master_branch.bzrdir.sprout('other')
485
524
        other_tree = other_bzrdir.open_workingtree()
486
525
 
487
 
        # do a commit to the the other branch changing the content file so
 
526
        # do a commit to the other branch changing the content file so
488
527
        # that our commit after merging will have a merged revision in the
489
528
        # content file history.
490
529
        self.build_tree_contents([('other/content_file', 'change in other\n')])
501
540
        bound_tree.commit(message='commit of merge in bound tree')
502
541
 
503
542
    def test_commit_reporting_after_merge(self):
504
 
        # when doing a commit of a merge, the reporter needs to still 
 
543
        # when doing a commit of a merge, the reporter needs to still
505
544
        # be called for each item that is added/removed/deleted.
506
545
        this_tree = self.make_branch_and_tree('this')
507
546
        # we need a bunch of files and dirs, to perform one action on each.
550
589
        this_tree.merge_from_branch(other_tree.branch)
551
590
        reporter = CapturingReporter()
552
591
        this_tree.commit('do the commit', reporter=reporter)
553
 
        self.assertEqual([
554
 
            ('change', 'unchanged', ''),
555
 
            ('change', 'unchanged', 'dirtoleave'),
556
 
            ('change', 'unchanged', 'filetoleave'),
 
592
        expected = set([
557
593
            ('change', 'modified', 'filetomodify'),
558
594
            ('change', 'added', 'newdir'),
559
595
            ('change', 'added', 'newfile'),
563
599
            ('renamed', 'renamed', 'filetoreparent', 'renameddir/reparentedfile'),
564
600
            ('deleted', 'dirtoremove'),
565
601
            ('deleted', 'filetoremove'),
566
 
            ],
567
 
            reporter.calls)
 
602
            ])
 
603
        result = set(reporter.calls)
 
604
        missing = expected - result
 
605
        new = result - expected
 
606
        self.assertEqual((set(), set()), (missing, new))
568
607
 
569
608
    def test_commit_removals_respects_filespec(self):
570
609
        """Commit respects the specified_files for removals."""
660
699
    def test_commit_unversioned_specified(self):
661
700
        """Commit should raise if specified files isn't in basis or worktree"""
662
701
        tree = self.make_branch_and_tree('.')
663
 
        self.assertRaises(errors.PathsNotVersionedError, tree.commit, 
 
702
        self.assertRaises(errors.PathsNotVersionedError, tree.commit,
664
703
                          'message', specific_files=['bogus'])
665
704
 
666
705
    class Callback(object):
667
 
        
 
706
 
668
707
        def __init__(self, message, testcase):
669
708
            self.called = False
670
709
            self.message = message
698
737
        """Callback should not be invoked for pointless commit"""
699
738
        tree = self.make_branch_and_tree('.')
700
739
        cb = self.Callback(u'commit 2', self)
701
 
        self.assertRaises(PointlessCommit, tree.commit, message_callback=cb, 
 
740
        self.assertRaises(PointlessCommit, tree.commit, message_callback=cb,
702
741
                          allow_pointless=False)
703
742
        self.assertFalse(cb.called)
704
743
 
708
747
        cb = self.Callback(u'commit 2', self)
709
748
        repository = tree.branch.repository
710
749
        # simulate network failure
711
 
        def raise_(self, arg, arg2):
 
750
        def raise_(self, arg, arg2, arg3=None, arg4=None):
712
751
            raise errors.NoSuchFile('foo')
713
752
        repository.add_inventory = raise_
 
753
        repository.add_inventory_by_delta = raise_
714
754
        self.assertRaises(errors.NoSuchFile, tree.commit, message_callback=cb)
715
755
        self.assertFalse(cb.called)
716
756
 
738
778
        tree.add('a/c/d')
739
779
        tree.rename_one('a/z/x', 'a/c/d/x')
740
780
        tree.commit('test', specific_files=['a/z/y'])
741
 
 
 
781
 
742
782
    def test_commit_no_author(self):
743
783
        """The default kwarg author in MutableTree.commit should not add
744
784
        the 'author' revision property.
747
787
        rev_id = tree.commit('commit 1')
748
788
        rev = tree.branch.repository.get_revision(rev_id)
749
789
        self.assertFalse('author' in rev.properties)
 
790
        self.assertFalse('authors' in rev.properties)
750
791
 
751
792
    def test_commit_author(self):
752
793
        """Passing a non-empty author kwarg to MutableTree.commit should add
753
794
        the 'author' revision property.
754
795
        """
755
796
        tree = self.make_branch_and_tree('foo')
756
 
        rev_id = tree.commit('commit 1', author='John Doe <jdoe@example.com>')
 
797
        rev_id = self.callDeprecated(['The parameter author was '
 
798
                'deprecated in version 1.13. Use authors instead'],
 
799
                tree.commit, 'commit 1', author='John Doe <jdoe@example.com>')
757
800
        rev = tree.branch.repository.get_revision(rev_id)
758
801
        self.assertEqual('John Doe <jdoe@example.com>',
759
 
                         rev.properties['author'])
 
802
                         rev.properties['authors'])
 
803
        self.assertFalse('author' in rev.properties)
 
804
 
 
805
    def test_commit_empty_authors_list(self):
 
806
        """Passing an empty list to authors shouldn't add the property."""
 
807
        tree = self.make_branch_and_tree('foo')
 
808
        rev_id = tree.commit('commit 1', authors=[])
 
809
        rev = tree.branch.repository.get_revision(rev_id)
 
810
        self.assertFalse('author' in rev.properties)
 
811
        self.assertFalse('authors' in rev.properties)
 
812
 
 
813
    def test_multiple_authors(self):
 
814
        tree = self.make_branch_and_tree('foo')
 
815
        rev_id = tree.commit('commit 1',
 
816
                authors=['John Doe <jdoe@example.com>',
 
817
                         'Jane Rey <jrey@example.com>'])
 
818
        rev = tree.branch.repository.get_revision(rev_id)
 
819
        self.assertEqual('John Doe <jdoe@example.com>\n'
 
820
                'Jane Rey <jrey@example.com>', rev.properties['authors'])
 
821
        self.assertFalse('author' in rev.properties)
 
822
 
 
823
    def test_author_and_authors_incompatible(self):
 
824
        tree = self.make_branch_and_tree('foo')
 
825
        self.assertRaises(AssertionError, tree.commit, 'commit 1',
 
826
                authors=['John Doe <jdoe@example.com>',
 
827
                         'Jane Rey <jrey@example.com>'],
 
828
                author="Jack Me <jme@example.com>")
 
829
 
 
830
    def test_author_with_newline_rejected(self):
 
831
        tree = self.make_branch_and_tree('foo')
 
832
        self.assertRaises(AssertionError, tree.commit, 'commit 1',
 
833
                authors=['John\nDoe <jdoe@example.com>'])
760
834
 
761
835
    def test_commit_with_checkout_and_branch_sharing_repo(self):
762
836
        repo = self.make_repository('repo', shared=True)
763
837
        # make_branch_and_tree ignores shared repos
764
 
        branch = bzrdir.BzrDir.create_branch_convenience('repo/branch')
 
838
        branch = controldir.ControlDir.create_branch_convenience('repo/branch')
765
839
        tree2 = branch.create_checkout('repo/tree2')
766
840
        tree2.commit('message', rev_id='rev1')
767
841
        self.assertTrue(tree2.branch.repository.has_revision('rev1'))