/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to breezy/tests/test_commit.py

  • Committer: Jelmer Vernooij
  • Date: 2018-02-18 21:42:57 UTC
  • mto: This revision was merged to the branch mainline in revision 6859.
  • Revision ID: jelmer@jelmer.uk-20180218214257-jpevutp1wa30tz3v
Update TODO to reference Breezy, not Bazaar.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005-2010 Canonical Ltd
 
1
# Copyright (C) 2005-2012, 2016 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
17
17
 
18
18
import os
19
19
 
20
 
import bzrlib
21
 
from bzrlib import (
22
 
    bzrdir,
 
20
import breezy
 
21
from .. import (
 
22
    config,
 
23
    controldir,
23
24
    errors,
24
 
    lockdir,
25
 
    osutils,
26
 
    tests,
27
 
    )
28
 
from bzrlib.branch import Branch
29
 
from bzrlib.bzrdir import BzrDir, BzrDirMetaFormat1
30
 
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
 
25
    )
 
26
from ..branch import Branch
 
27
from ..bzr.bzrdir import BzrDirMetaFormat1
 
28
from ..commit import (
 
29
    CannotCommitSelectedFileMerge,
 
30
    Commit,
 
31
    NullCommitReporter,
 
32
    PointlessCommit,
 
33
    filter_excluded,
 
34
    )
 
35
from ..errors import (
 
36
    BzrError,
 
37
    LockContention,
 
38
    )
 
39
from . import (
 
40
    TestCase,
 
41
    TestCaseWithTransport,
 
42
    test_foreign,
 
43
    )
 
44
from .features import (
 
45
    SymlinkFeature,
 
46
    )
 
47
from .matchers import MatchesAncestry
36
48
 
37
49
 
38
50
# TODO: Test commit with some added, and added-but-missing files
39
51
 
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"
 
52
class MustSignConfig(config.MemoryStack):
 
53
 
 
54
    def __init__(self):
 
55
        super(MustSignConfig, self).__init__('''
 
56
create_signatures=always
 
57
''')
53
58
 
54
59
 
55
60
class CapturingReporter(NullCommitReporter):
81
86
        """Commit and check two versions of a single file."""
82
87
        wt = self.make_branch_and_tree('.')
83
88
        b = wt.branch
84
 
        file('hello', 'w').write('hello world')
 
89
        with open('hello', 'w') as f: f.write('hello world')
85
90
        wt.add('hello')
86
 
        wt.commit(message='add hello')
87
 
        file_id = wt.path2id('hello')
88
 
 
89
 
        file('hello', 'w').write('version 2')
90
 
        wt.commit(message='commit 2')
91
 
 
92
 
        eq = self.assertEquals
 
91
        rev1 = wt.commit(message='add hello')
 
92
 
 
93
        with open('hello', 'w') as f: f.write('version 2')
 
94
        rev2 = wt.commit(message='commit 2')
 
95
 
 
96
        eq = self.assertEqual
93
97
        eq(b.revno(), 2)
94
 
        rh = b.revision_history()
95
 
        rev = b.repository.get_revision(rh[0])
 
98
        rev = b.repository.get_revision(rev1)
96
99
        eq(rev.message, 'add hello')
97
100
 
98
 
        tree1 = b.repository.revision_tree(rh[0])
 
101
        tree1 = b.repository.revision_tree(rev1)
99
102
        tree1.lock_read()
100
 
        text = tree1.get_file_text(file_id)
 
103
        text = tree1.get_file_text('hello')
101
104
        tree1.unlock()
102
105
        self.assertEqual('hello world', text)
103
106
 
104
 
        tree2 = b.repository.revision_tree(rh[1])
 
107
        tree2 = b.repository.revision_tree(rev2)
105
108
        tree2.lock_read()
106
 
        text = tree2.get_file_text(file_id)
 
109
        text = tree2.get_file_text('hello')
107
110
        tree2.unlock()
108
111
        self.assertEqual('version 2', text)
109
112
 
 
113
    def test_commit_lossy_native(self):
 
114
        """Attempt a lossy commit to a native branch."""
 
115
        wt = self.make_branch_and_tree('.')
 
116
        b = wt.branch
 
