~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_commit.py

  • Committer: Aaron Bentley
  • Date: 2007-06-11 14:59:52 UTC
  • mto: (2520.5.2 bzr.mpbundle)
  • mto: This revision was merged to the branch mainline in revision 2631.
  • Revision ID: abentley@panoramicfeedback.com-20070611145952-cwt4480gphdhen6l
Get installation started

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005-2011 Canonical Ltd
 
1
# Copyright (C) 2005, 2006 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
21
from bzrlib import (
22
 
    bzrdir,
23
 
    config,
24
22
    errors,
 
23
    lockdir,
 
24
    osutils,
 
25
    tests,
25
26
    )
26
27
from bzrlib.branch import Branch
27
 
from bzrlib.bzrdir import BzrDirMetaFormat1
 
28
from bzrlib.bzrdir import BzrDir, BzrDirMetaFormat1
28
29
from bzrlib.commit import Commit, NullCommitReporter
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
 
30
from bzrlib.config import BranchConfig
 
31
from bzrlib.errors import (PointlessCommit, BzrError, SigningFailed, 
 
32
                           LockContention)
 
33
from bzrlib.tests import TestCaseWithTransport
 
34
from bzrlib.workingtree import WorkingTree
43
35
 
44
36
 
45
37
# TODO: Test commit with some added, and added-but-missing files
46
38
 
47
 
class MustSignConfig(config.Stack):
48
 
 
49
 
    def __init__(self, branch):
50
 
        store = config.IniFileStore()
51
 
        store._load_from_string('''
52
 
gpg_signing_command=cat -
53
 
create_signatures=always
54
 
''')
55
 
        super(MustSignConfig, self).__init__([store.get_sections])
56
 
        # FIXME: Strictly speaking we should fallback to the no-name section in
57
 
        # branch.conf but no tests need that so far -- vila 2011-12-14
58
 
 
59
 
 
60
 
class BranchWithHooks(config.Stack):
61
 
 
62
 
    def __init__(self, branch):
63
 
        store = config.IniFileStore()
64
 
        store._load_from_string('post_commit=bzrlib.ahook bzrlib.ahook')
65
 
        super(BranchWithHooks, self).__init__([store.get_sections])
66
 
        # FIXME: Strictly speaking we should fallback to the no-name section in
67
 
        # branch.conf but no tests need that so far -- vila 2011-12-14
 
39
class MustSignConfig(BranchConfig):
 
40
 
 
41
    def signature_needed(self):
 
42
        return True
 
43
 
 
44
    def gpg_signing_command(self):
 
45
        return ['cat', '-']
 
46
 
 
47
 
 
48
class BranchWithHooks(BranchConfig):
 
49
 
 
50
    def post_commit(self):
 
51
        return "bzrlib.ahook bzrlib.ahook"
68
52
 
69
53
 
70
54
class CapturingReporter(NullCommitReporter):
86
70
    def renamed(self, change, old_path, new_path):
87
71
        self.calls.append(('renamed', change, old_path, new_path))
88
72
 
89
 
    def is_verbose(self):
90
 
        return True
91
 
 
92
73
 
93
74
class TestCommit(TestCaseWithTransport):
94
75
 
98
79
        b = wt.branch
99
80
        file('hello', 'w').write('hello world')
100
81
        wt.add('hello')
101
 
        rev1 = wt.commit(message='add hello')
 
82
        wt.commit(message='add hello')
102
83
        file_id = wt.path2id('hello')
103
84
 
104
85
        file('hello', 'w').write('version 2')
105
 
        rev2 = wt.commit(message='commit 2')
 
86
        wt.commit(message='commit 2')
106
87
 
107
88
        eq = self.assertEquals
108
89
        eq(b.revno(), 2)
109
 
        rev = b.repository.get_revision(rev1)
 
90
        rh = b.revision_history()
 
91
        rev = b.repository.get_revision(rh[0])
110
92
        eq(rev.message, 'add hello')
111
93
 
