~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_commit.py

  • Committer: Tarmac
  • Author(s): Vincent Ladeuil
  • Date: 2017-01-30 14:42:05 UTC
  • mfrom: (6620.1.1 trunk)
  • Revision ID: tarmac-20170130144205-r8fh2xpmiuxyozpv
Merge  2.7 into trunk including fix for bug #1657238 [r=vila]

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005-2011 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
19
19
 
20
20
import bzrlib
21
21
from bzrlib import (
22
 
    bzrdir,
 
22
    config,
 
23
    controldir,
23
24
    errors,
24
25
    )
25
26
from bzrlib.branch import Branch
26
27
from bzrlib.bzrdir import BzrDirMetaFormat1
27
28
from bzrlib.commit import Commit, NullCommitReporter
28
 
from bzrlib.config import BranchConfig
29
29
from bzrlib.errors import (
30
30
    PointlessCommit,
31
31
    BzrError,
33
33
    LockContention,
34
34
    )
35
35
from bzrlib.tests import (
36
 
    SymlinkFeature,
37
36
    TestCaseWithTransport,
38
37
    test_foreign,
39
38
    )
 
39
from bzrlib.tests.features import (
 
40
    SymlinkFeature,
 
41
    )
40
42
from bzrlib.tests.matchers import MatchesAncestry
41
43
 
42
44
 
43
45
# TODO: Test commit with some added, and added-but-missing files
44
46
 
45
 
class MustSignConfig(BranchConfig):
46
 
 
47
 
    def signature_needed(self):
48
 
        return True
49
 
 
50
 
    def gpg_signing_command(self):
51
 
        return ['cat', '-']
52
 
 
53
 
 
54
 
class BranchWithHooks(BranchConfig):
55
 
 
56
 
    def post_commit(self):
57
 
        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
