20
21
from bzrlib.selftest import TestCaseInTempDir
21
22
from bzrlib.branch import Branch
23
from bzrlib.workingtree import WorkingTree
22
24
from bzrlib.commit import Commit
23
from bzrlib.errors import PointlessCommit, BzrError
25
from bzrlib.config import BranchConfig
26
from bzrlib.errors import PointlessCommit, BzrError, SigningFailed
26
29
# TODO: Test commit with some added, and added-but-missing files
31
class MustSignConfig(BranchConfig):
33
def signature_needed(self):
36
def gpg_signing_command(self):
40
class BranchWithHooks(BranchConfig):
42
def post_commit(self):
43
return "bzrlib.ahook bzrlib.ahook"
28
46
class TestCommit(TestCaseInTempDir):
29
48
def test_simple_commit(self):
30
49
"""Commit and check two versions of a single file."""
31
b = Branch('.', init=True)
50
b = Branch.initialize('.')
32
51
file('hello', 'w').write('hello world')
34
53
b.commit(message='add hello')
137
155
b.rename_one('hello', 'fruity')
138
156
b.commit(message='renamed', rev_id='test@rev-2', allow_pointless=False)
158
eq = self.assertEquals
140
159
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')
160
eq(tree1.id2path('hello-id'), 'hello')
161
eq(tree1.get_file_text('hello-id'), 'contents of hello\n')
143
162
self.assertFalse(tree1.has_filename('fruity'))
144
163
self.check_inventory_shape(tree1.inventory, ['hello'])
164
ie = tree1.inventory['hello-id']
165
eq(ie.revision, 'test@rev-1')
146
167
tree2 = b.revision_tree('test@rev-2')
147
self.assertEquals(tree2.id2path('hello-id'), 'fruity')
148
self.assertEquals(tree2.get_file_text('hello-id'), 'contents of hello\n')
168
eq(tree2.id2path('hello-id'), 'fruity')
169
eq(tree2.get_file_text('hello-id'), 'contents of hello\n')
149
170
self.check_inventory_shape(tree2.inventory, ['fruity'])
171
ie = tree2.inventory['hello-id']
172
eq(ie.revision, 'test@rev-2')
152
175
def test_reused_rev_id(self):
153
176
"""Test that a revision id cannot be reused in a branch"""
154
b = Branch('.', init=True)
177
b = Branch.initialize('.')
155
178
b.commit('initial', rev_id='test@rev-1', allow_pointless=True)
156
179
self.assertRaises(Exception,
164
187
def test_commit_move(self):
165
188
"""Test commit of revisions with moved files and directories"""
166
b = Branch('.', init=True)
189
eq = self.assertEquals
190
b = Branch.initialize('.')
167
192
self.build_tree(['hello', 'a/', 'b/'])
168
193
b.add(['hello', 'a', 'b'], ['hello-id', 'a-id', 'b-id'])
169
b.commit('initial', rev_id='test@rev-1', allow_pointless=False)
194
b.commit('initial', rev_id=r1, allow_pointless=False)
171
196
b.move(['hello'], 'a')
172
b.commit('two', rev_id='test@rev-2', allow_pointless=False)
198
b.commit('two', rev_id=r2, allow_pointless=False)
173
199
self.check_inventory_shape(b.inventory,
174
200
['a', 'a/hello', 'b'])
176
202
b.move(['b'], 'a')
177
b.commit('three', rev_id='test@rev-3', allow_pointless=False)
204
b.commit('three', rev_id=r3, allow_pointless=False)
178
205
self.check_inventory_shape(b.inventory,
179
206
['a', 'a/hello', 'a/b'])
180
self.check_inventory_shape(b.get_revision_inventory('test@rev-3'),
207
self.check_inventory_shape(b.get_revision_inventory(r3),
181
208
['a', 'a/hello', 'a/b'])
183
210
b.move([os.sep.join(['a', 'hello'])],
184
211
os.sep.join(['a', 'b']))
185
b.commit('four', rev_id='test@rev-4', allow_pointless=False)
213
b.commit('four', rev_id=r4, allow_pointless=False)
186
214
self.check_inventory_shape(b.inventory,
187
215
['a', 'a/b/hello', 'a/b'])
217
inv = b.get_revision_inventory(r4)
218
eq(inv['hello-id'].revision, r4)
219
eq(inv['a-id'].revision, r1)
220
eq(inv['b-id'].revision, r3)
192
223
def test_removed_commit(self):
193
"""Test a commit with a removed file"""
194
b = Branch('.', init=True)
224
"""Commit with a removed file"""
225
b = Branch.initialize('.')
226
wt = b.working_tree()
195
227
file('hello', 'w').write('hello world')
196
228
b.add(['hello'], ['hello-id'])
197
229
b.commit(message='add hello')
231
wt = b.working_tree() # FIXME: kludge for aliasing of working inventory
200
233
b.commit('removed hello', rev_id='rev2')
202
235
tree = b.revision_tree('rev2')
219
252
eq(b.revision_history(), rev_ids)
220
253
for i in range(4):
221
254
anc = b.get_ancestry(rev_ids[i])
222
eq(anc, rev_ids[:i+1])
227
if __name__ == '__main__':
255
eq(anc, [None] + rev_ids[:i+1])
257
def test_commit_new_subdir_child_selective(self):
258
b = Branch.initialize('.')
259
self.build_tree(['dir/', 'dir/file1', 'dir/file2'])
260
b.add(['dir', 'dir/file1', 'dir/file2'],
261
['dirid', 'file1id', 'file2id'])
262
b.commit('dir/file1', specific_files=['dir/file1'], rev_id='1')
263
inv = b.get_inventory('1')
264
self.assertEqual('1', inv['dirid'].revision)
265
self.assertEqual('1', inv['file1id'].revision)
266
# FIXME: This should raise a KeyError I think, rbc20051006
267
self.assertRaises(BzrError, inv.__getitem__, 'file2id')
269
def test_strict_commit(self):
270
"""Try and commit with unknown files and strict = True, should fail."""
271
from bzrlib.errors import StrictCommitFailed
272
b = Branch.initialize('.')
273
file('hello', 'w').write('hello world')
275
file('goodbye', 'w').write('goodbye cruel world!')
276
self.assertRaises(StrictCommitFailed, b.commit,
277
message='add hello but not goodbye', strict=True)
279
def test_nonstrict_commit(self):
280
"""Try and commit with unknown files and strict = False, should work."""
281
b = Branch.initialize('.')
282
file('hello', 'w').write('hello world')
284
file('goodbye', 'w').write('goodbye cruel world!')
285
b.commit(message='add hello but not goodbye', strict=False)
287
def test_signed_commit(self):
289
import bzrlib.commit as commit
290
oldstrategy = bzrlib.gpg.GPGStrategy
291
branch = Branch.initialize('.')
292
branch.commit("base", allow_pointless=True, rev_id='A')
293
self.failIf(branch.revision_store.has_id('A', 'sig'))
295
from bzrlib.testament import Testament
296
# monkey patch gpg signing mechanism
297
bzrlib.gpg.GPGStrategy = bzrlib.gpg.LoopbackGPGStrategy
298
commit.Commit(config=MustSignConfig(branch)).commit(branch, "base",
299
allow_pointless=True,
301
self.assertEqual(Testament.from_revision(branch,'B').as_short_text(),
302
branch.revision_store.get('B', 'sig').read())
304
bzrlib.gpg.GPGStrategy = oldstrategy
306
def test_commit_failed_signature(self):
308
import bzrlib.commit as commit
309
oldstrategy = bzrlib.gpg.GPGStrategy
310
branch = Branch.initialize('.')
311
branch.commit("base", allow_pointless=True, rev_id='A')
312
self.failIf(branch.revision_store.has_id('A', 'sig'))
314
from bzrlib.testament import Testament
315
# monkey patch gpg signing mechanism
316
bzrlib.gpg.GPGStrategy = bzrlib.gpg.DisabledGPGStrategy
317
config = MustSignConfig(branch)
318
self.assertRaises(SigningFailed,
319
commit.Commit(config=config).commit,
321
allow_pointless=True,
323
branch = Branch.open('.')
324
self.assertEqual(branch.revision_history(), ['A'])
325
self.failIf(branch.revision_store.has_id('B'))
327
bzrlib.gpg.GPGStrategy = oldstrategy
329
def test_commit_invokes_hooks(self):
330
import bzrlib.commit as commit
331
branch = Branch.initialize('.')
333
def called(branch, rev_id):
334
calls.append('called')
335
bzrlib.ahook = called
337
config = BranchWithHooks(branch)
338
commit.Commit(config=config).commit(
340
allow_pointless=True,
342
self.assertEqual(['called', 'called'], calls)