112
 
        tree1 = b.repository.revision_tree(rev1)
113
 
        tree1.lock_read()
 
94
        tree1 = b.repository.revision_tree(rh[0])
114
95
        text = tree1.get_file_text(file_id)
115
 
        tree1.unlock()
116
 
        self.assertEqual('hello world', text)
117
 
 
118
 
        tree2 = b.repository.revision_tree(rev2)
119
 
        tree2.lock_read()
120
 
        text = tree2.get_file_text(file_id)
121
 
        tree2.unlock()
122
 
        self.assertEqual('version 2', text)
123
 
 
124
 
    def test_commit_lossy_native(self):
125
 
        """Attempt a lossy commit to a native branch."""
126
 
        wt = self.make_branch_and_tree('.')
127
 
        b = wt.branch
128
 
        file('hello', 'w').write('hello world')
129
 
        wt.add('hello')
130
 
        revid = wt.commit(message='add hello', rev_id='revid', lossy=True)
131
 
        self.assertEquals('revid', revid)
132
 
 
133
 
    def test_commit_lossy_foreign(self):
134
 
        """Attempt a lossy commit to a foreign branch."""
135
 
        test_foreign.register_dummy_foreign_for_test(self)
136
 
        wt = self.make_branch_and_tree('.',
137
 
            format=test_foreign.DummyForeignVcsDirFormat())
138
 
        b = wt.branch
139
 
        file('hello', 'w').write('hello world')
140
 
        wt.add('hello')
141
 
        revid = wt.commit(message='add hello', lossy=True,
142
 
            timestamp=1302659388, timezone=0)
143
 
        self.assertEquals('dummy-v1:1302659388.0-0-UNKNOWN', revid)
144
 
 
145
 
    def test_commit_bound_lossy_foreign(self):
146
 
        """Attempt a lossy commit to a bzr branch bound to a foreign branch."""
147
 
        test_foreign.register_dummy_foreign_for_test(self)
148
 
        foreign_branch = self.make_branch('foreign',
149
 
            format=test_foreign.DummyForeignVcsDirFormat())
150
 
        wt = foreign_branch.create_checkout("local")
151
 
        b = wt.branch
152
 
        file('local/hello', 'w').write('hello world')
153
 
        wt.add('hello')
154
 
        revid = wt.commit(message='add hello', lossy=True,
155
 
            timestamp=1302659388, timezone=0)
156
 
        self.assertEquals('dummy-v1:1302659388.0-0-0', revid)
157
 
        self.assertEquals('dummy-v1:1302659388.0-0-0',
158
 
            foreign_branch.last_revision())
159
 
        self.assertEquals('dummy-v1:1302659388.0-0-0',
160
 
            wt.branch.last_revision())
161
 
 
162
 
    def test_missing_commit(self):
163
 
        """Test a commit with a missing file"""
 
96
        eq(text, 'hello world')
 
97
 
 
98
        tree2 = b.repository.revision_tree(rh[1])
 
99
        eq(tree2.get_file_text(file_id), 'version 2')
 
100
 
 
101
    def test_delete_commit(self):
 
102
        """Test a commit with a deleted file"""
164
103
        wt = self.make_branch_and_tree('.')
165
104
        b = wt.branch
166
105
        file('hello', 'w').write('hello world')
168
107
        wt.commit(message='add hello')
169
108
 
170
109
        os.remove('hello')
171
 
        reporter = CapturingReporter()
172
 
        wt.commit('removed hello', rev_id='rev2', reporter=reporter)
173
 
        self.assertEquals(
174
 
            [('missing', u'hello'), ('deleted', u'hello')],
175
 
            reporter.calls)
 
110
        wt.commit('removed hello', rev_id='rev2')
176
111
 
177
112
        tree = b.repository.revision_tree('rev2')
178
113
        self.assertFalse(tree.has_id('hello-id'))
179
114
 
180
 
    def test_partial_commit_move(self):
