~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/selftest/test_commit.py

  • Committer: Robert Collins
  • Date: 2005-10-18 05:26:22 UTC
  • mto: This revision was merged to the branch mainline in revision 1463.
  • Revision ID: robertc@robertcollins.net-20051018052622-653d638c9e26fde4
fix broken tests

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
22
from bzrlib.commit import Commit
26
23
from bzrlib.config import BranchConfig
27
 
from bzrlib.errors import (PointlessCommit, BzrError, SigningFailed, 
28
 
                           LockContention)
 
24
from bzrlib.errors import PointlessCommit, BzrError, SigningFailed
29
25
 
30
26
 
31
27
# TODO: Test commit with some added, and added-but-missing files
39
35
        return ['cat', '-']
40
36
 
41
37
 
42
 
class BranchWithHooks(BranchConfig):
43
 
 
44
 
    def post_commit(self):
45
 
        return "bzrlib.ahook bzrlib.ahook"
46
 
 
47
 
 
48
 
class TestCommit(TestCaseWithTransport):
 
38
class TestCommit(TestCaseInTempDir):
49
39
 
50
40
    def test_simple_commit(self):
51
41
        """Commit and check two versions of a single file."""
52
 
        wt = self.make_branch_and_tree('.')
53
 
        b = wt.branch
 
42
        b = Branch.initialize('.')
54
43
        file('hello', 'w').write('hello world')
55
 
        wt.add('hello')
56
 
        wt.commit(message='add hello')
57
 
        file_id = wt.path2id('hello')
 
44
        b.add('hello')
 
45
        b.commit(message='add hello')
 
46
        file_id = b.working_tree().path2id('hello')
58
47
 
59
48
        file('hello', 'w').write('version 2')
60
 
        wt.commit(message='commit 2')
 
49
        b.commit(message='commit 2')
61
50
 
62
51
        eq = self.assertEquals
63
52
        eq(b.revno(), 2)
64
53
        rh = b.revision_history()
65
 
        rev = b.repository.get_revision(rh[0])
 
54
        rev = b.get_revision(rh[0])
66
55
        eq(rev.message, 'add hello')
67
56
 
68
 
        tree1 = b.repository.revision_tree(rh[0])
 
57
        tree1 = b.revision_tree(rh[0])
69
58
        text = tree1.get_file_text(file_id)
70
59
        eq(text, 'hello world')
71
60
 
72
 
        tree2 = b.repository.revision_tree(rh[1])
 
61
        tree2 = b.revision_tree(rh[1])
73
62
        eq(tree2.get_file_text(file_id), 'version 2')
74
63
 
75
64
    def test_delete_commit(self):
76
65
        """Test a commit with a deleted file"""
77
 
        wt = self.make_branch_and_tree('.')
78
 
        b = wt.branch
 
66
        b = Branch.initialize('.')
79
67
        file('hello', 'w').write('hello world')
80
 
        wt.add(['hello'], ['hello-id'])
81
 
        wt.commit(message='add hello')
 
68
        b.add(['hello'], ['hello-id'])
 
69
        b.commit(message='add hello')
82
70
 
83
71
        os.remove('hello')
84
 
        wt.commit('removed hello', rev_id='rev2')
 
72
        b.commit('removed hello', rev_id='rev2')
85
73
 
86
 
        tree = b.repository.revision_tree('rev2')
 
74
        tree = b.revision_tree('rev2')
87
75
        self.assertFalse(tree.has_id('hello-id'))
88
76
 
 
77
 
89
78
    def test_pointless_commit(self):
90
79
        """Commit refuses unless there are changes or it's forced."""
91
 
        wt = self.make_branch_and_tree('.')
92
 
        b = wt.branch
 
80
        b = Branch.initialize('.')
93
81
        file('hello', 'w').write('hello')
94
 
        wt.add(['hello'])
95
 
        wt.commit(message='add hello')
 
82
        b.add(['hello'])
 
83
        b.commit(message='add hello')
96
84
        self.assertEquals(b.revno(), 1)
97
85
        self.assertRaises(PointlessCommit,
98
 
                          wt.commit,
 
86
                          b.commit,
99
87
                          message='fails',
100
88
                          allow_pointless=False)
101
89
        self.assertEquals(b.revno(), 1)
102
90
        
 
91
 
 
92
 
103
93
    def test_commit_empty(self):
104
94
        """Commiting an empty tree works."""
105
 
        wt = self.make_branch_and_tree('.')
106
 
        b = wt.branch
107
 
        wt.commit(message='empty tree', allow_pointless=True)
 