117
        with open('hello', 'w') as f: f.write('hello world')
 
118
        wt.add('hello')
 
119
        revid = wt.commit(message='add hello', rev_id='revid', lossy=True)
 
120
        self.assertEqual('revid', revid)
 
121
 
 
122
    def test_commit_lossy_foreign(self):
 
123
        """Attempt a lossy commit to a foreign branch."""
 
124
        test_foreign.register_dummy_foreign_for_test(self)
 
125
        wt = self.make_branch_and_tree('.',
 
126
            format=test_foreign.DummyForeignVcsDirFormat())
 
127
        b = wt.branch
 
128
        with open('hello', 'w') as f: f.write('hello world')
 
129
        wt.add('hello')
 
130
        revid = wt.commit(message='add hello', lossy=True,
 
131
            timestamp=1302659388, timezone=0)
 
132
        self.assertEqual('dummy-v1:1302659388.0-0-UNKNOWN', revid)
 
133
 
 
134
    def test_commit_bound_lossy_foreign(self):
 
135
        """Attempt a lossy commit to a bzr branch bound to a foreign branch."""
 
136
        test_foreign.register_dummy_foreign_for_test(self)
 
137
        foreign_branch = self.make_branch('foreign',
 
138
            format=test_foreign.DummyForeignVcsDirFormat())
 
139
        wt = foreign_branch.create_checkout("local")
 
140
        b = wt.branch
 
141
        with open('local/hello', 'w') as f: f.write('hello world')
 
142
        wt.add('hello')
 
143
        revid = wt.commit(message='add hello', lossy=True,
 
144
            timestamp=1302659388, timezone=0)
 
145
        self.assertEqual('dummy-v1:1302659388.0-0-0', revid)
 
146
        self.assertEqual('dummy-v1:1302659388.0-0-0',
 
147
            foreign_branch.last_revision())
 
148
        self.assertEqual('dummy-v1:1302659388.0-0-0',
 
149
            wt.branch.last_revision())
 
150
 
110
151
    def test_missing_commit(self):
111
152
        """Test a commit with a missing file"""
112
153
        wt = self.make_branch_and_tree('.')
113
154
        b = wt.branch
114
 
        file('hello', 'w').write('hello world')
 
155
        with open('hello', 'w') as f: f.write('hello world')
115
156
        wt.add(['hello'], ['hello-id'])
116
157
        wt.commit(message='add hello')
117
158
 
118
159
        os.remove('hello')
119
 
        wt.commit('removed hello', rev_id='rev2')
 
160
        reporter = CapturingReporter()
 
161
        wt.commit('removed hello', rev_id='rev2', reporter=reporter)
 
162
        self.assertEqual(
 
163
            [('missing', u'hello'), ('deleted', u'hello')],
 
164
            reporter.calls)
120
165
 
121
166
        tree = b.repository.revision_tree('rev2')
122
167
        self.assertFalse(tree.has_id('hello-id'))
145
190
        """Commit refuses unless there are changes or it's forced."""
146
191
        wt = self.make_branch_and_tree('.')
147
192
        b = wt.branch
148
 
        file('hello', 'w').write('hello')
 
193
        with open('hello', 'w') as f: f.write('hello')
149
194
        wt.add(['hello'])
150
195
        wt.commit(message='add hello')
151
 
        self.assertEquals(b.revno(), 1)
 
196
        self.assertEqual(b.revno(), 1)
152
197
        self.assertRaises(PointlessCommit,
153
198
                          wt.commit,
154
199
                          message='fails',
155
200
                          allow_pointless=False)
156
 
        self.assertEquals(b.revno(), 1)
 
201
        self.assertEqual(b.revno(), 1)
157
202
 
158
203
    def test_commit_empty(self):
159
204
        """Commiting an empty tree works."""
165
210
                          message='empty tree',
166
211
                          allow_pointless=False)
167
212
        wt.commit(message='empty tree', allow_pointless=True)
168
 
        self.assertEquals(b.revno(), 2)
 
213
        self.assertEqual(b.revno(), 2)
169
214
 
170
215
    def test_selective_delete(self):
171
216
        """Selective commit in tree with deletions"""