''')
58
54
 
59
55
 
60
56
class CapturingReporter(NullCommitReporter):
86
82
        """Commit and check two versions of a single file."""
87
83
        wt = self.make_branch_and_tree('.')
88
84
        b = wt.branch
89
 
        file('hello', 'w').write('hello world')
 
85
        with file('hello', 'w') as f: f.write('hello world')
90
86
        wt.add('hello')
91
 
        wt.commit(message='add hello')
 
87
        rev1 = wt.commit(message='add hello')
92
88
        file_id = wt.path2id('hello')
93
89
 
94
 
        file('hello', 'w').write('version 2')
95
 
        wt.commit(message='commit 2')
 
90
        with file('hello', 'w') as f: f.write('version 2')
 
91
        rev2 = wt.commit(message='commit 2')
96
92
 
97
 
        eq = self.assertEquals
 
93
        eq = self.assertEqual
98
94
        eq(b.revno(), 2)
99
 
        rh = b.revision_history()
100
 
        rev = b.repository.get_revision(rh[0])
 
95
        rev = b.repository.get_revision(rev1)
101
96
        eq(rev.message, 'add hello')
102
97
 
103
 
        tree1 = b.repository.revision_tree(rh[0])
 
98
        tree1 = b.repository.revision_tree(rev1)
104
99
        tree1.lock_read()
105
100
        text = tree1.get_file_text(file_id)
106
101
        tree1.unlock()
107
102
        self.assertEqual('hello world', text)
108
103
 
109
 
        tree2 = b.repository.revision_tree(rh[1])
 
104
        tree2 = b.repository.revision_tree(rev2)
110
105
        tree2.lock_read()
111
106
        text = tree2.get_file_text(file_id)
112
107
        tree2.unlock()
116
111
        """Attempt a lossy commit to a native branch."""
117
112
        wt = self.make_branch_and_tree('.')
118
113
        b = wt.branch
119
 
        file('hello', 'w').write('hello world')
 
114
        with file('hello', 'w') as f: f.write('hello world')
120
115
        wt.add('hello')
121
116
        revid = wt.commit(message='add hello', rev_id='revid', lossy=True)
122
 
        self.assertEquals('revid', revid)
 
117
        self.assertEqual('revid', revid)
123
118
 
124
119
    def test_commit_lossy_foreign(self):
125
120
        """Attempt a lossy commit to a foreign branch."""
127
122
        wt = self.make_branch_and_tree('.',
128
123
            format=test_foreign.DummyForeignVcsDirFormat())
129
124
        b = wt.branch
130
 
        file('hello', 'w').write('hello world')
 
125
        with file('hello', 'w') as f: f.write('hello world')
131
126
        wt.add('hello')
132
127
        revid = wt.commit(message='add hello', lossy=True,
133
128
            timestamp=1302659388, timezone=0)
134
 
        self.assertEquals('dummy-v1:1302659388.0-0-UNKNOWN', revid)
 
129
        self.assertEqual('dummy-v1:1302659388.0-0-UNKNOWN', revid)
135
130
 
136
131
    def test_commit_bound_lossy_foreign(self):
137
132
        """Attempt a lossy commit to a bzr branch bound to a foreign branch."""
140
135
            format=test_foreign.DummyForeignVcsDirFormat())
141
136
        wt = foreign_branch.create_checkout("local")
142
137
        b = wt.branch
143
 
        file('local/hello', 'w').write('hello world')
 
138
        with file('local/hello', 'w') as f: f.write('hello world')
144
139
        wt.add('hello')
145
140
        revid = wt.commit(message='add hello', lossy=True,
146
141
            timestamp=1302659388, timezone=0)
147
 
        self.assertEquals('dummy-v1:1302659388.0-0-0', revid)
148
 
        self.assertEquals('dummy-v1:1302659388.0-0-0',
 
142
        self.assertEqual('dummy-v1:1302659388.0-0-0', revid)
 
143
        self.assertEqual('dummy-v1:1302659388.0-0-0',
149
144
            foreign_branch.last_revision())
150
 
        self.assertEquals('dummy-v1:1302659388.0-0-0',
 
145
        self.assertEqual('dummy-v1:1302659388.0-0-0',
151
146
            wt.branch.last_revision())
152
147
 
153
148
    def test_missing_commit(self):
154
149
        """Test a commit with a missing file"""
155
150
        wt = self.make_branch_and_tree('.')
156
151
        b = wt.branch
157
 
        file('hello', 'w').write('hello world')
 
152
        with file('hello', 'w') as f: f.write('hello world')
158
153
        wt.add(['hello'], ['hello-id'])
159
154
        wt.commit(message='add hello')
160
155
 
161
156
        os.remove('hello')
162
 
        wt.commit('removed hello', rev_id='rev2')
 
157
        reporter = CapturingReporter()
 
158
        wt.commit('removed hello', rev_id='rev2', reporter=reporter)
 
159
        self.assertEqual(
 
160
            [('missing', u'hello'), ('deleted', u'hello')],
 
161
            reporter.calls)
163
162
 
164
163
        tree = b.repository.revision_tree('rev2')
165
164
        self.assertFalse(tree.has_id('hello-id'))
188
187
        """Commit refuses unless there are changes or it's forced."""
189
188
        wt = self.make_branch_and_tree('.')
190
189
        b = wt.branch
191
 
        file('hello', 'w').write('hello')
 
190
        with file('hello', 'w') as f: f.write('hello')
192
191
        wt.add(['hello'])
193
192
        wt.commit(message='add hello')
194
 
        self.assertEquals(b.revno(), 1)
 
193
        self.assertEqual(b.revno(), 1)
195
194
        self.assertRaises(PointlessCommit,
196
195
                          wt.commit,
197
196
                          message='fails',
198
197
                          allow_pointless=False)
199
 
        self.assertEquals(b.revno(), 1)
 
198
        self.assertEqual(b.revno(), 1)
200
199
 
201
200
    def test_commit_empty(self):
202
201
        """Commiting an empty tree works."""
208
207
                          message='empty tree',
209
208
                          allow_pointless=False)
210
209
        wt.commit(message='empty tree', allow_pointless=True)
211
 
        self.assertEquals(b.revno(), 2)
 
210
        self.assertEqual(b.revno(), 2)
212
211
 
213
212
    def test_selective_delete(self):
214
213
        """Selective commit in tree with deletions"""
215
214
        wt = self.make_branch_and_tree('.')
216
215
        b = wt.branch
217
 
        file('hello', 'w').write('hello')
218
 
        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')
219
218
        wt.add(['hello', 'buongia'],
220
219
              ['hello-id', 'buongia-id'])
221
220
        wt.commit(message='add files',
222
221
                 rev_id='test@rev-1')
223
222
 
224
223
        os.remove('hello')
225
 
        file('buongia', 'w').write('new text')
 
224
        with file('buongia', 'w') as f: f.write('new text')
226
225
        wt.commit(message='update text',
227
226
                 specific_files=['buongia'],
228
227
                 allow_pointless=False,
233
232
                 allow_pointless=False,
234
233
                 rev_id='test@rev-3')
235
234
 
236
 
        eq = self.assertEquals
 
235
        eq = self.assertEqual
237
236
        eq(b.revno(), 3)
238
237
 
239
238
        tree2 = b.repository.revision_tree('test@rev-2')
240
239
        tree2.lock_read()
241
240
        self.addCleanup(tree2.unlock)
242
241
        self.assertTrue(tree2.has_filename('hello'))
243
 
        self.assertEquals(tree2.get_file_text('hello-id'), 'hello')
244
 
        self.assertEquals(tree2.get_file_text('buongia-id'), 'new text')
 
242
        self.assertEqual(tree2.get_file_text('hello-id'), 'hello')
 
243
        self.assertEqual(tree2.get_file_text('buongia-id'), 'new text')
245
244
 
246
245
        tree3 = b.repository.revision_tree('test@rev-3')
247
246
        tree3.lock_read()
248
247
        self.addCleanup(tree3.unlock)
249
248
        self.assertFalse(tree3.has_filename('hello'))
250
 
        self.assertEquals(tree3.get_file_text('buongia-id'), 'new text')
 
249
        self.assertEqual(tree3.get_file_text('buongia-id'), 'new text')
251
250
 
252
251
    def test_commit_rename(self):
253
252
        """Test commit of a revision where a file is renamed."""
260
259
        tree.rename_one('hello', 'fruity')
261
260
        tree.commit(message='renamed', rev_id='test@rev-2', allow_pointless=False)
262
261
 
263
 
        eq = self.assertEquals
 
262
        eq = self.assertEqual
264
263
        tree1 = b.repository.revision_tree('test@rev-1')
265
264
        tree1.lock_read()
266
265
        self.addCleanup(tree1.unlock)
291
290
 
292
291
    def test_commit_move(self):
293
292
        """Test commit of revisions with moved files and directories"""
294
 
        eq = self.assertEquals
 
293
        eq = self.assertEqual
295
294
        wt = self.make_branch_and_tree('.')
296
295
        b = wt.branch
297
296
        r1 = 'test@rev-1'
337
336
        """Commit with a removed file"""
338
337
        wt = self.make_branch_and_tree('.')
339
338
        b = wt.branch
340
 
        file('hello', 'w').write('hello world')
 
339
        with file('hello', 'w') as f: f.write('hello world')
341
340
        wt.add(['hello'], ['hello-id'])
342
341
        wt.commit(message='add hello')
343
342
        wt.remove('hello')
352
351
        b = wt.branch
353
352
        rev_ids = []
354
353
        for i in range(4):
355
 
            file('hello', 'w').write((str(i) * 4) + '\n')
 
354
            with file('hello', 'w') as f: f.write((str(i) * 4) + '\n')
356
355
            if i == 0:
357
356
                wt.add(['hello'], ['hello-id'])
358
357
            rev_id = 'test@rev-%d' % (i+1)
359
358
            rev_ids.append(rev_id)
360
359
            wt.commit(message='rev %d' % (i+1),
361
360
                     rev_id=rev_id)
362
 
        eq = self.assertEquals
363
 
        eq(b.revision_history(), rev_ids)
364
361
        for i in range(4):
365
362
            self.assertThat(rev_ids[:i+1],
366
363
                MatchesAncestry(b.repository, rev_ids[i]))
383
380
        from bzrlib.errors import StrictCommitFailed
384
381
        wt = self.make_branch_and_tree('.')
385
382
        b = wt.branch
386
 
        file('hello', 'w').write('hello world')
 
383
        with file('hello', 'w') as f: f.write('hello world')
387
384
        wt.add('hello')
388
 
        file('goodbye', 'w').write('goodbye cruel world!')
 
385
        with file('goodbye', 'w') as f: f.write('goodbye cruel world!')
389
386
        self.assertRaises(StrictCommitFailed, wt.commit,
390
387
            message='add hello but not goodbye', strict=True)
391
388
 
394
391
        should work."""
395
392
        wt = self.make_branch_and_tree('.')
396
393
        b = wt.branch
397
 
        file('hello', 'w').write('hello world')
 
394
        with file('hello', 'w') as f: f.write('hello world')
398
395
        wt.add('hello')
399
396
        wt.commit(message='add hello', strict=True)
400
397
 
402
399
        """Try and commit with unknown files and strict = False, should work."""
403
400
        wt = self.make_branch_and_tree('.')
404
401
        b = wt.branch
405
 
        file('hello', 'w').write('hello world')
 
402
        with file('hello', 'w') as f: f.write('hello world')
406
403
        wt.add('hello')
407
 
        file('goodbye', 'w').write('goodbye cruel world!')
 
404
        with file('goodbye', 'w') as f: f.write('goodbye cruel world!')
408
405
        wt.commit(message='add hello but not goodbye', strict=False)
409
406
 
410
407
    def test_nonstrict_commit_without_unknowns(self):
412
409
        should work."""
413
410
        wt = self.make_branch_and_tree('.')
414
411
        b = wt.branch
415
 
        file('hello', 'w').write('hello world')
 
412
        with file('hello', 'w') as f: f.write('hello world')
416
413
        wt.add('hello')
417
414
        wt.commit(message='add hello', strict=False)
418
415
 
428
425
            from bzrlib.testament import Testament
429
426
            # monkey patch gpg signing mechanism
430
427
            bzrlib.gpg.GPGStrategy = bzrlib.gpg.LoopbackGPGStrategy
431
 
            commit.Commit(config=MustSignConfig(branch)).commit(message="base",
432
 
                                                      allow_pointless=True,
433
 
                                                      rev_id='B',
434
 
                                                      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)
435
435
            def sign(text):
436
436
                return bzrlib.gpg.LoopbackGPGStrategy(None).sign(text)
437
437
            self.assertEqual(sign(Testament.from_revision(branch.repository,
438
 
                             'B').as_short_text()),
 
438
                                                          'B').as_short_text()),
439
439
                             branch.repository.get_signature_text('B'))
440
440
        finally:
441
441
            bzrlib.gpg.GPGStrategy = oldstrategy
451
451
        try:
452
452
            # monkey patch gpg signing mechanism
453
453
            bzrlib.gpg.GPGStrategy = bzrlib.gpg.DisabledGPGStrategy
454
 
            config = MustSignConfig(branch)
 
454
            conf = config.MemoryStack('''
 