95
        b = Branch.initialize('.')
 
96
        b.commit(message='empty tree', allow_pointless=True)
108
97
        self.assertRaises(PointlessCommit,
109
 
                          wt.commit,
 
98
                          b.commit,
110
99
                          message='empty tree',
111
100
                          allow_pointless=False)
112
 
        wt.commit(message='empty tree', allow_pointless=True)
 
101
        b.commit(message='empty tree', allow_pointless=True)
113
102
        self.assertEquals(b.revno(), 2)
114
103
 
 
104
 
115
105
    def test_selective_delete(self):
116
106
        """Selective commit in tree with deletions"""
117
 
        wt = self.make_branch_and_tree('.')
118
 
        b = wt.branch
 
107
        b = Branch.initialize('.')
119
108
        file('hello', 'w').write('hello')
120
109
        file('buongia', 'w').write('buongia')
121
 
        wt.add(['hello', 'buongia'],
 
110
        b.add(['hello', 'buongia'],
122
111
              ['hello-id', 'buongia-id'])
123
 
        wt.commit(message='add files',
 
112
        b.commit(message='add files',
124
113
                 rev_id='test@rev-1')
125
114
        
126
115
        os.remove('hello')
127
116
        file('buongia', 'w').write('new text')
128
 
        wt.commit(message='update text',
 
117
        b.commit(message='update text',
129
118
                 specific_files=['buongia'],
130
119
                 allow_pointless=False,
131
120
                 rev_id='test@rev-2')
132
121
 
133
 
        wt.commit(message='remove hello',
 
122
        b.commit(message='remove hello',
134
123
                 specific_files=['hello'],
135
124
                 allow_pointless=False,
136
125
                 rev_id='test@rev-3')
138
127
        eq = self.assertEquals
139
128
        eq(b.revno(), 3)
140
129
 
141
 
        tree2 = b.repository.revision_tree('test@rev-2')
 
130
        tree2 = b.revision_tree('test@rev-2')
142
131
        self.assertTrue(tree2.has_filename('hello'))
143
132
        self.assertEquals(tree2.get_file_text('hello-id'), 'hello')
144
133
        self.assertEquals(tree2.get_file_text('buongia-id'), 'new text')
145
134
        
146
 
        tree3 = b.repository.revision_tree('test@rev-3')
 
135
        tree3 = b.revision_tree('test@rev-3')
147
136
        self.assertFalse(tree3.has_filename('hello'))
148
137
        self.assertEquals(tree3.get_file_text('buongia-id'), 'new text')
149
138
 
 
139
 
150
140
    def test_commit_rename(self):
151
141
        """Test commit of a revision where a file is renamed."""
152
 
        tree = self.make_branch_and_tree('.')
153
 
        b = tree.branch
154
 
        self.build_tree(['hello'], line_endings='binary')
155
 
        tree.add(['hello'], ['hello-id'])
156
 
        tree.commit(message='one', rev_id='test@rev-1', allow_pointless=False)
 
142
        b = Branch.initialize('.')
 
143
        self.build_tree(['hello'])
 
144
        b.add(['hello'], ['hello-id'])
 
145
        b.commit(message='one', rev_id='test@rev-1', allow_pointless=False)
157
146
 
158
 
        tree.rename_one('hello', 'fruity')
159
 
        tree.commit(message='renamed', rev_id='test@rev-2', allow_pointless=False)
 
147
        b.rename_one('hello', 'fruity')
 
148
        b.commit(message='renamed', rev_id='test@rev-2', allow_pointless=False)
160
149
 
161
150
        eq = self.assertEquals
162
 
        tree1 = b.repository.revision_tree('test@rev-1')
 
151
        tree1 = b.revision_tree('test@rev-1')
163
152
        eq(tree1.id2path('hello-id'), 'hello')
164
153
        eq(tree1.get_file_text('hello-id'), 'contents of hello\n')
165
154
        self.assertFalse(tree1.has_filename('fruity'))
167
156
        ie = tree1.inventory['hello-id']
168
157
        eq(ie.revision, 'test@rev-1')
169
158
 
170
 
        tree2 = b.repository.revision_tree('test@rev-2')
 
159
        tree2 = b.revision_tree('test@rev-2')
171
160
        eq(tree2.id2path('hello-id'), 'fruity')
172
161
        eq(tree2.get_file_text('hello-id'), 'contents of hello\n')
173
162
        self.check_inventory_shape(tree2.inventory, ['fruity'])
174
163
        ie = tree2.inventory['hello-id']
175
164
        eq(ie.revision, 'test@rev-2')
176
165
 
 
166
 
177
167
    def test_reused_rev_id(self):
178
168
        """Test that a revision id cannot be reused in a branch"""
179
 
        wt = self.make_branch_and_tree('.')
180
 
        b = wt.branch
181
 
        wt.commit('initial', rev_id='test@rev-1', allow_pointless=True)
 
169
        b = Branch.initialize('.')
 
170
        b.commit('initial', rev_id='test@rev-1', allow_pointless=True)
182
171
        self.assertRaises(Exception,
183
 
                          wt.commit,
 
172
                          b.commit,
184
173
                          message='reused id',
185
174
                          rev_id='test@rev-1',
186
175
                          allow_pointless=True)
 
176
                          
 
177
 
187
178
 
188
179
    def test_commit_move(self):
189
180
        """Test commit of revisions with moved files and directories"""
190
181
        eq = self.assertEquals
191
 
        wt = self.make_branch_and_tree('.')
192
 
        b = wt.branch
 
182
        b = Branch.initialize('.')
193
183
        r1 = 'test@rev-1'
194
184
        self.build_tree(['hello', 'a/', 'b/'])
195
 
        wt.add(['hello', 'a', 'b'], ['hello-id', 'a-id', 'b-id'])
196
 
        wt.commit('initial', rev_id=r1, allow_pointless=False)
197
 
        wt.move(['hello'], 'a')
 
185
        b.add(['hello', 'a', 'b'], ['hello-id', 'a-id', 'b-id'])
 
186
        b.commit('initial', rev_id=r1, allow_pointless=False)
 
187
 
 
188
        b.move(['hello'], 'a')
198
189
        r2 = 'test@rev-2'
199
 
        wt.commit('two', rev_id=r2, allow_pointless=False)
200
 
        self.check_inventory_shape(wt.read_working_inventory(),
 
190
        b.commit('two', rev_id=r2, allow_pointless=False)
 
191
        self.check_inventory_shape(b.inventory,
201
192
                                   ['a', 'a/hello', 'b'])
202
193
 
203
 
        wt.move(['b'], 'a')
 
194
        b.move(['b'], 'a')
204
195
        r3 = 'test@rev-3'
205
 
        wt.commit('three', rev_id=r3, allow_pointless=False)
206
 
        self.check_inventory_shape(wt.read_working_inventory(),
 
196
        b.commit('three', rev_id=r3, allow_pointless=False)
 
197
        self.check_inventory_shape(b.inventory,
207
198
                                   ['a', 'a/hello', 'a/b'])
208
 
        self.check_inventory_shape(b.repository.get_revision_inventory(r3),
 
199
        self.check_inventory_shape(b.get_revision_inventory(r3),
209
200
                                   ['a', 'a/hello', 'a/b'])
210
201
 
211
 
        wt.move(['a/hello'], 'a/b')
 
202
        b.move([os.sep.join(['a', 'hello'])],
 
203
               os.sep.join(['a', 'b']))
212
204
        r4 = 'test@rev-4'
213
 
        wt.commit('four', rev_id=r4, allow_pointless=False)
214
 
        self.check_inventory_shape(wt.read_working_inventory(),
 
205
        b.commit('four', rev_id=r4, allow_pointless=False)
 
206
        self.check_inventory_shape(b.inventory,
215
207
                                   ['a', 'a/b/hello', 'a/b'])
216
208
 
217
 
        inv = b.repository.get_revision_inventory(r4)
 
209
        inv = b.get_revision_inventory(r4)
218
210
        eq(inv['hello-id'].revision, r4)
219
211
        eq(inv['a-id'].revision, r1)
220
212
        eq(inv['b-id'].revision, r3)
 
213
 
221
214
        
222
215
    def test_removed_commit(self):
223
 
        """Commit with a removed file"""
224
 
        wt = self.make_branch_and_tree('.')
225
 
        b = wt.branch
 
216
        """Test a commit with a removed file"""
 
217
        b = Branch.initialize('.')
226
218
        file('hello', 'w').write('hello world')
227
 
        wt.add(['hello'], ['hello-id'])
228
 
        wt.commit(message='add hello')
229
 
        wt.remove('hello')
230
 
        wt.commit('removed hello', rev_id='rev2')
231
 
 
232
 
        tree = b.repository.revision_tree('rev2')
 
219
        b.add(['hello'], ['hello-id'])
 
220
        b.commit(message='add hello')
 
221
 
 
222
        b.working_tree().remove('hello')
 
223
        b.commit('removed hello', rev_id='rev2')
 
224
 
 
225
        tree = b.revision_tree('rev2')
233
226
        self.assertFalse(tree.has_id('hello-id'))
234
227
 
 
228
 
235
229
    def test_committed_ancestry(self):
236
230
        """Test commit appends revisions to ancestry."""
237
 
        wt = self.make_branch_and_tree('.')
238
 
        b = wt.branch
 
231
        b = Branch.initialize('.')
239
232
        rev_ids = []
240
233
        for i in range(4):
241
234
            file('hello', 'w').write((str(i) * 4) + '\n')
242
235
            if i == 0:
243
 
                wt.add(['hello'], ['hello-id'])
 
236
                b.add(['hello'], ['hello-id'])
244
237
            rev_id = 'test@rev-%d' % (i+1)
245
238
            rev_ids.append(rev_id)
246
 
            wt.commit(message='rev %d' % (i+1),
 
239
            b.commit(message='rev %d' % (i+1),
247
240
                     rev_id=rev_id)
248
241
        eq = self.assertEquals
249
242
        eq(b.revision_history(), rev_ids)
250
243
        for i in range(4):
251
 
            anc = b.repository.get_ancestry(rev_ids[i])
 
244
            anc = b.get_ancestry(rev_ids[i])
252
245
            eq(anc, [None] + rev_ids[:i+1])
253
246
 
254
247
    def test_commit_new_subdir_child_selective(self):
255
 
        wt = self.make_branch_and_tree('.')
256
 
        b = wt.branch
 
248
        b = Branch.initialize('.')
257
249
        self.build_tree(['dir/', 'dir/file1', 'dir/file2'])
258
 
        wt.add(['dir', 'dir/file1', 'dir/file2'],
 
250
        b.add(['dir', 'dir/file1', 'dir/file2'],
259
251
              ['dirid', 'file1id', 'file2id'])
260
 
        wt.commit('dir/file1', specific_files=['dir/file1'], rev_id='1')
261
 
        inv = b.repository.get_inventory('1')
 
252
        b.commit('dir/file1', specific_files=['dir/file1'], rev_id='1')
 
253
        inv = b.get_inventory('1')
262
254
        self.assertEqual('1', inv['dirid'].revision)
263
255
        self.assertEqual('1', inv['file1id'].revision)
264
256
        # FIXME: This should raise a KeyError I think, rbc20051006
265
257
        self.assertRaises(BzrError, inv.__getitem__, 'file2id')
266
258
 
267
 
    def test_strict_commit(self):
268
 
        """Try and commit with unknown files and strict = True, should fail."""
269
 
        from bzrlib.errors import StrictCommitFailed
270
 
        wt = self.make_branch_and_tree('.')
271
 
        b = wt.branch
272
 
        file('hello', 'w').write('hello world')
273
 
        wt.add('hello')
274
 
        file('goodbye', 'w').write('goodbye cruel world!')
275
 
        self.assertRaises(StrictCommitFailed, wt.commit,
276
 
            message='add hello but not goodbye', strict=True)
277
 
 
278
 
    def test_strict_commit_without_unknowns(self):
279
 
        """Try and commit with no unknown files and strict = True,
280
 
        should work."""
281
 
        from bzrlib.errors import StrictCommitFailed
282
 
        wt = self.make_branch_and_tree('.')
283
 
        b = wt.branch
284
 
        file('hello', 'w').write('hello world')
285
 
        wt.add('hello')
286
 
        wt.commit(message='add hello', strict=True)
287
 
 
288
 
    def test_nonstrict_commit(self):
289
 
        """Try and commit with unknown files and strict = False, should work."""
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
 
        wt.commit(message='add hello but not goodbye', strict=False)
296
 
 
297
 
    def test_nonstrict_commit_without_unknowns(self):
298
 
        """Try and commit with no unknown files and strict = False,
299
 
        should work."""
300
 
        wt = self.make_branch_and_tree('.')
301
 
        b = wt.branch
302
 
        file('hello', 'w').write('hello world')
303
 
        wt.add('hello')
304
 
        wt.commit(message='add hello', strict=False)
305
 
 
306
259
    def test_signed_commit(self):
307
260
        import bzrlib.gpg
308
261
        import bzrlib.commit as commit
309
262
        oldstrategy = bzrlib.gpg.GPGStrategy
310
 
        wt = self.make_branch_and_tree('.')
311
 
        branch = wt.branch
312
 
        wt.commit("base", allow_pointless=True, rev_id='A')
313
 
        self.failIf(branch.repository.has_signature_for_revision_id('A'))
 
263
        branch = Branch.initialize('.')
 
264
        branch.commit("base", allow_pointless=True, rev_id='A')
 
265
        self.failIf(branch.revision_store.has_id('A', 'sig'))
314
266
        try:
315
267
            from bzrlib.testament import Testament
316
268
            # monkey patch gpg signing mechanism
317
269
            bzrlib.gpg.GPGStrategy = bzrlib.gpg.LoopbackGPGStrategy
318
 
            commit.Commit(config=MustSignConfig(branch)).commit(message="base",
 
270
            commit.Commit(config=MustSignConfig(branch)).commit(branch, "base",
319
271
                                                      allow_pointless=True,
320
 
                                                      rev_id='B',
321
 
                                                      working_tree=wt)
322
 
            self.assertEqual(Testament.from_revision(branch.repository,
323
 
                             'B').as_short_text(),
324
 
                             branch.repository.get_signature_text('B'))
 
272
                                                      rev_id='B')
 
273
            self.assertEqual(Testament.from_revision(branch,'B').as_short_text(),
 
274
                             branch.revision_store.get('B', 'sig').read())
325
275
        finally:
326
276
            bzrlib.gpg.GPGStrategy = oldstrategy
327
277
 
329
279
        import bzrlib.gpg
330
280
        import bzrlib.commit as commit
331
281
        oldstrategy = bzrlib.gpg.GPGStrategy
332
 
        wt = self.make_branch_and_tree('.')
333
 
        branch = wt.branch
334
 
        wt.commit("base", allow_pointless=True, rev_id='A')
335
 
        self.failIf(branch.repository.has_signature_for_revision_id('A'))
 
282
        branch = Branch.initialize('.')
 
283
        branch.commit("base", allow_pointless=True, rev_id='A')
 
284
        self.failIf(branch.revision_store.has_id('A', 'sig'))
336
285
        try:
337
286
            from bzrlib.testament import Testament
338
287
            # monkey patch gpg signing mechanism
340
289
            config = MustSignConfig(branch)
341
290
            self.assertRaises(SigningFailed,
342
291
                              commit.Commit(config=config).commit,
343
 
                              message="base",
 
292
                              branch, "base",
344
293
                              allow_pointless=True,
345
 
                              rev_id='B',
346
 
                              working_tree=wt)
347
 
            branch = Branch.open(self.get_url('.'))
 
294
                              rev_id='B')
 
295
            branch = Branch.open('.')
348
296
            self.assertEqual(branch.revision_history(), ['A'])
349
 
            self.failIf(branch.repository.has_revision('B'))
 
297
            self.failIf(branch.revision_store.has_id('B'))
350
298
        finally:
351
299
            bzrlib.gpg.GPGStrategy = oldstrategy
352
300
 
353
 
    def test_commit_invokes_hooks(self):
354
 
        import bzrlib.commit as commit
355
 
        wt = self.make_branch_and_tree('.')
356
 
        branch = wt.branch
357
 
        calls = []
358
 
        def called(branch, rev_id):
359
 
            calls.append('called')
360
 
        bzrlib.ahook = called
361
 
        try:
362
 
            config = BranchWithHooks(branch)
363
 
            commit.Commit(config=config).commit(
364
 
                            message = "base",
365
 
                            allow_pointless=True,
366
 
                            rev_id='A', working_tree = wt)
367
 
            self.assertEqual(['called', 'called'], calls)
368
 
        finally:
369
 
            del bzrlib.ahook
370
 
 
371
 
    def test_commit_object_doesnt_set_nick(self):
372
 
        # using the Commit object directly does not set the branch nick.
373
 
        wt = self.make_branch_and_tree('.')
374
 
        c = Commit()
375
 
        c.commit(working_tree=wt, message='empty tree', allow_pointless=True)
376
 
        self.assertEquals(wt.branch.revno(), 1)
377
 
        self.assertEqual({},
378
 
                         wt.branch.repository.get_revision(
379
 
                            wt.branch.last_revision()).properties)
380
 
 
381
 
    def test_safe_master_lock(self):
382
 
        os.mkdir('master')
383
 
        master = BzrDirMetaFormat1().initialize('master')
384
 
        master.create_repository()
385
 
        master_branch = master.create_branch()
386
 
        master.create_workingtree()
387
 
        bound = master.sprout('bound')
388
 
        wt = bound.open_workingtree()
389
 
        wt.branch.set_bound_location(os.path.realpath('master'))
390
 
        master_branch.lock_write()
391
 
        try:
392
 
            self.assertRaises(LockContention, wt.commit, 'silly')
393
 
        finally:
394
 
            master_branch.unlock()
 
301