~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/selftest/test_commit.py

  • Committer: Martin Pool
  • Date: 2005-09-16 08:23:10 UTC
  • Revision ID: mbp@sourcefrog.net-20050916082310-ecb5a25c40253839
- wrap wide strings when showing exceptions

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006 by Canonical Ltd
 
1
# Copyright (C) 2005 by 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.tests import TestCaseWithTransport
 
20
from bzrlib.selftest import TestCaseInTempDir
22
21
from bzrlib.branch import Branch
23
 
from bzrlib.bzrdir import BzrDir, BzrDirMetaFormat1
24
 
from bzrlib.workingtree import WorkingTree
25
 
from bzrlib.commit import Commit, NullCommitReporter
26
 
from bzrlib.config import BranchConfig
27
 
from bzrlib.errors import (PointlessCommit, BzrError, SigningFailed, 
28
 
                           LockContention)
 
22
from bzrlib.commit import Commit
 
23
from bzrlib.errors import PointlessCommit
29
24
 
30
25
 
31
26
# TODO: Test commit with some added, and added-but-missing files
32
27
 
33
 
class MustSignConfig(BranchConfig):
34
 
 
35
 
    def signature_needed(self):
36
 
        return True
37
 
 
38
 
    def gpg_signing_command(self):
39
 
        return ['cat', '-']
40
 
 
41
 
 
42
 
class BranchWithHooks(BranchConfig):
43
 
 
44
 
    def post_commit(self):
45
 
        return "bzrlib.ahook bzrlib.ahook"
46
 
 
47
 
 
48
 
class CapturingReporter(NullCommitReporter):
49
 
    """This reporter captures the calls made to it for evaluation later."""
50
 
 
51
 
    def __init__(self):
52
 
        # a list of the calls this received
53
 
        self.calls = []
54
 
 
55
 
    def snapshot_change(self, change, path):
56
 
        self.calls.append(('change', change, path))
57
 
 
58
 
    def deleted(self, file_id):
59
 
        self.calls.append(('deleted', file_id))
60
 
 
61
 
    def missing(self, path):
62
 
        self.calls.append(('missing', path))
63
 
 
64
 
    def renamed(self, change, old_path, new_path):
65
 
        self.calls.append(('renamed', change, old_path, new_path))
66
 
 
67
 
 
68
 
class TestCommit(TestCaseWithTransport):
69
 
 
 
28
class TestCommit(TestCaseInTempDir):
70
29
    def test_simple_commit(self):
71
30
        """Commit and check two versions of a single file."""
72
 
        wt = self.make_branch_and_tree('.')
73
 
        b = wt.branch
 
31
        b = Branch('.', init=True)
74
32
        file('hello', 'w').write('hello world')
75
 
        wt.add('hello')
76
 
        wt.commit(message='add hello')
77
 
        file_id = wt.path2id('hello')
 
33
        b.add('hello')
 
34
        b.commit(message='add hello')
 
35
        file_id = b.working_tree().path2id('hello')
78
36
 
79
37
        file('hello', 'w').write('version 2')
80
 
        wt.commit(message='commit 2')
 
38
        b.commit(message='commit 2')
81
39
 
82
40
        eq = self.assertEquals
83
41
        eq(b.revno(), 2)
84
42
        rh = b.revision_history()
85
 
        rev = b.repository.get_revision(rh[0])
 
43
        rev = b.get_revision(rh[0])
86
44
        eq(rev.message, 'add hello')
87
45
 
88
 
        tree1 = b.repository.revision_tree(rh[0])
 
46
        tree1 = b.revision_tree(rh[0])
89
47
        text = tree1.get_file_text(file_id)
90
48
        eq(text, 'hello world')
91
49
 
92
 
        tree2 = b.repository.revision_tree(rh[1])
 
50
        tree2 = b.revision_tree(rh[1])
93
51
        eq(tree2.get_file_text(file_id), 'version 2')
94
52
 
 
53
 
95
54
    def test_delete_commit(self):