172
217
        wt = self.make_branch_and_tree('.')
173
218
        b = wt.branch
174
 
        file('hello', 'w').write('hello')
175
 
        file('buongia', 'w').write('buongia')
 
219
        with open('hello', 'w') as f: f.write('hello')
 
220
        with open('buongia', 'w') as f: f.write('buongia')
176
221
        wt.add(['hello', 'buongia'],
177
222
              ['hello-id', 'buongia-id'])
178
223
        wt.commit(message='add files',
179
224
                 rev_id='test@rev-1')
180
225
 
181
226
        os.remove('hello')
182
 
        file('buongia', 'w').write('new text')
 
227
        with open('buongia', 'w') as f: f.write('new text')
183
228
        wt.commit(message='update text',
184
229
                 specific_files=['buongia'],
185
230
                 allow_pointless=False,
190
235
                 allow_pointless=False,
191
236
                 rev_id='test@rev-3')
192
237
 
193
 
        eq = self.assertEquals
 
238
        eq = self.assertEqual
194
239
        eq(b.revno(), 3)
195
240
 
196
241
        tree2 = b.repository.revision_tree('test@rev-2')
197
242
        tree2.lock_read()
198
243
        self.addCleanup(tree2.unlock)
199
244
        self.assertTrue(tree2.has_filename('hello'))
200
 
        self.assertEquals(tree2.get_file_text('hello-id'), 'hello')
201
 
        self.assertEquals(tree2.get_file_text('buongia-id'), 'new text')
 
245
        self.assertEqual(tree2.get_file_text('hello'), 'hello')
 
246
        self.assertEqual(tree2.get_file_text('buongia'), 'new text')
202
247
 
203
248
        tree3 = b.repository.revision_tree('test@rev-3')
204
249
        tree3.lock_read()
205
250
        self.addCleanup(tree3.unlock)
206
251
        self.assertFalse(tree3.has_filename('hello'))
207
 
        self.assertEquals(tree3.get_file_text('buongia-id'), 'new text')
 
252
        self.assertEqual(tree3.get_file_text('buongia'), 'new text')
208
253
 
209
254
    def test_commit_rename(self):
210
255
        """Test commit of a revision where a file is renamed."""
217
262
        tree.rename_one('hello', 'fruity')
218
263
        tree.commit(message='renamed', rev_id='test@rev-2', allow_pointless=False)
219
264
 
220
 
        eq = self.assertEquals
 
265
        eq = self.assertEqual
221
266
        tree1 = b.repository.revision_tree('test@rev-1')
222
267
        tree1.lock_read()
223
268
        self.addCleanup(tree1.unlock)
224
269
        eq(tree1.id2path('hello-id'), 'hello')
225
 
        eq(tree1.get_file_text('hello-id'), 'contents of hello\n')
 
270
        eq(tree1.get_file_text('hello'), 'contents of hello\n')
226
271
        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')
 
272
        self.check_tree_shape(tree1, ['hello'])
 
273
        eq(tree1.get_file_revision('hello'), 'test@rev-1')
230
274
 
231
275
        tree2 = b.repository.revision_tree('test@rev-2')
232
276
        tree2.lock_read()
233
277
        self.addCleanup(tree2.unlock)
234
278
        eq(tree2.id2path('hello-id'), 'fruity')
235
 
        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')
 
279
        eq(tree2.get_file_text('fruity'), 'contents of hello\n')
 
280
        self.check_tree_shape(tree2, ['fruity'])
 
281
        eq(tree2.get_file_revision('fruity'), 'test@rev-2')
239
282
 
240
283
    def test_reused_rev_id(self):
241
284
        """Test that a revision id cannot be reused in a branch"""
250
293
 
251
294
    def test_commit_move(self):
252
295
        """Test commit of revisions with moved files and directories"""
253
 
        eq = self.assertEquals
 
296
        eq = self.assertEqual
254
297
        wt = self.make_branch_and_tree('.')
255
298
        b = wt.branch
256
299
        r1 = 'test@rev-1'
262
305
        wt.commit('two', rev_id=r2, allow_pointless=False)
263
306
        wt.lock_read()
264
307
        try:
