21
from bzrlib.tests import TestCaseInTempDir
20
from bzrlib.selftest import TestCaseInTempDir
22
21
from bzrlib.branch import Branch
23
from bzrlib.workingtree import WorkingTree
24
22
from bzrlib.commit import Commit
25
from bzrlib.config import BranchConfig
26
from bzrlib.errors import PointlessCommit, BzrError, SigningFailed
23
from bzrlib.errors import PointlessCommit, BzrError
29
26
# 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"
46
28
class TestCommit(TestCaseInTempDir):
48
30
def test_simple_commit(self):
49
31
"""Commit and check two versions of a single file."""
50
32
b = Branch.initialize('.')
51
33
file('hello', 'w').write('hello world')
52
b.working_tree().add('hello')
53
b.working_tree().commit(message='add hello')
35
b.commit(message='add hello')
54
36
file_id = b.working_tree().path2id('hello')
56
38
file('hello', 'w').write('version 2')
57
b.working_tree().commit(message='commit 2')
39
b.commit(message='commit 2')
59
41
eq = self.assertEquals
69
51
tree2 = b.revision_tree(rh[1])
70
52
eq(tree2.get_file_text(file_id), 'version 2')
72
55
def test_delete_commit(self):
73
56
"""Test a commit with a deleted file"""
74
57
b = Branch.initialize('.')
75
58
file('hello', 'w').write('hello world')
76
b.working_tree().add(['hello'], ['hello-id'])
77
b.working_tree().commit(message='add hello')
59
b.add(['hello'], ['hello-id'])
60
b.commit(message='add hello')
80
b.working_tree().commit('removed hello', rev_id='rev2')
63
b.commit('removed hello', rev_id='rev2')
82
65
tree = b.revision_tree('rev2')
83
66
self.assertFalse(tree.has_id('hello-id'))
85
69
def test_pointless_commit(self):
86
70
"""Commit refuses unless there are changes or it's forced."""
87
71
b = Branch.initialize('.')
88
72
file('hello', 'w').write('hello')
89
b.working_tree().add(['hello'])
90
b.working_tree().commit(message='add hello')
74
b.commit(message='add hello')
91
75
self.assertEquals(b.revno(), 1)
92
76
self.assertRaises(PointlessCommit,
93
b.working_tree().commit,
95
79
allow_pointless=False)
96
80
self.assertEquals(b.revno(), 1)
98
84
def test_commit_empty(self):
99
85
"""Commiting an empty tree works."""
100
86
b = Branch.initialize('.')
101
b.working_tree().commit(message='empty tree', allow_pointless=True)
87
b.commit(message='empty tree', allow_pointless=True)
102
88
self.assertRaises(PointlessCommit,
103
b.working_tree().commit,
104
90
message='empty tree',
105
91
allow_pointless=False)
106
b.working_tree().commit(message='empty tree', allow_pointless=True)
92
b.commit(message='empty tree', allow_pointless=True)
107
93
self.assertEquals(b.revno(), 2)
112
98
b = Branch.initialize('.')
113
99
file('hello', 'w').write('hello')
114
100
file('buongia', 'w').write('buongia')
115
b.working_tree().add(['hello', 'buongia'],
101
b.add(['hello', 'buongia'],
116
102
['hello-id', 'buongia-id'])
117
b.working_tree().commit(message='add files',
103
b.commit(message='add files',
118
104
rev_id='test@rev-1')
120
106
os.remove('hello')
121
107
file('buongia', 'w').write('new text')
122
b.working_tree().commit(message='update text',
108
b.commit(message='update text',
123
109
specific_files=['buongia'],
124
110
allow_pointless=False,
125
111
rev_id='test@rev-2')
127
b.working_tree().commit(message='remove hello',
113
b.commit(message='remove hello',
128
114
specific_files=['hello'],
129
115
allow_pointless=False,
130
116
rev_id='test@rev-3')
145
131
def test_commit_rename(self):
146
132
"""Test commit of a revision where a file is renamed."""
147
133
b = Branch.initialize('.')
148
tree = WorkingTree('.', b)
149
self.build_tree(['hello'], line_endings='binary')
150
tree.add(['hello'], ['hello-id'])
151
tree.commit(message='one', rev_id='test@rev-1', allow_pointless=False)
134
self.build_tree(['hello'])
135
b.add(['hello'], ['hello-id'])
136
b.commit(message='one', rev_id='test@rev-1', allow_pointless=False)
153
tree.rename_one('hello', 'fruity')
154
tree.commit(message='renamed', rev_id='test@rev-2', allow_pointless=False)
138
b.rename_one('hello', 'fruity')
139
b.commit(message='renamed', rev_id='test@rev-2', allow_pointless=False)
156
141
eq = self.assertEquals
157
142
tree1 = b.revision_tree('test@rev-1')
185
173
b = Branch.initialize('.')
186
174
r1 = 'test@rev-1'
187
175
self.build_tree(['hello', 'a/', 'b/'])
188
b.working_tree().add(['hello', 'a', 'b'], ['hello-id', 'a-id', 'b-id'])
189
b.working_tree().commit('initial', rev_id=r1, allow_pointless=False)
190
b.working_tree().move(['hello'], 'a')
176
b.add(['hello', 'a', 'b'], ['hello-id', 'a-id', 'b-id'])
177
b.commit('initial', rev_id=r1, allow_pointless=False)
179
b.move(['hello'], 'a')
191
180
r2 = 'test@rev-2'
192
b.working_tree().commit('two', rev_id=r2, allow_pointless=False)
193
self.check_inventory_shape(b.working_tree().read_working_inventory(),
181
b.commit('two', rev_id=r2, allow_pointless=False)
182
self.check_inventory_shape(b.inventory,
194
183
['a', 'a/hello', 'b'])
196
b.working_tree().move(['b'], 'a')
197
186
r3 = 'test@rev-3'
198
b.working_tree().commit('three', rev_id=r3, allow_pointless=False)
199
self.check_inventory_shape(b.working_tree().read_working_inventory(),
187
b.commit('three', rev_id=r3, allow_pointless=False)
188
self.check_inventory_shape(b.inventory,
200
189
['a', 'a/hello', 'a/b'])
201
190
self.check_inventory_shape(b.get_revision_inventory(r3),
202
191
['a', 'a/hello', 'a/b'])
204
b.working_tree().move([os.sep.join(['a', 'hello'])],
193
b.move([os.sep.join(['a', 'hello'])],
205
194
os.sep.join(['a', 'b']))
206
195
r4 = 'test@rev-4'
207
b.working_tree().commit('four', rev_id=r4, allow_pointless=False)
208
self.check_inventory_shape(b.working_tree().read_working_inventory(),
196
b.commit('four', rev_id=r4, allow_pointless=False)
197
self.check_inventory_shape(b.inventory,
209
198
['a', 'a/b/hello', 'a/b'])
211
200
inv = b.get_revision_inventory(r4)
212
201
eq(inv['hello-id'].revision, r4)
213
202
eq(inv['a-id'].revision, r1)
214
203
eq(inv['b-id'].revision, r3)
216
206
def test_removed_commit(self):
217
"""Commit with a removed file"""
207
"""Test a commit with a removed file"""
218
208
b = Branch.initialize('.')
219
wt = b.working_tree()
220
209
file('hello', 'w').write('hello world')
221
b.working_tree().add(['hello'], ['hello-id'])
222
b.working_tree().commit(message='add hello')
210
b.add(['hello'], ['hello-id'])
211
b.commit(message='add hello')
224
wt = b.working_tree() # FIXME: kludge for aliasing of working inventory
226
b.working_tree().commit('removed hello', rev_id='rev2')
214
b.commit('removed hello', rev_id='rev2')
228
216
tree = b.revision_tree('rev2')
229
217
self.assertFalse(tree.has_id('hello-id'))
250
238
def test_commit_new_subdir_child_selective(self):
251
239
b = Branch.initialize('.')
252
240
self.build_tree(['dir/', 'dir/file1', 'dir/file2'])
253
b.working_tree().add(['dir', 'dir/file1', 'dir/file2'],
241
b.add(['dir', 'dir/file1', 'dir/file2'],
254
242
['dirid', 'file1id', 'file2id'])
255
b.working_tree().commit('dir/file1', specific_files=['dir/file1'], rev_id='1')
243
b.commit('dir/file1', specific_files=['dir/file1'], rev_id='1')
256
244
inv = b.get_inventory('1')
257
245
self.assertEqual('1', inv['dirid'].revision)
258
246
self.assertEqual('1', inv['file1id'].revision)
259
247
# FIXME: This should raise a KeyError I think, rbc20051006
260
248
self.assertRaises(BzrError, inv.__getitem__, 'file2id')
262
def test_strict_commit(self):
263
"""Try and commit with unknown files and strict = True, should fail."""
264
from bzrlib.errors import StrictCommitFailed
265
b = Branch.initialize('.')
266
file('hello', 'w').write('hello world')
267
b.working_tree().add('hello')
268
file('goodbye', 'w').write('goodbye cruel world!')
269
self.assertRaises(StrictCommitFailed, b.working_tree().commit,
270
message='add hello but not goodbye', strict=True)
272
def test_strict_commit_without_unknowns(self):
273
"""Try and commit with no unknown files and strict = True,
275
from bzrlib.errors import StrictCommitFailed
276
b = Branch.initialize('.')
277
file('hello', 'w').write('hello world')
278
b.working_tree().add('hello')
279
b.working_tree().commit(message='add hello', strict=True)
281
def test_nonstrict_commit(self):
282
"""Try and commit with unknown files and strict = False, should work."""
283
b = Branch.initialize('.')
284
file('hello', 'w').write('hello world')
285
b.working_tree().add('hello')
286
file('goodbye', 'w').write('goodbye cruel world!')
287
b.working_tree().commit(message='add hello but not goodbye', strict=False)
289
def test_nonstrict_commit_without_unknowns(self):
290
"""Try and commit with no unknown files and strict = False,
292
b = Branch.initialize('.')
293
file('hello', 'w').write('hello world')
294
b.working_tree().add('hello')
295
b.working_tree().commit(message='add hello', strict=False)
297
def test_signed_commit(self):
299
import bzrlib.commit as commit
300
oldstrategy = bzrlib.gpg.GPGStrategy
301
branch = Branch.initialize('.')
302
branch.working_tree().commit("base", allow_pointless=True, rev_id='A')
303
self.failIf(branch.revision_store.has_id('A', 'sig'))
305
from bzrlib.testament import Testament
306
# monkey patch gpg signing mechanism
307
bzrlib.gpg.GPGStrategy = bzrlib.gpg.LoopbackGPGStrategy
308
commit.Commit(config=MustSignConfig(branch)).commit(branch, "base",
309
allow_pointless=True,
311
self.assertEqual(Testament.from_revision(branch,'B').as_short_text(),
312
branch.revision_store.get('B', 'sig').read())
314
bzrlib.gpg.GPGStrategy = oldstrategy
316
def test_commit_failed_signature(self):
318
import bzrlib.commit as commit
319
oldstrategy = bzrlib.gpg.GPGStrategy
320
branch = Branch.initialize('.')
321
branch.working_tree().commit("base", allow_pointless=True, rev_id='A')
322
self.failIf(branch.revision_store.has_id('A', 'sig'))
324
from bzrlib.testament import Testament
325
# monkey patch gpg signing mechanism
326
bzrlib.gpg.GPGStrategy = bzrlib.gpg.DisabledGPGStrategy
327
config = MustSignConfig(branch)
328
self.assertRaises(SigningFailed,
329
commit.Commit(config=config).commit,
331
allow_pointless=True,
333
branch = Branch.open('.')
334
self.assertEqual(branch.revision_history(), ['A'])
335
self.failIf(branch.revision_store.has_id('B'))
337
bzrlib.gpg.GPGStrategy = oldstrategy
339
def test_commit_invokes_hooks(self):
340
import bzrlib.commit as commit
341
branch = Branch.initialize('.')
343
def called(branch, rev_id):
344
calls.append('called')
345
bzrlib.ahook = called
347
config = BranchWithHooks(branch)
348
commit.Commit(config=config).commit(
350
allow_pointless=True,
352
self.assertEqual(['called', 'called'], calls)