96
55
        """Test a commit with a deleted file"""
97
 
        wt = self.make_branch_and_tree('.')
98
 
        b = wt.branch
 
56
        b = Branch('.', init=True)
99
57
        file('hello', 'w').write('hello world')
100
 
        wt.add(['hello'], ['hello-id'])
101
 
        wt.commit(message='add hello')
 
58
        b.add(['hello'], ['hello-id'])
 
59
        b.commit(message='add hello')
102
60
 
103
61
        os.remove('hello')
104
 
        wt.commit('removed hello', rev_id='rev2')
 
62
        b.commit('removed hello', rev_id='rev2')
105
63
 
106
 
        tree = b.repository.revision_tree('rev2')
 
64
        tree = b.revision_tree('rev2')
107
65
        self.assertFalse(tree.has_id('hello-id'))
108
66
 
 
67
 
109
68
    def test_pointless_commit(self):
110
69
        """Commit refuses unless there are changes or it's forced."""
111
 
        wt = self.make_branch_and_tree('.')
112
 
        b = wt.branch
 
70
        b = Branch('.', init=True)
113
71
        file('hello', 'w').write('hello')
114
 
        wt.add(['hello'])
115
 
        wt.commit(message='add hello')
 
72
        b.add(['hello'])
 
73
        b.commit(message='add hello')
116
74
        self.assertEquals(b.revno(), 1)
117
75
        self.assertRaises(PointlessCommit,
118
 
                          wt.commit,
 
76
                          b.commit,
119
77
                          message='fails',
120
78
                          allow_pointless=False)
121
79
        self.assertEquals(b.revno(), 1)
122
80
        
 
81
 
 
82
 
123
83
    def test_commit_empty(self):
124
84
        """Commiting an empty tree works."""
125
 
        wt = self.make_branch_and_tree('.')
126
 
        b = wt.branch
127
 
        wt.commit(message='empty tree', allow_pointless=True)
 
85
        b = Branch('.', init=True)
 
86
        b.commit(message='empty tree', allow_pointless=True)
128
87
        self.assertRaises(PointlessCommit,
129
 
                          wt.commit,
 
88
                          b.commit,
130
89
                          message='empty tree',
131
90
                          allow_pointless=False)
132
 
        wt.commit(message='empty tree', allow_pointless=True)
 
91
        b.commit(message='empty tree', allow_pointless=True)
133
92
        self.assertEquals(b.revno(), 2)
134
93
 
 
94
 
135
95
    def test_selective_delete(self):
136
96
        """Selective commit in tree with deletions"""
137
 
        wt = self.make_branch_and_tree('.')
138
 
        b = wt.branch
 
97
        b = Branch('.', init=True)
139
98
        file('hello', 'w').write('hello')
140
99
        file('buongia', 'w').write('buongia')