265
 
            self.check_inventory_shape(wt.read_working_inventory(),
266
 
                                       ['a/', 'a/hello', 'b/'])
 
308
            self.check_tree_shape(wt, ['a/', 'a/hello', 'b/'])
267
309
        finally:
268
310
            wt.unlock()
269
311
 
272
314
        wt.commit('three', rev_id=r3, allow_pointless=False)
273
315
        wt.lock_read()
274
316
        try:
275
 
            self.check_inventory_shape(wt.read_working_inventory(),
 
317
            self.check_tree_shape(wt,
276
318
                                       ['a/', 'a/hello', 'a/b/'])
277
 
            self.check_inventory_shape(b.repository.get_inventory(r3),
 
319
            self.check_tree_shape(b.repository.revision_tree(r3),
278
320
                                       ['a/', 'a/hello', 'a/b/'])
279
321
        finally:
280
322
            wt.unlock()
284
326
        wt.commit('four', rev_id=r4, allow_pointless=False)
285
327
        wt.lock_read()
286
328
        try:
287
 
            self.check_inventory_shape(wt.read_working_inventory(),
288
 
                                       ['a/', 'a/b/hello', 'a/b/'])
 
329
            self.check_tree_shape(wt, ['a/', 'a/b/hello', 'a/b/'])
289
330
        finally:
290
331
            wt.unlock()
291
332
 
298
339
        """Commit with a removed file"""
299
340
        wt = self.make_branch_and_tree('.')
300
341
        b = wt.branch
301
 
        file('hello', 'w').write('hello world')
 
342
        with open('hello', 'w') as f: f.write('hello world')
302
343
        wt.add(['hello'], ['hello-id'])
303
344
        wt.commit(message='add hello')
304
345
        wt.remove('hello')
313
354
        b = wt.branch
314
355
        rev_ids = []
315
356
        for i in range(4):
316
 
            file('hello', 'w').write((str(i) * 4) + '\n')
 
357
            with open('hello', 'w') as f: f.write((str(i) * 4) + '\n')
317
358
            if i == 0:
318
359
                wt.add(['hello'], ['hello-id'])
319
360
            rev_id = 'test@rev-%d' % (i+1)
320
361
            rev_ids.append(rev_id)
321
362
            wt.commit(message='rev %d' % (i+1),
322
363
                     rev_id=rev_id)
323
 
        eq = self.assertEquals
324
 
        eq(b.revision_history(), rev_ids)
325
364
        for i in range(4):
326
 
            anc = b.repository.get_ancestry(rev_ids[i])
327
 
            eq(anc, [None] + rev_ids[:i+1])
 
365
            self.assertThat(rev_ids[:i+1],
 
366
                MatchesAncestry(b.repository, rev_ids[i]))
328
367
 
329
368
    def test_commit_new_subdir_child_selective(self):
330
369
        wt = self.make_branch_and_tree('.')
341
380
 
342
381
    def test_strict_commit(self):
343
382
        """Try and commit with unknown files and strict = True, should fail."""
344
 
        from bzrlib.errors import StrictCommitFailed
 
383
        from ..errors import StrictCommitFailed
345
384
        wt = self.make_branch_and_tree('.')
346
385
        b = wt.branch
347
 
        file('hello', 'w').write('hello world')
 
386
        with open('hello', 'w') as f: f.write('hello world')
348
387
        wt.add('hello')
349
 
        file('goodbye', 'w').write('goodbye cruel world!')
 
388
        with open('goodbye', 'w') as f: f.write('goodbye cruel world!')
350
389
        self.assertRaises(StrictCommitFailed, wt.commit,
351
390
            message='add hello but not goodbye', strict=True)
352
391
 
353
392
    def test_strict_commit_without_unknowns(self):
354
393
        """Try and commit with no unknown files and strict = True,
355
394
        should work."""
356
 
        from bzrlib.errors import StrictCommitFailed
357
395
        wt = self.make_branch_and_tree('.')
358
396
        b = wt.branch
359
 
        file('hello', 'w').write('hello world')
 
397
        with open('hello', 'w') as f: f.write('hello world')
360
398
        wt.add('hello')
361
399
        wt.commit(message='add hello', strict=True)
362
400
 
364
402
        """Try and commit with unknown files and strict = False, should work."""
365
403
        wt = self.make_branch_and_tree('.')
366
404
        b = wt.branch
367
 
        file('hello', 'w').write('hello world')
 
405
        with open('hello', 'w') as f: f.write('hello world')
368
406
        wt.add('hello')
369
 
        file('goodbye', 'w').write('goodbye cruel world!')
 
407
        with open('goodbye', 'w') as f: f.write('goodbye cruel world!')
370
408
        wt.commit(message='add hello but not goodbye', strict=False)
371
409
 
372
410
    def test_nonstrict_commit_without_unknowns(self):
374
412
        should work."""
375
413
        wt = self.make_branch_and_tree('.')
376
414
        b = wt.branch
377
 
        file('hello', 'w').write('hello world')
 
415
        with open('hello', 'w') as f: f.write('hello world')
378
416
        wt.add('hello')
379
417
        wt.commit(message='add hello', strict=False)
380
418
 
381
419
    def test_signed_commit(self):
382
 
        import bzrlib.gpg
383
 
        import bzrlib.commit as commit
384
 
        oldstrategy = bzrlib.gpg.GPGStrategy
 
420
        import breezy.gpg
 
421
        import breezy.commit as commit
 
422
        oldstrategy = breezy.gpg.GPGStrategy
385
423
        wt = self.make_branch_and_tree('.')
386
424
        branch = wt.branch
387
425
        wt.commit("base", allow_pointless=True, rev_id='A')
388
 
        self.failIf(branch.repository.has_signature_for_revision_id('A'))
 
426
        self.assertFalse(branch.repository.has_signature_for_revision_id('A'))
389
427
        try:
390
 
            from bzrlib.testament import Testament
 
428
            from ..testament import Testament
391
429
            # monkey patch gpg signing mechanism
392
 
            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)
 
430
            breezy.gpg.GPGStrategy = breezy.gpg.LoopbackGPGStrategy
 
431
            conf = config.MemoryStack('''
 
432
create_signatures=always
 
433
''')
 
434
            commit.Commit(config_stack=conf).commit(
 
435
                message="base", allow_pointless=True, rev_id='B',
 
436
                working_tree=wt)
397
437
            def sign(text):
398
 
                return bzrlib.gpg.LoopbackGPGStrategy(None).sign(text)
 
438
                return breezy.gpg.LoopbackGPGStrategy(None).sign(text)
399
439
            self.assertEqual(sign(Testament.from_revision(branch.repository,
400
 
                             'B').as_short_text()),
 
440
                                                          'B').as_short_text()),
401
441
                             branch.repository.get_signature_text('B'))
402
442
        finally:
403
 
            bzrlib.gpg.GPGStrategy = oldstrategy
 
443
            breezy.gpg.GPGStrategy = oldstrategy
404
444
 
405
445
    def test_commit_failed_signature(self):
406
 
        import bzrlib.gpg
407
 
        import bzrlib.commit as commit
408
 
        oldstrategy = bzrlib.gpg.GPGStrategy
 
446
        import breezy.gpg
 
447
        import breezy.commit as commit
 
448
        oldstrategy = breezy.gpg.GPGStrategy
409
449
        wt = self.make_branch_and_tree('.')
410
450
        branch = wt.branch
411
451
        wt.commit("base", allow_pointless=True, rev_id='A')
412
 
        self.failIf(branch.repository.has_signature_for_revision_id('A'))
 
452
        self.assertFalse(branch.repository.has_signature_for_revision_id('A'))
413
453
        try:
414
 
            from bzrlib.testament import Testament
415
454
            # monkey patch gpg signing mechanism
416
 
            bzrlib.gpg.GPGStrategy = bzrlib.gpg.DisabledGPGStrategy
417
 
            config = MustSignConfig(branch)
418
 
            self.assertRaises(SigningFailed,
419
 
                              commit.Commit(config=config).commit,
 
455
            breezy.gpg.GPGStrategy = breezy.gpg.DisabledGPGStrategy
 
456
            conf = config.MemoryStack('''
 
457
create_signatures=always
 
458
''')
 
459
            self.assertRaises(breezy.gpg.SigningFailed,
 
460
                              commit.Commit(config_stack=conf).commit,
420
461
                              message="base",
421
462
                              allow_pointless=True,
422
463
                              rev_id='B',
423
464
                              working_tree=wt)
424
465
            branch = Branch.open(self.get_url('.'))
425
 
            self.assertEqual(branch.revision_history(), ['A'])
426
 
            self.failIf(branch.repository.has_revision('B'))
 
466
            self.assertEqual(branch.last_revision(), 'A')
 
467
            self.assertFalse(branch.repository.has_revision('B'))
427
468
        finally:
428
 
            bzrlib.gpg.GPGStrategy = oldstrategy
 
469
            breezy.gpg.GPGStrategy = oldstrategy
429
470
 
430
471
    def test_commit_invokes_hooks(self):
431
 
        import bzrlib.commit as commit
 
472
        import breezy.commit as commit
432
473
        wt = self.make_branch_and_tree('.')
433
474
        branch = wt.branch
434
475
        calls = []
435
476
        def called(branch, rev_id):
436
477
            calls.append('called')
437
 
        bzrlib.ahook = called
 
478
        breezy.ahook = called
438
479
        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)
 
480
            conf = config.MemoryStack('post_commit=breezy.ahook breezy.ahook')
 
481
            commit.Commit(config_stack=conf).commit(
 
482
                message = "base", allow_pointless=True, rev_id='A',
 
483
                working_tree = wt)
444
484
            self.assertEqual(['called', 'called'], calls)
445
485
        finally:
446
 
            del bzrlib.ahook
 
486
            del breezy.ahook
447
487
 
448
488
    def test_commit_object_doesnt_set_nick(self):
449
489
        # using the Commit object directly does not set the branch nick.
450
490
        wt = self.make_branch_and_tree('.')
451
491
        c = Commit()
452
492
        c.commit(working_tree=wt, message='empty tree', allow_pointless=True)
453
 
        self.assertEquals(wt.branch.revno(), 1)
 
493
        self.assertEqual(wt.branch.revno(), 1)
454
494
        self.assertEqual({},
455
495
                         wt.branch.repository.get_revision(
456
496
                            wt.branch.last_revision()).properties)
481
521
        bound_tree.add(['content_file'])
482
522
        bound_tree.commit(message='woo!')
483
523
 
484
 
        other_bzrdir = master_branch.bzrdir.sprout('other')
 
524
        other_bzrdir = master_branch.controldir.sprout('other')
485
525
        other_tree = other_bzrdir.open_workingtree()
486
526
 
487
527
        # do a commit to the other branch changing the content file so
528
568
            'filetoleave']
529
569
            )
530
570
        this_tree.commit('create_files')
531
 
        other_dir = this_tree.bzrdir.sprout('other')
 
571
        other_dir = this_tree.controldir.sprout('other')
532
572
        other_tree = other_dir.open_workingtree()
533
573
        other_tree.lock_write()
534
574
        # perform the needed actions on the files and dirs.
550
590
        this_tree.merge_from_branch(other_tree.branch)
551
591
        reporter = CapturingReporter()
552
592
        this_tree.commit('do the commit', reporter=reporter)
553
 
        expected = set([
 
593
        expected = {
554
594
            ('change', 'modified', 'filetomodify'),
555
595
            ('change', 'added', 'newdir'),
556
596
            ('change', 'added', 'newfile'),
560
600
            ('renamed', 'renamed', 'filetoreparent', 'renameddir/reparentedfile'),
561
601
            ('deleted', 'dirtoremove'),
562
602
            ('deleted', 'filetoremove'),
563
 
            ])
 
603
            }
564
604
        result = set(reporter.calls)
565
605
        missing = expected - result
566
606
        new = result - expected
575
615
        tree.remove(['a', 'b'])
576
616
        tree.commit('removed a', specific_files='a')
577
617
        basis = tree.basis_tree()
578
 
        tree.lock_read()
579
 
        try:
580
 
            self.assertIs(None, basis.path2id('a'))
581
 
            self.assertFalse(basis.path2id('b') is None)
582
 
        finally:
583
 
            tree.unlock()
 
618
        with tree.lock_read():
 
619
            self.assertFalse(basis.is_versioned('a'))
 
620
            self.assertTrue(basis.is_versioned('b'))
584
621
 
585
622
    def test_commit_saves_1ms_timestamp(self):
586
623
        """Passing in a timestamp is saved with 1ms resolution"""
605
642
        timestamp_1ms = round(timestamp, 3)
606
643
        self.assertEqual(timestamp_1ms, timestamp)
607
644
 
608
 
    def assertBasisTreeKind(self, kind, tree, file_id):
 
645
    def assertBasisTreeKind(self, kind, tree, path):
609
646
        basis = tree.basis_tree()
610
647
        basis.lock_read()
611
648
        try:
612
 
            self.assertEqual(kind, basis.kind(file_id))
 
649
            self.assertEqual(kind, basis.kind(path))
613
650
        finally:
614
651
            basis.unlock()
615
652
 
619
656
        os.symlink('target', 'name')
620
657
        tree.add('name', 'a-file-id')
621
658
        tree.commit('Added a symlink')
622
 
        self.assertBasisTreeKind('symlink', tree, 'a-file-id')
 
659
        self.assertBasisTreeKind('symlink', tree, 'name')
623
660
 
624
661
        os.unlink('name')
625
662
        self.build_tree(['name'])
626
663
        tree.commit('Changed symlink to file')
627
 
        self.assertBasisTreeKind('file', tree, 'a-file-id')
 
664
        self.assertBasisTreeKind('file', tree, 'name')
628
665
 
629
666
        os.unlink('name')
630
667
        os.symlink('target', 'name')
631
668
        tree.commit('file to symlink')
632
 
        self.assertBasisTreeKind('symlink', tree, 'a-file-id')
 
669
        self.assertBasisTreeKind('symlink', tree, 'name')
633
670
 
634
671
        os.unlink('name')
635
672
        os.mkdir('name')
636
673
        tree.commit('symlink to directory')
637
 
        self.assertBasisTreeKind('directory', tree, 'a-file-id')
 
674
        self.assertBasisTreeKind('directory', tree, 'name')
638
675
 
639
676
        os.rmdir('name')
640
677
        os.symlink('target', 'name')
641
678
        tree.commit('directory to symlink')
642
 
        self.assertBasisTreeKind('symlink', tree, 'a-file-id')
 
679
        self.assertBasisTreeKind('symlink', tree, 'name')
643
680
 
644
681
        # prepare for directory <-> file tests
645
682
        os.unlink('name')
646
683
        os.mkdir('name')
647
684
        tree.commit('symlink to directory')
648
 
        self.assertBasisTreeKind('directory', tree, 'a-file-id')
 
685
        self.assertBasisTreeKind('directory', tree, 'name')
649
686
 
650
687
        os.rmdir('name')
651
688
        self.build_tree(['name'])
652
689
        tree.commit('Changed directory to file')
653
 
        self.assertBasisTreeKind('file', tree, 'a-file-id')
 
690
        self.assertBasisTreeKind('file', tree, 'name')
654
691
 
655
692
        os.unlink('name')
656
693
        os.mkdir('name')
657
694
        tree.commit('file to directory')
658
 
        self.assertBasisTreeKind('directory', tree, 'a-file-id')
 
695
        self.assertBasisTreeKind('directory', tree, 'name')
659
696
 
660
697
    def test_commit_unversioned_specified(self):
661
698
        """Commit should raise if specified files isn't in basis or worktree"""
681
718
        tree = self.make_branch_and_tree('.')
682
719
        try:
683
720
            tree.commit()
684
 
        except Exception, e:
 
721
        except Exception as e:
685
722
            self.assertTrue(isinstance(e, BzrError))
686
723
            self.assertEqual('The message or message_callback keyword'
687
724
                             ' parameter is required for commit().', str(e))
723
760
        tree.add_parent_tree_id('example')
724
761
        self.build_tree(['foo/bar', 'foo/baz'])
725
762
        tree.add(['bar', 'baz'])
726
 
        err = self.assertRaises(errors.CannotCommitSelectedFileMerge,
 
763
        err = self.assertRaises(CannotCommitSelectedFileMerge,
727
764
            tree.commit, 'commit 2', specific_files=['bar', 'baz'])
728
765
        self.assertEqual(['bar', 'baz'], err.files)
729
766
        self.assertEqual('Selected-file commit of merges is not supported'
751
788
        self.assertFalse('authors' in rev.properties)
752
789
 
753
790
    def test_commit_author(self):
754
 
        """Passing a non-empty author kwarg to MutableTree.commit should add
 
791
        """Passing a non-empty authors kwarg to MutableTree.commit should add
755
792
        the 'author' revision property.
756
793
        """
757
794
        tree = self.make_branch_and_tree('foo')
758
 
        rev_id = self.callDeprecated(['The parameter author was '
759
 
                'deprecated in version 1.13. Use authors instead'],
760
 
                tree.commit, 'commit 1', author='John Doe <jdoe@example.com>')
 
795
        rev_id = tree.commit(
 
796
            'commit 1',
 
797
            authors=['John Doe <jdoe@example.com>'])
761
798
        rev = tree.branch.repository.get_revision(rev_id)
762
799
        self.assertEqual('John Doe <jdoe@example.com>',
763
800
                         rev.properties['authors'])
781
818
                'Jane Rey <jrey@example.com>', rev.properties['authors'])
782
819
        self.assertFalse('author' in rev.properties)
783
820
 
784
 
    def test_author_and_authors_incompatible(self):
785
 
        tree = self.make_branch_and_tree('foo')
786
 
        self.assertRaises(AssertionError, tree.commit, 'commit 1',
787
 
                authors=['John Doe <jdoe@example.com>',
788
 
                         'Jane Rey <jrey@example.com>'],
789
 
                author="Jack Me <jme@example.com>")
790
 
 
791
821
    def test_author_with_newline_rejected(self):
792
822
        tree = self.make_branch_and_tree('foo')
793
823
        self.assertRaises(AssertionError, tree.commit, 'commit 1',
796
826
    def test_commit_with_checkout_and_branch_sharing_repo(self):
797
827
        repo = self.make_repository('repo', shared=True)
798
828
        # make_branch_and_tree ignores shared repos
799
 
        branch = bzrdir.BzrDir.create_branch_convenience('repo/branch')
 
829
        branch = controldir.ControlDir.create_branch_convenience('repo/branch')
800
830
        tree2 = branch.create_checkout('repo/tree2')
801
831
        tree2.commit('message', rev_id='rev1')
802
832
        self.assertTrue(tree2.branch.repository.has_revision('rev1'))
 
833
 
 
834
 
 
835
class FilterExcludedTests(TestCase):
 
836
 
 
837
    def test_add_file_not_excluded(self):
 
838
        changes = [
 
839
            ('fid', (None, 'newpath'),
 
840
             0, (False, False), ('pid', 'pid'), ('newpath', 'newpath'),
 
841
             ('file', 'file'), (True, True))]
 
842
        self.assertEqual(changes, list(filter_excluded(changes, ['otherpath'])))
 
843
 
 
844
    def test_add_file_excluded(self):
 
845
        changes = [
 
846
            ('fid', (None, 'newpath'),
 
847
             0, (False, False), ('pid', 'pid'), ('newpath', 'newpath'),
 
848
             ('file', 'file'), (True, True))]
 
849
        self.assertEqual([], list(filter_excluded(changes, ['newpath'])))
 
850
 
 
851
    def test_delete_file_excluded(self):
 
852
        changes = [
 
853
            ('fid', ('somepath', None),
 
854
             0, (False, None), ('pid', None), ('newpath', None),
 
855
             ('file', None), (True, None))]
 
856
        self.assertEqual([], list(filter_excluded(changes, ['somepath'])))
 
857
 
 
858
    def test_move_from_or_to_excluded(self):
 
859
        changes = [
 
860
            ('fid', ('oldpath', 'newpath'),
 
861
             0, (False, False), ('pid', 'pid'), ('oldpath', 'newpath'),
 
862
             ('file', 'file'), (True, True))]
 
863
        self.assertEqual([], list(filter_excluded(changes, ['oldpath'])))
 
864
        self.assertEqual([], list(filter_excluded(changes, ['newpath'])))