~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_commit.py

  • Committer: John Arbash Meinel
  • Date: 2008-03-04 14:25:46 UTC
  • mto: This revision was merged to the branch mainline in revision 3279.
  • Revision ID: john@arbash-meinel.com-20080304142546-zuwwy0o9roo14928
Implement cherrypick support for Merge3
When merging a cherrypick, use a slightly different resolve logic.
When encountering a conflict, the new logic does not include lines that
were present in BASE that are conflicting with OTHER.
This is done since a cherrypick is (by definition) avoiding changes that
are present in the base.
(related to bug #151731)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005-2012, 2016 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
 
    config,
23
 
    controldir,
 
22
    bzrdir,
24
23
    errors,
 
24
    lockdir,
 
25
    osutils,
 
26
    tests,
25
27
    )
26
28
from bzrlib.branch import Branch
27
 
from bzrlib.bzrdir import BzrDirMetaFormat1
 
29
from bzrlib.bzrdir import BzrDir, BzrDirMetaFormat1
28
30
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
 
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
43
36
 
44
37
 
45
38
# TODO: Test commit with some added, and added-but-missing files
46
39
 
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
 
''')
 
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"
54
53
 
55
54
 
56
55
class CapturingReporter(NullCommitReporter):
82
81
        """Commit and check two versions of a single file."""
83
82
        wt = self.make_branch_and_tree('.')
84
83
        b = wt.branch
85
 
        with file('hello', 'w') as f: f.write('hello world')
 
84
        file('hello', 'w').write('hello world')
86
85
        wt.add('hello')
87
 
        rev1 = wt.commit(message='add hello')
 
86
        wt.commit(message='add hello')
88
87
        file_id = wt.path2id('hello')
89
88
 
90
 
        with file('hello', 'w') as f: f.write('version 2')
91
 
        rev2 = wt.commit(message='commit 2')
 
89
        file('hello', 'w').write('version 2')
 
90
        wt.commit(message='commit 2')
92
91
 
93
 
        eq = self.assertEqual
 
92
        eq = self.assertEquals
94
93
        eq(b.revno(), 2)
95
 
        rev = b.repository.get_revision(rev1)
 
94
        rh = b.revision_history()
 
95
        rev = b.repository.get_revision(rh[0])
96
96
        eq(rev.message, 'add hello')
97
97
 
98
 
        tree1 = b.repository.revision_tree(rev1)
 
98
        tree1 = b.repository.revision_tree(rh[0])
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(rev2)
 
104
        tree2 = b.repository.revision_tree(rh[1])
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_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.assertEqual('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.assertEqual('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.assertEqual('dummy-v1:1302659388.0-0-0', revid)
143
 
        self.assertEqual('dummy-v1:1302659388.0-0-0',
144
 
            foreign_branch.last_revision())
145
 
        self.assertEqual('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')
 
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')
153
115
        wt.add(['hello'], ['hello-id'])
154
116
        wt.commit(message='add hello')
155
117
 
156
118
        os.remove('hello')
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)
 
119
        wt.commit('removed hello', rev_id='rev2')
162
120
 
163
121
        tree = b.repository.revision_tree('rev2')
164
122
        self.assertFalse(tree.has_id('hello-id'))
165
123
 
166
 
    def test_partial_commit_move(self):
167
 
        """Test a partial commit where a file was renamed but not committed.
168
 
 
169
 
        https://bugs.launchpad.net/bzr/+bug/83039
170
 
 
171
 
        If not handled properly, commit will try to snapshot
172
 
        dialog.py with olive/ as a parent, while
173
 
        olive/ has not been snapshotted yet.
174
 
        """
175
 
        wt = self.make_branch_and_tree('.')
176
 
        b = wt.branch
177
 
        self.build_tree(['annotate/', 'annotate/foo.py',
178
 
                         'olive/', 'olive/dialog.py'
179
 
                        ])
180
 
        wt.add(['annotate', 'olive', 'annotate/foo.py', 'olive/dialog.py'])
181
 
        wt.commit(message='add files')
182
 
        wt.rename_one("olive/dialog.py", "aaa")
183
 
        self.build_tree_contents([('annotate/foo.py', 'modified\n')])
184
 
        wt.commit('renamed hello', specific_files=["annotate"])
185
 
 
186
124
    def test_pointless_commit(self):
187
125
        """Commit refuses unless there are changes or it's forced."""
188
126
        wt = self.make_branch_and_tree('.')
189
127
        b = wt.branch
190
 
        with file('hello', 'w') as f: f.write('hello')
 
128
        file('hello', 'w').write('hello')
191
129
        wt.add(['hello'])
192
130
        wt.commit(message='add hello')
193
 
        self.assertEqual(b.revno(), 1)
 
131
        self.assertEquals(b.revno(), 1)
194
132
        self.assertRaises(PointlessCommit,
195
133
                          wt.commit,
196
134
                          message='fails',
197
135
                          allow_pointless=False)
198
 
        self.assertEqual(b.revno(), 1)
199
 
 
 
136
        self.assertEquals(b.revno(), 1)
 
137
        
200
138
    def test_commit_empty(self):
201
139
        """Commiting an empty tree works."""
202
140
        wt = self.make_branch_and_tree('.')
207
145
                          message='empty tree',
208
146
                          allow_pointless=False)
209
147
        wt.commit(message='empty tree', allow_pointless=True)
210
 
        self.assertEqual(b.revno(), 2)
 
148
        self.assertEquals(b.revno(), 2)
211
149
 
212
150
    def test_selective_delete(self):
213
151
        """Selective commit in tree with deletions"""
214
152
        wt = self.make_branch_and_tree('.')
215
153
        b = wt.branch
216
 
        with file('hello', 'w') as f: f.write('hello')
217
 
        with file('buongia', 'w') as f: f.write('buongia')
 
154
        file('hello', 'w').write('hello')
 
155
        file('buongia', 'w').write('buongia')
218
156
        wt.add(['hello', 'buongia'],
219
157
              ['hello-id', 'buongia-id'])
220
158
        wt.commit(message='add files',
221
159
                 rev_id='test@rev-1')
222
 
 
 
160
        
223
161
        os.remove('hello')
224
 
        with file('buongia', 'w') as f: f.write('new text')
 
162
        file('buongia', 'w').write('new text')
225
163
        wt.commit(message='update text',
226
164
                 specific_files=['buongia'],
227
165
                 allow_pointless=False,
232
170
                 allow_pointless=False,
233
171
                 rev_id='test@rev-3')
234
172
 
235
 
        eq = self.assertEqual
 
173
        eq = self.assertEquals
236
174
        eq(b.revno(), 3)
237
175
 
238
176
        tree2 = b.repository.revision_tree('test@rev-2')
239
177
        tree2.lock_read()
240
178
        self.addCleanup(tree2.unlock)
241
179
        self.assertTrue(tree2.has_filename('hello'))
242
 
        self.assertEqual(tree2.get_file_text('hello-id'), 'hello')
243
 
        self.assertEqual(tree2.get_file_text('buongia-id'), 'new text')
244
 
 
 
180
        self.assertEquals(tree2.get_file_text('hello-id'), 'hello')
 
181
        self.assertEquals(tree2.get_file_text('buongia-id'), 'new text')
 
182
        
245
183
        tree3 = b.repository.revision_tree('test@rev-3')
246
184
        tree3.lock_read()
247
185
        self.addCleanup(tree3.unlock)
248
186
        self.assertFalse(tree3.has_filename('hello'))
249
 
        self.assertEqual(tree3.get_file_text('buongia-id'), 'new text')
 
187
        self.assertEquals(tree3.get_file_text('buongia-id'), 'new text')
250
188
 
251
189
    def test_commit_rename(self):
252
190
        """Test commit of a revision where a file is renamed."""
259
197
        tree.rename_one('hello', 'fruity')
260
198
        tree.commit(message='renamed', rev_id='test@rev-2', allow_pointless=False)
261
199
 
262
 
        eq = self.assertEqual
 
200
        eq = self.assertEquals
263
201
        tree1 = b.repository.revision_tree('test@rev-1')
264
202
        tree1.lock_read()
265
203
        self.addCleanup(tree1.unlock)
266
204
        eq(tree1.id2path('hello-id'), 'hello')
267
205
        eq(tree1.get_file_text('hello-id'), 'contents of hello\n')
268
206
        self.assertFalse(tree1.has_filename('fruity'))
269
 
        self.check_tree_shape(tree1, ['hello'])
270
 
        eq(tree1.get_file_revision('hello-id'), 'test@rev-1')
 
207
        self.check_inventory_shape(tree1.inventory, ['hello'])
 
208
        ie = tree1.inventory['hello-id']
 
209
        eq(ie.revision, 'test@rev-1')
271
210
 
272
211
        tree2 = b.repository.revision_tree('test@rev-2')
273
212
        tree2.lock_read()
274
213
        self.addCleanup(tree2.unlock)
275
214
        eq(tree2.id2path('hello-id'), 'fruity')
276
215
        eq(tree2.get_file_text('hello-id'), 'contents of hello\n')
277
 
        self.check_tree_shape(tree2, ['fruity'])
278
 
        eq(tree2.get_file_revision('hello-id'), 'test@rev-2')
 
216
        self.check_inventory_shape(tree2.inventory, ['fruity'])
 
217
        ie = tree2.inventory['hello-id']
 
218
        eq(ie.revision, 'test@rev-2')
279
219
 
280
220
    def test_reused_rev_id(self):
281
221
        """Test that a revision id cannot be reused in a branch"""
290
230
 
291
231
    def test_commit_move(self):
292
232
        """Test commit of revisions with moved files and directories"""
293
 
        eq = self.assertEqual
 
233
        eq = self.assertEquals
294
234
        wt = self.make_branch_and_tree('.')
295
235
        b = wt.branch
296
236
        r1 = 'test@rev-1'
302
242
        wt.commit('two', rev_id=r2, allow_pointless=False)
303
243
        wt.lock_read()
304
244
        try:
305
 
            self.check_tree_shape(wt, ['a/', 'a/hello', 'b/'])
 
245
            self.check_inventory_shape(wt.read_working_inventory(),
 
246
                                       ['a/', 'a/hello', 'b/'])
306
247
        finally:
307
248
            wt.unlock()
308
249
 
311
252
        wt.commit('three', rev_id=r3, allow_pointless=False)
312
253
        wt.lock_read()
313
254
        try:
314
 
            self.check_tree_shape(wt,
 
255
            self.check_inventory_shape(wt.read_working_inventory(),
315
256
                                       ['a/', 'a/hello', 'a/b/'])
316
 
            self.check_tree_shape(b.repository.revision_tree(r3),
 
257
            self.check_inventory_shape(b.repository.get_revision_inventory(r3),
317
258
                                       ['a/', 'a/hello', 'a/b/'])
318
259
        finally:
319
260
            wt.unlock()
323
264
        wt.commit('four', rev_id=r4, allow_pointless=False)
324
265
        wt.lock_read()
325
266
        try:
326
 
            self.check_tree_shape(wt, ['a/', 'a/b/hello', 'a/b/'])
 
267
            self.check_inventory_shape(wt.read_working_inventory(),
 
268
                                       ['a/', 'a/b/hello', 'a/b/'])
327
269
        finally:
328
270
            wt.unlock()
329
271
 
330
 
        inv = b.repository.get_inventory(r4)
 
272
        inv = b.repository.get_revision_inventory(r4)
331
273
        eq(inv['hello-id'].revision, r4)
332
274
        eq(inv['a-id'].revision, r1)
333
275
        eq(inv['b-id'].revision, r3)
336
278
        """Commit with a removed file"""
337
279
        wt = self.make_branch_and_tree('.')
338
280
        b = wt.branch
339
 
        with file('hello', 'w') as f: f.write('hello world')
 
281
        file('hello', 'w').write('hello world')
340
282
        wt.add(['hello'], ['hello-id'])
341
283
        wt.commit(message='add hello')
342
284
        wt.remove('hello')
351
293
        b = wt.branch
352
294
        rev_ids = []
353
295
        for i in range(4):
354
 
            with file('hello', 'w') as f: f.write((str(i) * 4) + '\n')
 
296
            file('hello', 'w').write((str(i) * 4) + '\n')
355
297
            if i == 0:
356
298
                wt.add(['hello'], ['hello-id'])
357
299
            rev_id = 'test@rev-%d' % (i+1)
358
300
            rev_ids.append(rev_id)
359
301
            wt.commit(message='rev %d' % (i+1),
360
302
                     rev_id=rev_id)
 
303
        eq = self.assertEquals
 
304
        eq(b.revision_history(), rev_ids)
361
305
        for i in range(4):
362
 
            self.assertThat(rev_ids[:i+1],
363
 
                MatchesAncestry(b.repository, rev_ids[i]))
 
306
            anc = b.repository.get_ancestry(rev_ids[i])
 
307
            eq(anc, [None] + rev_ids[:i+1])
364
308
 
365
309
    def test_commit_new_subdir_child_selective(self):
366
310
        wt = self.make_branch_and_tree('.')
380
324
        from bzrlib.errors import StrictCommitFailed
381
325
        wt = self.make_branch_and_tree('.')
382
326
        b = wt.branch
383
 
        with file('hello', 'w') as f: f.write('hello world')
 
327
        file('hello', 'w').write('hello world')
384
328
        wt.add('hello')
385
 
        with file('goodbye', 'w') as f: f.write('goodbye cruel world!')
 
329
        file('goodbye', 'w').write('goodbye cruel world!')
386
330
        self.assertRaises(StrictCommitFailed, wt.commit,
387
331
            message='add hello but not goodbye', strict=True)
388
332
 
389
333
    def test_strict_commit_without_unknowns(self):
390
334
        """Try and commit with no unknown files and strict = True,
391
335
        should work."""
 
336
        from bzrlib.errors import StrictCommitFailed
392
337
        wt = self.make_branch_and_tree('.')
393
338
        b = wt.branch
394
 
        with file('hello', 'w') as f: f.write('hello world')
 
339
        file('hello', 'w').write('hello world')
395
340
        wt.add('hello')
396
341
        wt.commit(message='add hello', strict=True)
397
342
 
399
344
        """Try and commit with unknown files and strict = False, should work."""
400
345
        wt = self.make_branch_and_tree('.')
401
346
        b = wt.branch
402
 
        with file('hello', 'w') as f: f.write('hello world')
 
347
        file('hello', 'w').write('hello world')
403
348
        wt.add('hello')
404
 
        with file('goodbye', 'w') as f: f.write('goodbye cruel world!')
 
349
        file('goodbye', 'w').write('goodbye cruel world!')
405
350
        wt.commit(message='add hello but not goodbye', strict=False)
406
351
 
407
352
    def test_nonstrict_commit_without_unknowns(self):
409
354
        should work."""
410
355
        wt = self.make_branch_and_tree('.')
411
356
        b = wt.branch
412
 
        with file('hello', 'w') as f: f.write('hello world')
 
357
        file('hello', 'w').write('hello world')
413
358
        wt.add('hello')
414
359
        wt.commit(message='add hello', strict=False)
415
360
 
420
365
        wt = self.make_branch_and_tree('.')
421
366
        branch = wt.branch
422
367
        wt.commit("base", allow_pointless=True, rev_id='A')
423
 
        self.assertFalse(branch.repository.has_signature_for_revision_id('A'))
 
368
        self.failIf(branch.repository.has_signature_for_revision_id('A'))
424
369
        try:
425
370
            from bzrlib.testament import Testament
426
371
            # monkey patch gpg signing mechanism
427
372
            bzrlib.gpg.GPGStrategy = bzrlib.gpg.LoopbackGPGStrategy
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)
 
373
            commit.Commit(config=MustSignConfig(branch)).commit(message="base",
 
374
                                                      allow_pointless=True,
 
375
                                                      rev_id='B',
 
376
                                                      working_tree=wt)
435
377
            def sign(text):
436
378
                return bzrlib.gpg.LoopbackGPGStrategy(None).sign(text)
437
379
            self.assertEqual(sign(Testament.from_revision(branch.repository,
438
 
                                                          'B').as_short_text()),
 
380
                             'B').as_short_text()),
439
381
                             branch.repository.get_signature_text('B'))
440
382
        finally:
441
383
            bzrlib.gpg.GPGStrategy = oldstrategy
447
389
        wt = self.make_branch_and_tree('.')
448
390
        branch = wt.branch
449
391
        wt.commit("base", allow_pointless=True, rev_id='A')
450
 
        self.assertFalse(branch.repository.has_signature_for_revision_id('A'))
 
392
        self.failIf(branch.repository.has_signature_for_revision_id('A'))
451
393
        try:
 
394
            from bzrlib.testament import Testament
452
395
            # monkey patch gpg signing mechanism
453
396
            bzrlib.gpg.GPGStrategy = bzrlib.gpg.DisabledGPGStrategy
454
 
            conf = config.MemoryStack('''
