1
# Copyright (C) 2005-2011 Canonical Ltd
1
# Copyright (C) 2005-2012, 2016 Canonical Ltd
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
21
21
from bzrlib import (
25
26
from bzrlib.branch import Branch
26
27
from bzrlib.bzrdir import BzrDirMetaFormat1
27
28
from bzrlib.commit import Commit, NullCommitReporter
28
from bzrlib.config import BranchConfig
29
29
from bzrlib.errors import (
45
45
# TODO: Test commit with some added, and added-but-missing files
47
class MustSignConfig(BranchConfig):
49
def signature_needed(self):
52
def gpg_signing_command(self):
56
class BranchWithHooks(BranchConfig):
58
def post_commit(self):
59
return "bzrlib.ahook bzrlib.ahook"
47
class MustSignConfig(config.MemoryStack):
50
super(MustSignConfig, self).__init__('''
51
gpg_signing_command=cat -
52
create_signatures=always
62
56
class CapturingReporter(NullCommitReporter):
88
82
"""Commit and check two versions of a single file."""
89
83
wt = self.make_branch_and_tree('.')
91
file('hello', 'w').write('hello world')
85
with file('hello', 'w') as f: f.write('hello world')
93
87
rev1 = wt.commit(message='add hello')
94
88
file_id = wt.path2id('hello')
96
file('hello', 'w').write('version 2')
90
with file('hello', 'w') as f: f.write('version 2')
97
91
rev2 = wt.commit(message='commit 2')
99
eq = self.assertEquals
101
95
rev = b.repository.get_revision(rev1)
102
96
eq(rev.message, 'add hello')
117
111
"""Attempt a lossy commit to a native branch."""
118
112
wt = self.make_branch_and_tree('.')
120
file('hello', 'w').write('hello world')
114
with file('hello', 'w') as f: f.write('hello world')
122
116
revid = wt.commit(message='add hello', rev_id='revid', lossy=True)
123
self.assertEquals('revid', revid)
117
self.assertEqual('revid', revid)
125
119
def test_commit_lossy_foreign(self):
126
120
"""Attempt a lossy commit to a foreign branch."""
128
122
wt = self.make_branch_and_tree('.',
129
123
format=test_foreign.DummyForeignVcsDirFormat())
131
file('hello', 'w').write('hello world')
125
with file('hello', 'w') as f: f.write('hello world')
133
127
revid = wt.commit(message='add hello', lossy=True,
134
128
timestamp=1302659388, timezone=0)
135
self.assertEquals('dummy-v1:1302659388.0-0-UNKNOWN', revid)
129
self.assertEqual('dummy-v1:1302659388.0-0-UNKNOWN', revid)
137
131
def test_commit_bound_lossy_foreign(self):
138
132
"""Attempt a lossy commit to a bzr branch bound to a foreign branch."""
141
135
format=test_foreign.DummyForeignVcsDirFormat())
142
136
wt = foreign_branch.create_checkout("local")
144
file('local/hello', 'w').write('hello world')
138
with file('local/hello', 'w') as f: f.write('hello world')
146
140
revid = wt.commit(message='add hello', lossy=True,
147
141
timestamp=1302659388, timezone=0)
148
self.assertEquals('dummy-v1:1302659388.0-0-0', revid)
149
self.assertEquals('dummy-v1:1302659388.0-0-0',
142
self.assertEqual('dummy-v1:1302659388.0-0-0', revid)
143
self.assertEqual('dummy-v1:1302659388.0-0-0',
150
144
foreign_branch.last_revision())
151
self.assertEquals('dummy-v1:1302659388.0-0-0',
145
self.assertEqual('dummy-v1:1302659388.0-0-0',
152
146
wt.branch.last_revision())
154
148
def test_missing_commit(self):
155
149
"""Test a commit with a missing file"""
156
150
wt = self.make_branch_and_tree('.')
158
file('hello', 'w').write('hello world')
152
with file('hello', 'w') as f: f.write('hello world')
159
153
wt.add(['hello'], ['hello-id'])
160
154
wt.commit(message='add hello')
162
156
os.remove('hello')
163
157
reporter = CapturingReporter()
164
158
wt.commit('removed hello', rev_id='rev2', reporter=reporter)
166
160
[('missing', u'hello'), ('deleted', u'hello')],
193
187
"""Commit refuses unless there are changes or it's forced."""
194
188
wt = self.make_branch_and_tree('.')
196
file('hello', 'w').write('hello')
190
with file('hello', 'w') as f: f.write('hello')
197
191
wt.add(['hello'])
198
192
wt.commit(message='add hello')
199
self.assertEquals(b.revno(), 1)
193
self.assertEqual(b.revno(), 1)
200
194
self.assertRaises(PointlessCommit,
203
197
allow_pointless=False)
204
self.assertEquals(b.revno(), 1)
198
self.assertEqual(b.revno(), 1)
206
200
def test_commit_empty(self):
207
201
"""Commiting an empty tree works."""
213
207
message='empty tree',
214
208
allow_pointless=False)
215
209
wt.commit(message='empty tree', allow_pointless=True)
216
self.assertEquals(b.revno(), 2)
210
self.assertEqual(b.revno(), 2)
218
212
def test_selective_delete(self):
219
213
"""Selective commit in tree with deletions"""
220
214
wt = self.make_branch_and_tree('.')
222
file('hello', 'w').write('hello')
223
file('buongia', 'w').write('buongia')
216
with file('hello', 'w') as f: f.write('hello')
217
with file('buongia', 'w') as f: f.write('buongia')
224
218
wt.add(['hello', 'buongia'],
225
219
['hello-id', 'buongia-id'])
226
220
wt.commit(message='add files',
227
221
rev_id='test@rev-1')
229
223
os.remove('hello')
230
file('buongia', 'w').write('new text')
224
with file('buongia', 'w') as f: f.write('new text')
231
225
wt.commit(message='update text',
232
226
specific_files=['buongia'],
233
227
allow_pointless=False,
238
232
allow_pointless=False,
239
233
rev_id='test@rev-3')
241
eq = self.assertEquals
235
eq = self.assertEqual
244
238
tree2 = b.repository.revision_tree('test@rev-2')
245
239
tree2.lock_read()
246
240
self.addCleanup(tree2.unlock)
247
241
self.assertTrue(tree2.has_filename('hello'))
248
self.assertEquals(tree2.get_file_text('hello-id'), 'hello')
249
self.assertEquals(tree2.get_file_text('buongia-id'), 'new text')
242
self.assertEqual(tree2.get_file_text('hello-id'), 'hello')
243
self.assertEqual(tree2.get_file_text('buongia-id'), 'new text')
251
245
tree3 = b.repository.revision_tree('test@rev-3')
252
246
tree3.lock_read()
253
247
self.addCleanup(tree3.unlock)
254
248
self.assertFalse(tree3.has_filename('hello'))
255
self.assertEquals(tree3.get_file_text('buongia-id'), 'new text')
249
self.assertEqual(tree3.get_file_text('buongia-id'), 'new text')
257
251
def test_commit_rename(self):
258
252
"""Test commit of a revision where a file is renamed."""
265
259
tree.rename_one('hello', 'fruity')
266
260
tree.commit(message='renamed', rev_id='test@rev-2', allow_pointless=False)
268
eq = self.assertEquals
262
eq = self.assertEqual
269
263
tree1 = b.repository.revision_tree('test@rev-1')
270
264
tree1.lock_read()
271
265
self.addCleanup(tree1.unlock)
342
336
"""Commit with a removed file"""
343
337
wt = self.make_branch_and_tree('.')
345
file('hello', 'w').write('hello world')
339
with file('hello', 'w') as f: f.write('hello world')
346
340
wt.add(['hello'], ['hello-id'])
347
341
wt.commit(message='add hello')
348
342
wt.remove('hello')
359
353
for i in range(4):
360
file('hello', 'w').write((str(i) * 4) + '\n')
354
with file('hello', 'w') as f: f.write((str(i) * 4) + '\n')
362
356
wt.add(['hello'], ['hello-id'])
363
357
rev_id = 'test@rev-%d' % (i+1)
386
380
from bzrlib.errors import StrictCommitFailed
387
381
wt = self.make_branch_and_tree('.')
389
file('hello', 'w').write('hello world')
383
with file('hello', 'w') as f: f.write('hello world')
391
file('goodbye', 'w').write('goodbye cruel world!')
385
with file('goodbye', 'w') as f: f.write('goodbye cruel world!')
392
386
self.assertRaises(StrictCommitFailed, wt.commit,
393
387
message='add hello but not goodbye', strict=True)
398
392
wt = self.make_branch_and_tree('.')
400
file('hello', 'w').write('hello world')
394
with file('hello', 'w') as f: f.write('hello world')
402
396
wt.commit(message='add hello', strict=True)
405
399
"""Try and commit with unknown files and strict = False, should work."""
406
400
wt = self.make_branch_and_tree('.')
408
file('hello', 'w').write('hello world')
402
with file('hello', 'w') as f: f.write('hello world')
410
file('goodbye', 'w').write('goodbye cruel world!')
404
with file('goodbye', 'w') as f: f.write('goodbye cruel world!')
411
405
wt.commit(message='add hello but not goodbye', strict=False)
413
407
def test_nonstrict_commit_without_unknowns(self):
416
410
wt = self.make_branch_and_tree('.')
418
file('hello', 'w').write('hello world')
412
with file('hello', 'w') as f: f.write('hello world')
420
414
wt.commit(message='add hello', strict=False)
431
425
from bzrlib.testament import Testament
432
426
# monkey patch gpg signing mechanism
433
427
bzrlib.gpg.GPGStrategy = bzrlib.gpg.LoopbackGPGStrategy
434
commit.Commit(config=MustSignConfig(branch)).commit(message="base",
435
allow_pointless=True,
428
conf = config.MemoryStack('''
429
gpg_signing_command=cat -
430
create_signatures=always
432
commit.Commit(config_stack=conf).commit(
433
message="base", allow_pointless=True, rev_id='B',
439
436
return bzrlib.gpg.LoopbackGPGStrategy(None).sign(text)
440
437
self.assertEqual(sign(Testament.from_revision(branch.repository,
441
'B').as_short_text()),
438
'B').as_short_text()),
442
439
branch.repository.get_signature_text('B'))
444
441
bzrlib.gpg.GPGStrategy = oldstrategy
455
452
# monkey patch gpg signing mechanism
456
453
bzrlib.gpg.GPGStrategy = bzrlib.gpg.DisabledGPGStrategy
457
config = MustSignConfig(branch)
454
conf = config.MemoryStack('''
455
gpg_signing_command=cat -
456
create_signatures=always
458
458
self.assertRaises(SigningFailed,
459
commit.Commit(config=config).commit,
459
commit.Commit(config_stack=conf).commit,
461
461
allow_pointless=True,
476
476
calls.append('called')
477
477
bzrlib.ahook = called
479
config = BranchWithHooks(branch)
480
commit.Commit(config=config).commit(
482
allow_pointless=True,
483
rev_id='A', working_tree = wt)
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',
484
483
self.assertEqual(['called', 'called'], calls)
490
489
wt = self.make_branch_and_tree('.')
492
491
c.commit(working_tree=wt, message='empty tree', allow_pointless=True)
493
self.assertEquals(wt.branch.revno(), 1)
492
self.assertEqual(wt.branch.revno(), 1)
494
493
self.assertEqual({},
495
494
wt.branch.repository.get_revision(
496
495
wt.branch.last_revision()).properties)
836
835
def test_commit_with_checkout_and_branch_sharing_repo(self):
837
836
repo = self.make_repository('repo', shared=True)
838
837
# make_branch_and_tree ignores shared repos
839
branch = bzrdir.BzrDir.create_branch_convenience('repo/branch')
838
branch = controldir.ControlDir.create_branch_convenience('repo/branch')
840
839
tree2 = branch.create_checkout('repo/tree2')
841
840
tree2.commit('message', rev_id='rev1')
842
841
self.assertTrue(tree2.branch.repository.has_revision('rev1'))