455
gpg_signing_command=cat -
 
456
create_signatures=always
 
457
''')
455
458
            self.assertRaises(SigningFailed,
456
 
                              commit.Commit(config=config).commit,
 
459
                              commit.Commit(config_stack=conf).commit,
457
460
                              message="base",
458
461
                              allow_pointless=True,
459
462
                              rev_id='B',
460
463
                              working_tree=wt)
461
464
            branch = Branch.open(self.get_url('.'))
462
 
            self.assertEqual(branch.revision_history(), ['A'])
 
465
            self.assertEqual(branch.last_revision(), 'A')
463
466
            self.assertFalse(branch.repository.has_revision('B'))
464
467
        finally:
465
468
            bzrlib.gpg.GPGStrategy = oldstrategy
473
476
            calls.append('called')
474
477
        bzrlib.ahook = called
475
478
        try:
476
 
            config = BranchWithHooks(branch)
477
 
            commit.Commit(config=config).commit(
478
 
                            message = "base",
479
 
                            allow_pointless=True,
480
 
                            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)
481
483
            self.assertEqual(['called', 'called'], calls)
482
484
        finally:
483
485
            del bzrlib.ahook
487
489
        wt = self.make_branch_and_tree('.')
488
490
        c = Commit()
489
491
        c.commit(working_tree=wt, message='empty tree', allow_pointless=True)
490
 
        self.assertEquals(wt.branch.revno(), 1)
 
492
        self.assertEqual(wt.branch.revno(), 1)
491
493
        self.assertEqual({},
492
494
                         wt.branch.repository.get_revision(
493
495
                            wt.branch.last_revision()).properties)
833
835
    def test_commit_with_checkout_and_branch_sharing_repo(self):
834
836
        repo = self.make_repository('repo', shared=True)
835
837
        # make_branch_and_tree ignores shared repos
836
 
        branch = bzrdir.BzrDir.create_branch_convenience('repo/branch')
 
838
        branch = controldir.ControlDir.create_branch_convenience('repo/branch')
837
839
        tree2 = branch.create_checkout('repo/tree2')
838
840
        tree2.commit('message', rev_id='rev1')
839
841
        self.assertTrue(tree2.branch.repository.has_revision('rev1'))