181
 
        """Test a partial commit where a file was renamed but not committed.
182
 
 
183
 
        https://bugs.launchpad.net/bzr/+bug/83039
184
 
 
185
 
        If not handled properly, commit will try to snapshot
186
 
        dialog.py with olive/ as a parent, while
187
 
        olive/ has not been snapshotted yet.
188
 
        """
189
 
        wt = self.make_branch_and_tree('.')
190
 
        b = wt.branch
191
 
        self.build_tree(['annotate/', 'annotate/foo.py',
192
 
                         'olive/', 'olive/dialog.py'
193
 
                        ])
194
 
        wt.add(['annotate', 'olive', 'annotate/foo.py', 'olive/dialog.py'])
195
 
        wt.commit(message='add files')
196
 
        wt.rename_one("olive/dialog.py", "aaa")
197
 
        self.build_tree_contents([('annotate/foo.py', 'modified\n')])
198
 
        wt.commit('renamed hello', specific_files=["annotate"])
199
 
 
200
115
    def test_pointless_commit(self):
201
116
        """Commit refuses unless there are changes or it's forced."""
202
117
        wt = self.make_branch_and_tree('.')
210
125
                          message='fails',
211
126
                          allow_pointless=False)
212
127
        self.assertEquals(b.revno(), 1)
213
 
 
 
128
        
214
129
    def test_commit_empty(self):
215
130
        """Commiting an empty tree works."""
216
131
        wt = self.make_branch_and_tree('.')
233
148
              ['hello-id', 'buongia-id'])
234
149
        wt.commit(message='add files',
235
150
                 rev_id='test@rev-1')
236
 
 
 
151
        
237
152
        os.remove('hello')
238
153
        file('buongia', 'w').write('new text')