141
 
        wt.add(['hello', 'buongia'],
 
100
        b.add(['hello', 'buongia'],
142
101
              ['hello-id', 'buongia-id'])
143
 
        wt.commit(message='add files',
 
102
        b.commit(message='add files',
144
103
                 rev_id='test@rev-1')
145
104
        
146
105
        os.remove('hello')
147
106
        file('buongia', 'w').write('new text')
148
 
        wt.commit(message='update text',
 
107
        b.commit(message='update text',
149
108
                 specific_files=['buongia'],
150
109
                 allow_pointless=False,
151
110
                 rev_id='test@rev-2')
152
111
 
153
 
        wt.commit(message='remove hello',
 
112
        b.commit(message='remove hello',
154
113
                 specific_files=['hello'],
155
114
                 allow_pointless=False,
156
115
                 rev_id='test@rev-3')
158
117
        eq = self.assertEquals
159
118
        eq(b.revno(), 3)
160
119
 
161
 
        tree2 = b.repository.revision_tree('test@rev-2')
 
120
        tree2 = b.revision_tree('test@rev-2')
162
121
        self.assertTrue(tree2.has_filename('hello'))
163
122
        self.assertEquals(tree2.get_file_text('hello-id'), 'hello')
164
123
        self.assertEquals(tree2.get_file_text('buongia-id'), 'new text')
165
124
        
166
 
        tree3 = b.repository.revision_tree('test@rev-3')
 
125
        tree3 = b.revision_tree('test@rev-3')
167
126
        self.assertFalse(tree3.has_filename('hello'))
168
127
        self.assertEquals(tree3.get_file_text('buongia-id'), 'new text')
169
128
 
 
129
 
170
130
    def test_commit_rename(self):
171
131
        """Test commit of a revision where a file is renamed."""
172
 
        tree = self.make_branch_and_tree('.')
173
 
        b = tree.branch
174
 
        self.build_tree(['hello'], line_endings='binary')
175
 
        tree.add(['hello'], ['hello-id'])
176
 
        tree.commit(message='one', rev_id='test@rev-1', allow_pointless=False)
177
 
 
178
 
        tree.rename_one('hello', 'fruity')
179
 
        tree.commit(message='renamed', rev_id='test@rev-2', allow_pointless=False)
180
 
 
181
 
        eq = self.assertEquals
182
 
        tree1 = b.repository.revision_tree('test@rev-1')
183
 
        eq(tree1.id2path('hello-id'), 'hello')
184
 
        eq(tree1.get_file_text('hello-id'), 'contents of hello\n')
 
132
        b = Branch('.', init=True)
 
133
        self.build_tree(['hello'])
 
134
        b.add(['hello'], ['hello-id'])
 
135
        b.commit(message='one', rev_id='test@rev-1', allow_pointless=False)
 
136
 
 
137
        b.rename_one('hello', 'fruity')
 
138
        b.commit(message='renamed', rev_id='test@rev-2', allow_pointless=False)
 
139
 
 
140
        tree1 = b.revision_tree('test@rev-1')
 
141
        self.assertEquals(tree1.id2path('hello-id'), 'hello')
 
142
        self.assertEquals(tree1.get_file_text('hello-id'), 'contents of hello\n')
185
143
        self.assertFalse(tree1.has_filename('fruity'))
186
 
        self.check_inventory_shape(tree1.inventory, ['hello'])
187
 
        ie = tree1.inventory['hello-id']
188
 
        eq(ie.revision, 'test@rev-1')
189
 
 
190
 
        tree2 = b.repository.revision_tree('test@rev-2')
191
 
        eq(tree2.id2path('hello-id'), 'fruity')
192
 
        eq(tree2.get_file_text('hello-id'), 'contents of hello\n')
193
 
        self.check_inventory_shape(tree2.inventory, ['fruity'])
194
 
        ie = tree2.inventory['hello-id']
195
 
        eq(ie.revision, 'test@rev-2')
196
 
 
197
 
    def test_reused_rev_id(self):
198
 
        """Test that a revision id cannot be reused in a branch"""
199
 
        wt = self.make_branch_and_tree('.')
200
 
        b = wt.branch
201
 
        wt.commit('initial', rev_id='test@rev-1', allow_pointless=True)
202
 
        self.assertRaises(Exception,
203
 
                          wt.commit,
204
 
                          message='reused id',
205
 
                          rev_id='test@rev-1',
206
 
                          allow_pointless=True)
207
 
 
208
 
    def test_commit_move(self):
209
 
        """Test commit of revisions with moved files and directories"""
210
 
        eq = self.assertEquals
211
 
        wt = self.make_branch_and_tree('.')
212
 
        b = wt.branch
213
 
        r1 = 'test@rev-1'
214
 
        self.build_tree(['hello', 'a/', 'b/'])
215
 
        wt.add(['hello', 'a', 'b'], ['hello-id', 'a-id', 'b-id'])
216
 
        wt.commit('initial', rev_id=r1, allow_pointless=False)
217
 
        wt.move(['hello'], 'a')
218
 
        r2 = 'test@rev-2'
219
 
        wt.commit('two', rev_id=r2, allow_pointless=False)
220
 
        self.check_inventory_shape(wt.read_working_inventory(),
221
 
                                   ['a', 'a/hello', 'b'])
222
 
 
223
 
        wt.move(['b'], 'a')
224
 
        r3 = 'test@rev-3'
225
 
        wt.commit('three', rev_id=r3, allow_pointless=False)
226
 
        self.check_inventory_shape(wt.read_working_inventory(),
227
 
                                   ['a', 'a/hello', 'a/b'])
228
 
        self.check_inventory_shape(b.repository.get_revision_inventory(r3),
229
 
                                   ['a', 'a/hello', 'a/b'])
230
 
 
231
 
        wt.move(['a/hello'], 'a/b')
232
 
        r4 = 'test@rev-4'
233
 
        wt.commit('four', rev_id=r4, allow_pointless=False)
234
 
        self.check_inventory_shape(wt.read_working_inventory(),
235
 
                                   ['a', 'a/b/hello', 'a/b'])
236
 
 
237
 
        inv = b.repository.get_revision_inventory(r4)
238
 
        eq(inv['hello-id'].revision, r4)
239
 
        eq(inv['a-id'].revision, r1)
240
 
        eq(inv['b-id'].revision, r3)
 
144
 
 
145
        tree2 = b.revision_tree('test@rev-2')
 
146
        self.assertEquals(tree2.id2path('hello-id'), 'fruity')
 
147
        self.assertEquals(tree2.get_file_text('hello-id'), 'contents of hello\n')
 
148
        self.assertFalse(tree2.has_filename('hello'))
241
149
        
 
150
 
242
151
    def test_removed_commit(self):
243
 
        """Commit with a removed file"""
244
 
        wt = self.make_branch_and_tree('.')
245
 
        b = wt.branch
 
152
        """Test a commit with a removed file"""
 
153
        b = Branch('.', init=True)
246
154
        file('hello', 'w').write('hello world')
247
 
        wt.add(['hello'], ['hello-id'])
248
 
        wt.commit(message='add hello')
249
 
        wt.remove('hello')
250
 
        wt.commit('removed hello', rev_id='rev2')
251
 
 
252
 
        tree = b.repository.revision_tree('rev2')
 
155
        b.add(['hello'], ['hello-id'])
 
156
        b.commit(message='add hello')
 
157
 
 
158
        b.remove('hello')
 
159
        b.commit('removed hello', rev_id='rev2')
 
160
 
 
161
        tree = b.revision_tree('rev2')
253
162
        self.assertFalse(tree.has_id('hello-id'))
254
163
 
 
164
 
255
165
    def test_committed_ancestry(self):
256
166
        """Test commit appends revisions to ancestry."""
257
 
        wt = self.make_branch_and_tree('.')
258
 
        b = wt.branch
 
167
        b = Branch('.', init=True)
259
168
        rev_ids = []
260
169
        for i in range(4):
261
170
            file('hello', 'w').write((str(i) * 4) + '\n')
262
171
            if i == 0:
263
 
                wt.add(['hello'], ['hello-id'])
 
172
                b.add(['hello'], ['hello-id'])
264
173
            rev_id = 'test@rev-%d' % (i+1)
265
174
            rev_ids.append(rev_id)
266
 
            wt.commit(message='rev %d' % (i+1),
 
175
            b.commit(message='rev %d' % (i+1),
267
176
                     rev_id=rev_id)
268
177
        eq = self.assertEquals
269
178
        eq(b.revision_history(), rev_ids)
270
179
        for i in range(4):
271
 
            anc = b.repository.get_ancestry(rev_ids[i])
272
 
            eq(anc, [None] + rev_ids[:i+1])
273
 
 
274
 
    def test_commit_new_subdir_child_selective(self):
275
 
        wt = self.make_branch_and_tree('.')
276
 
        b = wt.branch
277
 
        self.build_tree(['dir/', 'dir/file1', 'dir/file2'])
278
 
        wt.add(['dir', 'dir/file1', 'dir/file2'],
279
 
              ['dirid', 'file1id', 'file2id'])
280
 
        wt.commit('dir/file1', specific_files=['dir/file1'], rev_id='1')
281
 
        inv = b.repository.get_inventory('1')
282
 
        self.assertEqual('1', inv['dirid'].revision)
283
 
        self.assertEqual('1', inv['file1id'].revision)
284
 
        # FIXME: This should raise a KeyError I think, rbc20051006
285
 
        self.assertRaises(BzrError, inv.__getitem__, 'file2id')
286
 
 
287
 
    def test_strict_commit(self):
288
 
        """Try and commit with unknown files and strict = True, should fail."""
289
 
        from bzrlib.errors import StrictCommitFailed
290
 
        wt = self.make_branch_and_tree('.')
291
 
        b = wt.branch
292
 
        file('hello', 'w').write('hello world')
293
 
        wt.add('hello')
294
 
        file('goodbye', 'w').write('goodbye cruel world!')
295
 
        self.assertRaises(StrictCommitFailed, wt.commit,
296
 
            message='add hello but not goodbye', strict=True)
297
 
 
298
 
    def test_strict_commit_without_unknowns(self):
299
 
        """Try and commit with no unknown files and strict = True,
300
 
        should work."""
301
 
        from bzrlib.errors import StrictCommitFailed
302
 
        wt = self.make_branch_and_tree('.')
303
 
        b = wt.branch
304
 
        file('hello', 'w').write('hello world')
305
 
        wt.add('hello')
306
 
        wt.commit(message='add hello', strict=True)
307
 
 
308
 
    def test_nonstrict_commit(self):
309
 
        """Try and commit with unknown files and strict = False, should work."""
310
 
        wt = self.make_branch_and_tree('.')
311
 
        b = wt.branch
312
 
        file('hello', 'w').write('hello world')
313
 
        wt.add('hello')
314
 
        file('goodbye', 'w').write('goodbye cruel world!')
315
 
        wt.commit(message='add hello but not goodbye', strict=False)
316
 
 
317
 
    def test_nonstrict_commit_without_unknowns(self):
318
 
        """Try and commit with no unknown files and strict = False,
319
 
        should work."""
320
 
        wt = self.make_branch_and_tree('.')
321
 
        b = wt.branch
322
 
        file('hello', 'w').write('hello world')
323
 
        wt.add('hello')
324
 
        wt.commit(message='add hello', strict=False)
325
 
 
326
 
    def test_signed_commit(self):
327
 
        import bzrlib.gpg
328
 
        import bzrlib.commit as commit
329
 
        oldstrategy = bzrlib.gpg.GPGStrategy
330
 
        wt = self.make_branch_and_tree('.')
331
 
        branch = wt.branch
332
 
        wt.commit("base", allow_pointless=True, rev_id='A')
333
 
        self.failIf(branch.repository.has_signature_for_revision_id('A'))
334
 
        try:
335
 
            from bzrlib.testament import Testament
336
 
            # monkey patch gpg signing mechanism
337
 
            bzrlib.gpg.GPGStrategy = bzrlib.gpg.LoopbackGPGStrategy
338
 
            commit.Commit(config=MustSignConfig(branch)).commit(message="base",
339
 
                                                      allow_pointless=True,
340
 
                                                      rev_id='B',
341
 
                                                      working_tree=wt)
342
 
            self.assertEqual(Testament.from_revision(branch.repository,
343
 
                             'B').as_short_text(),
344
 
                             branch.repository.get_signature_text('B'))
345
 
        finally:
346
 
            bzrlib.gpg.GPGStrategy = oldstrategy
347
 
 
348
 
    def test_commit_failed_signature(self):
349
 
        import bzrlib.gpg
350
 
        import bzrlib.commit as commit
351
 
        oldstrategy = bzrlib.gpg.GPGStrategy
352
 
        wt = self.make_branch_and_tree('.')
353
 
        branch = wt.branch
354
 
        wt.commit("base", allow_pointless=True, rev_id='A')
355
 
        self.failIf(branch.repository.has_signature_for_revision_id('A'))
356
 
        try:
357
 
            from bzrlib.testament import Testament
358
 
            # monkey patch gpg signing mechanism
359
 
            bzrlib.gpg.GPGStrategy = bzrlib.gpg.DisabledGPGStrategy
360
 
            config = MustSignConfig(branch)
361
 
            self.assertRaises(SigningFailed,
362
 
                              commit.Commit(config=config).commit,
363
 
                              message="base",
364
 
                              allow_pointless=True,
365
 
                              rev_id='B',
366
 
                              working_tree=wt)
367
 
            branch = Branch.open(self.get_url('.'))
368
 
            self.assertEqual(branch.revision_history(), ['A'])
369
 
            self.failIf(branch.repository.has_revision('B'))
370
 
        finally:
371
 
            bzrlib.gpg.GPGStrategy = oldstrategy
372
 
 
373
 
    def test_commit_invokes_hooks(self):
374
 
        import bzrlib.commit as commit
375
 
        wt = self.make_branch_and_tree('.')
376
 
        branch = wt.branch
377
 
        calls = []
378
 
        def called(branch, rev_id):
379
 
            calls.append('called')
380
 
        bzrlib.ahook = called
381
 
        try:
382
 
            config = BranchWithHooks(branch)
383
 
            commit.Commit(config=config).commit(
384
 
                            message = "base",
385
 
                            allow_pointless=True,
386
 
                            rev_id='A', working_tree = wt)
387
 
            self.assertEqual(['called', 'called'], calls)
388
 
        finally:
389
 
            del bzrlib.ahook
390
 
 
391
 
    def test_commit_object_doesnt_set_nick(self):
392
 
        # using the Commit object directly does not set the branch nick.
393
 
        wt = self.make_branch_and_tree('.')
394
 
        c = Commit()
395
 
        c.commit(working_tree=wt, message='empty tree', allow_pointless=True)
396
 
        self.assertEquals(wt.branch.revno(), 1)
397
 
        self.assertEqual({},
398
 
                         wt.branch.repository.get_revision(
399
 
                            wt.branch.last_revision()).properties)
400
 
 
401
 
    def test_safe_master_lock(self):
402
 
        os.mkdir('master')
403
 
        master = BzrDirMetaFormat1().initialize('master')
404
 
        master.create_repository()
405
 
        master_branch = master.create_branch()
406
 
        master.create_workingtree()
407
 
        bound = master.sprout('bound')
408
 
        wt = bound.open_workingtree()
409
 
        wt.branch.set_bound_location(os.path.realpath('master'))
410
 
        master_branch.lock_write()
411
 
        try:
412
 
            self.assertRaises(LockContention, wt.commit, 'silly')
413
 
        finally:
414
 
            master_branch.unlock()
415
 
 
416
 
    def test_commit_bound_merge(self):
417
 
        # see bug #43959; commit of a merge in a bound branch fails to push
418
 
        # the new commit into the master
419
 
        master_branch = self.make_branch('master')
420
 
        bound_tree = self.make_branch_and_tree('bound')
421
 
        bound_tree.branch.bind(master_branch)
422
 
 
423
 
        self.build_tree_contents([('bound/content_file', 'initial contents\n')])
424
 
        bound_tree.add(['content_file'])
425
 
        bound_tree.commit(message='woo!')
426
 
 
427
 
        other_bzrdir = master_branch.bzrdir.sprout('other')
428
 
        other_tree = other_bzrdir.open_workingtree()
429
 
 
430
 
        # do a commit to the the other branch changing the content file so
431
 
        # that our commit after merging will have a merged revision in the
432
 
        # content file history.
433
 
        self.build_tree_contents([('other/content_file', 'change in other\n')])
434
 
        other_tree.commit('change in other')
435
 
 
436
 
        # do a merge into the bound branch from other, and then change the
437
 
        # content file locally to force a new revision (rather than using the
438
 
        # revision from other). This forces extra processing in commit.
439
 
        self.merge(other_tree.branch, bound_tree)
440
 
        self.build_tree_contents([('bound/content_file', 'change in bound\n')])
441
 
 
442
 
        # before #34959 was fixed, this failed with 'revision not present in
443
 
        # weave' when trying to implicitly push from the bound branch to the master
444
 
        bound_tree.commit(message='commit of merge in bound tree')
445
 
 
446
 
    def test_commit_reporting_after_merge(self):
447
 
        # when doing a commit of a merge, the reporter needs to still 
448
 
        # be called for each item that is added/removed/deleted.
449
 
        this_tree = self.make_branch_and_tree('this')
450
 
        # we need a bunch of files and dirs, to perform one action on each.
451
 
        self.build_tree([
452
 
            'this/dirtorename/',
453
 
            'this/dirtoreparent/',
454
 
            'this/dirtoleave/',
455
 
            'this/dirtoremove/',
456
 
            'this/filetoreparent',
457
 
            'this/filetorename',
458
 
            'this/filetomodify',
459
 
            'this/filetoremove',
460
 
            'this/filetoleave']
461
 
            )
462
 
        this_tree.add([
463
 
            'dirtorename',
464
 
            'dirtoreparent',
465
 
            'dirtoleave',
466
 
            'dirtoremove',
467
 
            'filetoreparent',
468
 
            'filetorename',
469
 
            'filetomodify',
470
 
            'filetoremove',
471
 
            'filetoleave']
472
 
            )
473
 
        this_tree.commit('create_files')
474
 
        other_dir = this_tree.bzrdir.sprout('other')
475
 
        other_tree = other_dir.open_workingtree()
476
 
        other_tree.lock_write()
477
 
        # perform the needed actions on the files and dirs.
478
 
        try:
479
 
            other_tree.rename_one('dirtorename', 'renameddir')
480
 
            other_tree.rename_one('dirtoreparent', 'renameddir/reparenteddir')
481
 
            other_tree.rename_one('filetorename', 'renamedfile')
482
 
            other_tree.rename_one('filetoreparent', 'renameddir/reparentedfile')
483
 
            other_tree.remove(['dirtoremove', 'filetoremove'])
484
 
            self.build_tree_contents([
485
 
                ('other/newdir/', ),
486
 
                ('other/filetomodify', 'new content'),
487
 
                ('other/newfile', 'new file content')])
488
 
            other_tree.add('newfile')
489
 
            other_tree.add('newdir/')
490
 
            other_tree.commit('modify all sample files and dirs.')
491
 
        finally:
492
 
            other_tree.unlock()
493
 
        self.merge(other_tree.branch, this_tree)
494
 
        reporter = CapturingReporter()
495
 
        this_tree.commit('do the commit', reporter=reporter)
496
 
        self.assertEqual([
497
 
            ('change', 'unchanged', 'dirtoleave'),
498
 
            ('change', 'unchanged', 'filetoleave'),
499
 
            ('change', 'modified', 'filetomodify'),
500
 
            ('change', 'added', 'newdir'),
501
 
            ('change', 'added', 'newfile'),
502
 
            ('renamed', 'renamed', 'dirtorename', 'renameddir'),
503
 
            ('renamed', 'renamed', 'dirtoreparent', 'renameddir/reparenteddir'),
504
 
            ('renamed', 'renamed', 'filetoreparent', 'renameddir/reparentedfile'),
505
 
            ('renamed', 'renamed', 'filetorename', 'renamedfile'),
506
 
            ('deleted', 'dirtoremove'),
507
 
            ('deleted', 'filetoremove'),
508
 
            ],
509
 
            reporter.calls)
 
180
            anc = b.get_ancestry(rev_ids[i])
 
181
            eq(anc, rev_ids[:i+1])
 
182
            
 
183
        
 
184
 
 
185
 
 
186
if __name__ == '__main__':
 
187
    import unittest
 
188
    unittest.main()
 
189