455
 
gpg_signing_command=cat -
456
 
create_signatures=always
457
 
''')
 
397
            config = MustSignConfig(branch)
458
398
            self.assertRaises(SigningFailed,
459
 
                              commit.Commit(config_stack=conf).commit,
 
399
                              commit.Commit(config=config).commit,
460
400
                              message="base",
461
401
                              allow_pointless=True,
462
402
                              rev_id='B',
463
403
                              working_tree=wt)
464
404
            branch = Branch.open(self.get_url('.'))
465
 
            self.assertEqual(branch.last_revision(), 'A')
466
 
            self.assertFalse(branch.repository.has_revision('B'))
 
405
            self.assertEqual(branch.revision_history(), ['A'])
 
406
            self.failIf(branch.repository.has_revision('B'))
467
407
        finally:
468
408
            bzrlib.gpg.GPGStrategy = oldstrategy
469
409
 
476
416
            calls.append('called')
477
417
        bzrlib.ahook = called
478
418
        try:
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)
 
419
            config = BranchWithHooks(branch)
 
420
            commit.Commit(config=config).commit(
 
421
                            message = "base",
 
422
                            allow_pointless=True,
 
423
                            rev_id='A', working_tree = wt)
483
424
            self.assertEqual(['called', 'called'], calls)
484
425
        finally:
485
426
            del bzrlib.ahook
489
430
        wt = self.make_branch_and_tree('.')
490
431
        c = Commit()
491
432
        c.commit(working_tree=wt, message='empty tree', allow_pointless=True)
492
 
        self.assertEqual(wt.branch.revno(), 1)
 
433
        self.assertEquals(wt.branch.revno(), 1)
493
434
        self.assertEqual({},
494
435
                         wt.branch.repository.get_revision(
495
436
                            wt.branch.last_revision()).properties)
503
444
        bound = master.sprout('bound')
504
445
        wt = bound.open_workingtree()
505
446
        wt.branch.set_bound_location(os.path.realpath('master'))
 
447
 
 
448
        orig_default = lockdir._DEFAULT_TIMEOUT_SECONDS
506
449
        master_branch.lock_write()
507
450
        try:
 
451
            lockdir._DEFAULT_TIMEOUT_SECONDS = 1
508
452
            self.assertRaises(LockContention, wt.commit, 'silly')
509
453
        finally:
 
454
            lockdir._DEFAULT_TIMEOUT_SECONDS = orig_default
510
455
            master_branch.unlock()
511
456
 
512
457
    def test_commit_bound_merge(self):
523
468
        other_bzrdir = master_branch.bzrdir.sprout('other')
524
469
        other_tree = other_bzrdir.open_workingtree()
525
470
 
526
 
        # do a commit to the other branch changing the content file so
 
471
        # do a commit to the the other branch changing the content file so
527
472
        # that our commit after merging will have a merged revision in the
528
473
        # content file history.
529
474
        self.build_tree_contents([('other/content_file', 'change in other\n')])
540
485
        bound_tree.commit(message='commit of merge in bound tree')
541
486
 
542
487
    def test_commit_reporting_after_merge(self):
543
 
        # when doing a commit of a merge, the reporter needs to still
 
488
        # when doing a commit of a merge, the reporter needs to still 
544
489
        # be called for each item that is added/removed/deleted.
545
490
        this_tree = self.make_branch_and_tree('this')
546
491
        # we need a bunch of files and dirs, to perform one action on each.
589
534
        this_tree.merge_from_branch(other_tree.branch)
590
535
        reporter = CapturingReporter()
591
536
        this_tree.commit('do the commit', reporter=reporter)
592
 
        expected = set([
 
537
        self.assertEqual([
 
538
            ('change', 'unchanged', ''),
 
539
            ('change', 'unchanged', 'dirtoleave'),
 
540
            ('change', 'unchanged', 'filetoleave'),
593
541
            ('change', 'modified', 'filetomodify'),
594
542
            ('change', 'added', 'newdir'),
595
543
            ('change', 'added', 'newfile'),
599
547
            ('renamed', 'renamed', 'filetoreparent', 'renameddir/reparentedfile'),
600
548
            ('deleted', 'dirtoremove'),
601
549
            ('deleted', 'filetoremove'),
602
 
            ])
603
 
        result = set(reporter.calls)
604
 
        missing = expected - result
605
 
        new = result - expected
606
 
        self.assertEqual((set(), set()), (missing, new))
 
550
            ],
 
551
            reporter.calls)
607
552
 
608
553
    def test_commit_removals_respects_filespec(self):
609
554
        """Commit respects the specified_files for removals."""
699
644
    def test_commit_unversioned_specified(self):
700
645
        """Commit should raise if specified files isn't in basis or worktree"""
701
646
        tree = self.make_branch_and_tree('.')
702
 
        self.assertRaises(errors.PathsNotVersionedError, tree.commit,
 
647
        self.assertRaises(errors.PathsNotVersionedError, tree.commit, 
703
648
                          'message', specific_files=['bogus'])
704
649
 
705
650
    class Callback(object):
706
 
 
 
651
        
707
652
        def __init__(self, message, testcase):
708
653
            self.called = False
709
654
            self.message = message
737
682
        """Callback should not be invoked for pointless commit"""
738
683
        tree = self.make_branch_and_tree('.')
739
684
        cb = self.Callback(u'commit 2', self)
740
 
        self.assertRaises(PointlessCommit, tree.commit, message_callback=cb,
 
685
        self.assertRaises(PointlessCommit, tree.commit, message_callback=cb, 
741
686
                          allow_pointless=False)
742
687
        self.assertFalse(cb.called)
743
688
 
747
692
        cb = self.Callback(u'commit 2', self)
748
693
        repository = tree.branch.repository
749
694
        # simulate network failure
750
 
        def raise_(self, arg, arg2, arg3=None, arg4=None):
 
695
        def raise_(self, arg, arg2):
751
696
            raise errors.NoSuchFile('foo')
752
697
        repository.add_inventory = raise_
753
 
        repository.add_inventory_by_delta = raise_
754
698
        self.assertRaises(errors.NoSuchFile, tree.commit, message_callback=cb)
755
699
        self.assertFalse(cb.called)
756
700
 
778
722
        tree.add('a/c/d')
779
723
        tree.rename_one('a/z/x', 'a/c/d/x')
780
724
        tree.commit('test', specific_files=['a/z/y'])
781
 
 
 
725
 
782
726
    def test_commit_no_author(self):
783
727
        """The default kwarg author in MutableTree.commit should not add
784
728
        the 'author' revision property.
787
731
        rev_id = tree.commit('commit 1')
788
732
        rev = tree.branch.repository.get_revision(rev_id)
789
733
        self.assertFalse('author' in rev.properties)
790
 
        self.assertFalse('authors' in rev.properties)
791
734
 
792
735
    def test_commit_author(self):
793
736
        """Passing a non-empty author kwarg to MutableTree.commit should add
794
737
        the 'author' revision property.
795
738
        """
796
739
        tree = self.make_branch_and_tree('foo')
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>')
 
740
        rev_id = tree.commit('commit 1', author='John Doe <jdoe@example.com>')
800
741
        rev = tree.branch.repository.get_revision(rev_id)
801
742
        self.assertEqual('John Doe <jdoe@example.com>',
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>'])
 
743
                         rev.properties['author'])
834
744
 
835
745
    def test_commit_with_checkout_and_branch_sharing_repo(self):
836
746
        repo = self.make_repository('repo', shared=True)
837
747
        # make_branch_and_tree ignores shared repos
838
 
        branch = controldir.ControlDir.create_branch_convenience('repo/branch')
 
748
        branch = bzrdir.BzrDir.create_branch_convenience('repo/branch')
839
749
        tree2 = branch.create_checkout('repo/tree2')
840
750
        tree2.commit('message', rev_id='rev1')
841
751
        self.assertTrue(tree2.branch.repository.has_revision('rev1'))