239
154
        wt.commit(message='update text',
250
165
        eq(b.revno(), 3)
251
166
 
252
167
        tree2 = b.repository.revision_tree('test@rev-2')
253
 
        tree2.lock_read()
254
 
        self.addCleanup(tree2.unlock)
255
168
        self.assertTrue(tree2.has_filename('hello'))
256
169
        self.assertEquals(tree2.get_file_text('hello-id'), 'hello')
257
170
        self.assertEquals(tree2.get_file_text('buongia-id'), 'new text')
258
 
 
 
171
        
259
172
        tree3 = b.repository.revision_tree('test@rev-3')
260
 
        tree3.lock_read()
261
 
        self.addCleanup(tree3.unlock)
262
173
        self.assertFalse(tree3.has_filename('hello'))
263
174
        self.assertEquals(tree3.get_file_text('buongia-id'), 'new text')
264
175
 
275
186
 
276
187
        eq = self.assertEquals
277
188
        tree1 = b.repository.revision_tree('test@rev-1')
278
 
        tree1.lock_read()
279
 
        self.addCleanup(tree1.unlock)
280
189
        eq(tree1.id2path('hello-id'), 'hello')
281
190
        eq(tree1.get_file_text('hello-id'), 'contents of hello\n')
282
191
        self.assertFalse(tree1.has_filename('fruity'))
283
 
        self.check_tree_shape(tree1, ['hello'])
284
 
        eq(tree1.get_file_revision('hello-id'), 'test@rev-1')
 
192
        self.check_inventory_shape(tree1.inventory, ['hello'])
 
193
        ie = tree1.inventory['hello-id']
 
194
        eq(ie.revision, 'test@rev-1')
285
195
 
286
196
        tree2 = b.repository.revision_tree('test@rev-2')
287
 
        tree2.lock_read()
288
 
        self.addCleanup(tree2.unlock)
289
197
        eq(tree2.id2path('hello-id'), 'fruity')
290
198
        eq(tree2.get_file_text('hello-id'), 'contents of hello\n')
291
 
        self.check_tree_shape(tree2, ['fruity'])
292
 
        eq(tree2.get_file_revision('hello-id'), 'test@rev-2')
 
199
        self.check_inventory_shape(tree2.inventory, ['fruity'])
 
200
        ie = tree2.inventory['hello-id']
 
201
        eq(ie.revision, 'test@rev-2')
293
202
 
294
203
    def test_reused_rev_id(self):
295
204
        """Test that a revision id cannot be reused in a branch"""
316
225
        wt.commit('two', rev_id=r2, allow_pointless=False)
317
226
        wt.lock_read()
318
227
        try:
319
 
            self.check_tree_shape(wt, ['a/', 'a/hello', 'b/'])
 
228
            self.check_inventory_shape(wt.read_working_inventory(),
 
229
                                       ['a', 'a/hello', 'b'])
320
230
        finally:
321
231
            wt.unlock()
322
232
 
325
235
        wt.commit('three', rev_id=r3, allow_pointless=False)
326
236
        wt.lock_read()
327
237
        try:
328
 
            self.check_tree_shape(wt,
329
 
                                       ['a/', 'a/hello', 'a/b/'])
330
 
            self.check_tree_shape(b.repository.revision_tree(r3),
331
 
                                       ['a/', 'a/hello', 'a/b/'])
 
238
            self.check_inventory_shape(wt.read_working_inventory(),
 
239
                                       ['a', 'a/hello', 'a/b'])
 
240
            self.check_inventory_shape(b.repository.get_revision_inventory(r3),
 
241
                                       ['a', 'a/hello', 'a/b'])
332
242
        finally:
333
243
            wt.unlock()
334
244
 
337
247
        wt.commit('four', rev_id=r4, allow_pointless=False)
338
248
        wt.lock_read()
339
249
        try:
340
 
            self.check_tree_shape(wt, ['a/', 'a/b/hello', 'a/b/'])
 
250
            self.check_inventory_shape(wt.read_working_inventory(),
 
251
                                       ['a', 'a/b/hello', 'a/b'])
341
252
        finally:
342
253
            wt.unlock()
343
254
 
344
 
        inv = b.repository.get_inventory(r4)
 
255
        inv = b.repository.get_revision_inventory(r4)
345
256
        eq(inv['hello-id'].revision, r4)
346
257
        eq(inv['a-id'].revision, r1)
347
258
        eq(inv['b-id'].revision, r3)
372
283
            rev_ids.append(rev_id)
373
284
            wt.commit(message='rev %d' % (i+1),
374
285
                     rev_id=rev_id)
 
286
        eq = self.assertEquals
 
287
        eq(b.revision_history(), rev_ids)
375
288
        for i in range(4):
376
 
            self.assertThat(rev_ids[:i+1],
377
 
                MatchesAncestry(b.repository, rev_ids[i]))
 
289
            anc = b.repository.get_ancestry(rev_ids[i])
 
290
            eq(anc, [None] + rev_ids[:i+1])
378
291
 
379
292
    def test_commit_new_subdir_child_selective(self):
380
293
        wt = self.make_branch_and_tree('.')
403
316
    def test_strict_commit_without_unknowns(self):
404
317
        """Try and commit with no unknown files and strict = True,
405
318
        should work."""
 
319
        from bzrlib.errors import StrictCommitFailed
406
320
        wt = self.make_branch_and_tree('.')
407
321
        b = wt.branch
408
322
        file('hello', 'w').write('hello world')
434
348
        wt = self.make_branch_and_tree('.')
435
349
        branch = wt.branch
436
350
        wt.commit("base", allow_pointless=True, rev_id='A')
437
 
        self.assertFalse(branch.repository.has_signature_for_revision_id('A'))
 
351
        self.failIf(branch.repository.has_signature_for_revision_id('A'))
438
352
        try:
439
353
            from bzrlib.testament import Testament
440
354
            # monkey patch gpg signing mechanism
441
355
            bzrlib.gpg.GPGStrategy = bzrlib.gpg.LoopbackGPGStrategy
442
 
            commit.Commit(config_stack=MustSignConfig(branch)
443
 
                          ).commit(message="base", allow_pointless=True,
444
 
                                   rev_id='B', working_tree=wt)
 
356
            commit.Commit(config=MustSignConfig(branch)).commit(message="base",
 
357
                                                      allow_pointless=True,
 
358
                                                      rev_id='B',
 
359
                                                      working_tree=wt)
445
360
            def sign(text):
446
361
                return bzrlib.gpg.LoopbackGPGStrategy(None).sign(text)
447
362
            self.assertEqual(sign(Testament.from_revision(branch.repository,
448
 
                                                          'B').as_short_text()),
 
363
                             'B').as_short_text()),
449
364
                             branch.repository.get_signature_text('B'))
450
365
        finally:
451
366
            bzrlib.gpg.GPGStrategy = oldstrategy
457
372
        wt = self.make_branch_and_tree('.')
458
373
        branch = wt.branch
459
374
        wt.commit("base", allow_pointless=True, rev_id='A')
460
 
        self.assertFalse(branch.repository.has_signature_for_revision_id('A'))
 
375
        self.failIf(branch.repository.has_signature_for_revision_id('A'))
461
376
        try:
 
377
            from bzrlib.testament import Testament
462
378
            # monkey patch gpg signing mechanism
463
379
            bzrlib.gpg.GPGStrategy = bzrlib.gpg.DisabledGPGStrategy
464
380
            config = MustSignConfig(branch)
465
381
            self.assertRaises(SigningFailed,
466
 
                              commit.Commit(config_stack=config).commit,
 
382
                              commit.Commit(config=config).commit,
467
383
                              message="base",
468
384
                              allow_pointless=True,
469
385
                              rev_id='B',
470
386
                              working_tree=wt)
471
387
            branch = Branch.open(self.get_url('.'))
472
 
            self.assertEqual(branch.last_revision(), 'A')
473
 
            self.assertFalse(branch.repository.has_revision('B'))
 
388
            self.assertEqual(branch.revision_history(), ['A'])
 
389
            self.failIf(branch.repository.has_revision('B'))
474
390
        finally:
475
391
            bzrlib.gpg.GPGStrategy = oldstrategy
476
392
 
484
400
        bzrlib.ahook = called
485
401
        try:
486
402
            config = BranchWithHooks(branch)
487
 
            commit.Commit(config_stack=config).commit(
 
403
            commit.Commit(config=config).commit(
488
404
                            message = "base",
489
405
                            allow_pointless=True,
490
406
                            rev_id='A', working_tree = wt)
511
427
        bound = master.sprout('bound')
512
428
        wt = bound.open_workingtree()
513
429
        wt.branch.set_bound_location(os.path.realpath('master'))
 
430
 
 
431
        orig_default = lockdir._DEFAULT_TIMEOUT_SECONDS
514
432
        master_branch.lock_write()
515
433
        try:
 
434
            lockdir._DEFAULT_TIMEOUT_SECONDS = 1
516
435
            self.assertRaises(LockContention, wt.commit, 'silly')
517
436
        finally:
 
437
            lockdir._DEFAULT_TIMEOUT_SECONDS = orig_default
518
438
            master_branch.unlock()
519
439
 
520
440
    def test_commit_bound_merge(self):
531
451
        other_bzrdir = master_branch.bzrdir.sprout('other')
532
452
        other_tree = other_bzrdir.open_workingtree()
533
453
 
534
 
        # do a commit to the other branch changing the content file so
 
454
        # do a commit to the the other branch changing the content file so
535
455
        # that our commit after merging will have a merged revision in the
536
456
        # content file history.
537
457
        self.build_tree_contents([('other/content_file', 'change in other\n')])
548
468
        bound_tree.commit(message='commit of merge in bound tree')
549
469
 
550
470
    def test_commit_reporting_after_merge(self):
551
 
        # when doing a commit of a merge, the reporter needs to still
 
471
        # when doing a commit of a merge, the reporter needs to still 
552
472
        # be called for each item that is added/removed/deleted.
553
473
        this_tree = self.make_branch_and_tree('this')
554
474
        # we need a bunch of files and dirs, to perform one action on each.
597
517
        this_tree.merge_from_branch(other_tree.branch)
598
518
        reporter = CapturingReporter()
599
519
        this_tree.commit('do the commit', reporter=reporter)
600
 
        expected = set([
 
520
        self.assertEqual([
 
521
            ('change', 'unchanged', ''),
 
522
            ('change', 'unchanged', 'dirtoleave'),
 
523
            ('change', 'unchanged', 'filetoleave'),
601
524
            ('change', 'modified', 'filetomodify'),
602
525
            ('change', 'added', 'newdir'),
603
526
            ('change', 'added', 'newfile'),
604
527
            ('renamed', 'renamed', 'dirtorename', 'renameddir'),
605
 
            ('renamed', 'renamed', 'filetorename', 'renamedfile'),
606
528
            ('renamed', 'renamed', 'dirtoreparent', 'renameddir/reparenteddir'),
607
529
            ('renamed', 'renamed', 'filetoreparent', 'renameddir/reparentedfile'),
 
530
            ('renamed', 'renamed', 'filetorename', 'renamedfile'),
608
531
            ('deleted', 'dirtoremove'),
609
532
            ('deleted', 'filetoremove'),
610
 
            ])
611
 
        result = set(reporter.calls)
612
 
        missing = expected - result
613
 
        new = result - expected
614
 
        self.assertEqual((set(), set()), (missing, new))
 
533
            ],
 
534
            reporter.calls)
615
535
 
616
536
    def test_commit_removals_respects_filespec(self):
617
537
        """Commit respects the specified_files for removals."""
661
581
            basis.unlock()
662
582
 
663
583
    def test_commit_kind_changes(self):
664
 
        self.requireFeature(SymlinkFeature)
 
584
        if not osutils.has_symlinks():
 
585
            raise tests.TestSkipped('Test requires symlink support')
665
586
        tree = self.make_branch_and_tree('.')
666
587
        os.symlink('target', 'name')
667
588
        tree.add('name', 'a-file-id')
707
628
    def test_commit_unversioned_specified(self):
708
629
        """Commit should raise if specified files isn't in basis or worktree"""
709
630
        tree = self.make_branch_and_tree('.')
710
 
        self.assertRaises(errors.PathsNotVersionedError, tree.commit,
 
631
        self.assertRaises(errors.PathsNotVersionedError, tree.commit, 
711
632
                          'message', specific_files=['bogus'])
712
633
 
713
634
    class Callback(object):
714
 
 
 
635
        
715
636
        def __init__(self, message, testcase):
716
637
            self.called = False
717
638
            self.message = message
745
666
        """Callback should not be invoked for pointless commit"""
746
667
        tree = self.make_branch_and_tree('.')
747
668
        cb = self.Callback(u'commit 2', self)
748
 
        self.assertRaises(PointlessCommit, tree.commit, message_callback=cb,
 
669
        self.assertRaises(PointlessCommit, tree.commit, message_callback=cb, 
749
670
                          allow_pointless=False)
750
671
        self.assertFalse(cb.called)
751
672
 
755
676
        cb = self.Callback(u'commit 2', self)
756
677
        repository = tree.branch.repository
757
678
        # simulate network failure
758
 
        def raise_(self, arg, arg2, arg3=None, arg4=None):
 
679
        def raise_(self, arg, arg2):
759
680
            raise errors.NoSuchFile('foo')
760
681
        repository.add_inventory = raise_
761
 
        repository.add_inventory_by_delta = raise_
762
682
        self.assertRaises(errors.NoSuchFile, tree.commit, message_callback=cb)
763
683
        self.assertFalse(cb.called)
764
684
 
775
695
        self.assertEqual(['bar', 'baz'], err.files)
776
696
        self.assertEqual('Selected-file commit of merges is not supported'
777
697
                         ' yet: files bar, baz', str(err))
778
 
 
779
 
    def test_commit_ordering(self):
780
 
        """Test of corner-case commit ordering error"""
781
 
        tree = self.make_branch_and_tree('.')
782
 
        self.build_tree(['a/', 'a/z/', 'a/c/', 'a/z/x', 'a/z/y'])
783
 
        tree.add(['a/', 'a/z/', 'a/c/', 'a/z/x', 'a/z/y'])
784
 
        tree.commit('setup')
785
 
        self.build_tree(['a/c/d/'])
786
 
        tree.add('a/c/d')
787
 
        tree.rename_one('a/z/x', 'a/c/d/x')
788
 
        tree.commit('test', specific_files=['a/z/y'])
789
 
 
790
 
    def test_commit_no_author(self):
791
 
        """The default kwarg author in MutableTree.commit should not add
792
 
        the 'author' revision property.
793
 
        """
794
 
        tree = self.make_branch_and_tree('foo')
795
 
        rev_id = tree.commit('commit 1')
796
 
        rev = tree.branch.repository.get_revision(rev_id)
797
 
        self.assertFalse('author' in rev.properties)
798
 
        self.assertFalse('authors' in rev.properties)
799
 
 
800
 
    def test_commit_author(self):
801
 
        """Passing a non-empty author kwarg to MutableTree.commit should add
802
 
        the 'author' revision property.
803
 
        """
804
 
        tree = self.make_branch_and_tree('foo')
805
 
        rev_id = self.callDeprecated(['The parameter author was '
806
 
                'deprecated in version 1.13. Use authors instead'],
807
 
                tree.commit, 'commit 1', author='John Doe <jdoe@example.com>')
808
 
        rev = tree.branch.repository.get_revision(rev_id)
809
 
        self.assertEqual('John Doe <jdoe@example.com>',
810
 
                         rev.properties['authors'])
811
 
        self.assertFalse('author' in rev.properties)
812
 
 
813
 
    def test_commit_empty_authors_list(self):
814
 
        """Passing an empty list to authors shouldn't add the property."""
815
 
        tree = self.make_branch_and_tree('foo')
816
 
        rev_id = tree.commit('commit 1', authors=[])
817
 
        rev = tree.branch.repository.get_revision(rev_id)
818
 
        self.assertFalse('author' in rev.properties)
819
 
        self.assertFalse('authors' in rev.properties)
820
 
 
821
 
    def test_multiple_authors(self):
822
 
        tree = self.make_branch_and_tree('foo')
823
 
        rev_id = tree.commit('commit 1',
824
 
                authors=['John Doe <jdoe@example.com>',
825
 
                         'Jane Rey <jrey@example.com>'])
826
 
        rev = tree.branch.repository.get_revision(rev_id)
827
 
        self.assertEqual('John Doe <jdoe@example.com>\n'
828
 
                'Jane Rey <jrey@example.com>', rev.properties['authors'])
829
 
        self.assertFalse('author' in rev.properties)
830
 
 
831
 
    def test_author_and_authors_incompatible(self):
832
 
        tree = self.make_branch_and_tree('foo')
833
 
        self.assertRaises(AssertionError, tree.commit, 'commit 1',
834
 
                authors=['John Doe <jdoe@example.com>',
835
 
                         'Jane Rey <jrey@example.com>'],
836
 
                author="Jack Me <jme@example.com>")
837
 
 
838
 
    def test_author_with_newline_rejected(self):
839
 
        tree = self.make_branch_and_tree('foo')
840
 
        self.assertRaises(AssertionError, tree.commit, 'commit 1',
841
 
                authors=['John\nDoe <jdoe@example.com>'])
842
 
 
843
 
    def test_commit_with_checkout_and_branch_sharing_repo(self):
844
 
        repo = self.make_repository('repo', shared=True)
845
 
        # make_branch_and_tree ignores shared repos
846
 
        branch = bzrdir.BzrDir.create_branch_convenience('repo/branch')
847
 
        tree2 = branch.create_checkout('repo/tree2')
848
 
        tree2.commit('message', rev_id='rev1')
849
 
        self.assertTrue(tree2.branch.repository.has_revision('rev1'))