21
21
from bzrlib import (
28
26
from bzrlib.branch import Branch
29
from bzrlib.bzrdir import BzrDir, BzrDirMetaFormat1
27
from bzrlib.bzrdir import BzrDirMetaFormat1
30
28
from bzrlib.commit import Commit, NullCommitReporter
31
from bzrlib.config import BranchConfig
32
from bzrlib.errors import (PointlessCommit, BzrError, SigningFailed,
34
from bzrlib.tests import SymlinkFeature, TestCaseWithTransport
35
from bzrlib.workingtree import WorkingTree
29
from bzrlib.errors import (
35
from bzrlib.tests import (
36
TestCaseWithTransport,
39
from bzrlib.tests.features import (
42
from bzrlib.tests.matchers import MatchesAncestry
38
45
# TODO: Test commit with some added, and added-but-missing files
40
class MustSignConfig(BranchConfig):
42
def signature_needed(self):
45
def gpg_signing_command(self):
49
class BranchWithHooks(BranchConfig):
51
def post_commit(self):
52
return "bzrlib.ahook bzrlib.ahook"
47
class MustSignConfig(config.MemoryStack):
50
super(MustSignConfig, self).__init__('''
51
gpg_signing_command=cat -
52
create_signatures=always
55
56
class CapturingReporter(NullCommitReporter):
84
85
file('hello', 'w').write('hello world')
86
wt.commit(message='add hello')
87
rev1 = wt.commit(message='add hello')
87
88
file_id = wt.path2id('hello')
89
90
file('hello', 'w').write('version 2')
90
wt.commit(message='commit 2')
91
rev2 = wt.commit(message='commit 2')
92
93
eq = self.assertEquals
94
rh = b.revision_history()
95
rev = b.repository.get_revision(rh[0])
95
rev = b.repository.get_revision(rev1)
96
96
eq(rev.message, 'add hello')
98
tree1 = b.repository.revision_tree(rh[0])
98
tree1 = b.repository.revision_tree(rev1)
100
100
text = tree1.get_file_text(file_id)
102
102
self.assertEqual('hello world', text)
104
tree2 = b.repository.revision_tree(rh[1])
104
tree2 = b.repository.revision_tree(rev2)
105
105
tree2.lock_read()
106
106
text = tree2.get_file_text(file_id)
108
108
self.assertEqual('version 2', text)
110
def test_commit_lossy_native(self):
111
"""Attempt a lossy commit to a native branch."""
112
wt = self.make_branch_and_tree('.')
114
file('hello', 'w').write('hello world')
116
revid = wt.commit(message='add hello', rev_id='revid', lossy=True)
117
self.assertEquals('revid', revid)
119
def test_commit_lossy_foreign(self):
120
"""Attempt a lossy commit to a foreign branch."""
121
test_foreign.register_dummy_foreign_for_test(self)
122
wt = self.make_branch_and_tree('.',
123
format=test_foreign.DummyForeignVcsDirFormat())
125
file('hello', 'w').write('hello world')
127
revid = wt.commit(message='add hello', lossy=True,
128
timestamp=1302659388, timezone=0)
129
self.assertEquals('dummy-v1:1302659388.0-0-UNKNOWN', revid)
131
def test_commit_bound_lossy_foreign(self):
132
"""Attempt a lossy commit to a bzr branch bound to a foreign branch."""
133
test_foreign.register_dummy_foreign_for_test(self)
134
foreign_branch = self.make_branch('foreign',
135
format=test_foreign.DummyForeignVcsDirFormat())
136
wt = foreign_branch.create_checkout("local")
138
file('local/hello', 'w').write('hello world')
140
revid = wt.commit(message='add hello', lossy=True,
141
timestamp=1302659388, timezone=0)
142
self.assertEquals('dummy-v1:1302659388.0-0-0', revid)
143
self.assertEquals('dummy-v1:1302659388.0-0-0',
144
foreign_branch.last_revision())
145
self.assertEquals('dummy-v1:1302659388.0-0-0',
146
wt.branch.last_revision())
110
148
def test_missing_commit(self):
111
149
"""Test a commit with a missing file"""
112
150
wt = self.make_branch_and_tree('.')
116
154
wt.commit(message='add hello')
118
156
os.remove('hello')
119
wt.commit('removed hello', rev_id='rev2')
157
reporter = CapturingReporter()
158
wt.commit('removed hello', rev_id='rev2', reporter=reporter)
160
[('missing', u'hello'), ('deleted', u'hello')],
121
163
tree = b.repository.revision_tree('rev2')
122
164
self.assertFalse(tree.has_id('hello-id'))
224
266
eq(tree1.id2path('hello-id'), 'hello')
225
267
eq(tree1.get_file_text('hello-id'), 'contents of hello\n')
226
268
self.assertFalse(tree1.has_filename('fruity'))
227
self.check_inventory_shape(tree1.inventory, ['hello'])
228
ie = tree1.inventory['hello-id']
229
eq(ie.revision, 'test@rev-1')
269
self.check_tree_shape(tree1, ['hello'])
270
eq(tree1.get_file_revision('hello-id'), 'test@rev-1')
231
272
tree2 = b.repository.revision_tree('test@rev-2')
232
273
tree2.lock_read()
233
274
self.addCleanup(tree2.unlock)
234
275
eq(tree2.id2path('hello-id'), 'fruity')
235
276
eq(tree2.get_file_text('hello-id'), 'contents of hello\n')
236
self.check_inventory_shape(tree2.inventory, ['fruity'])
237
ie = tree2.inventory['hello-id']
238
eq(ie.revision, 'test@rev-2')
277
self.check_tree_shape(tree2, ['fruity'])
278
eq(tree2.get_file_revision('hello-id'), 'test@rev-2')
240
280
def test_reused_rev_id(self):
241
281
"""Test that a revision id cannot be reused in a branch"""
272
311
wt.commit('three', rev_id=r3, allow_pointless=False)
275
self.check_inventory_shape(wt.read_working_inventory(),
314
self.check_tree_shape(wt,
276
315
['a/', 'a/hello', 'a/b/'])
277
self.check_inventory_shape(b.repository.get_inventory(r3),
316
self.check_tree_shape(b.repository.revision_tree(r3),
278
317
['a/', 'a/hello', 'a/b/'])
320
358
rev_ids.append(rev_id)
321
359
wt.commit(message='rev %d' % (i+1),
323
eq = self.assertEquals
324
eq(b.revision_history(), rev_ids)
325
361
for i in range(4):
326
anc = b.repository.get_ancestry(rev_ids[i])
327
eq(anc, [None] + rev_ids[:i+1])
362
self.assertThat(rev_ids[:i+1],
363
MatchesAncestry(b.repository, rev_ids[i]))
329
365
def test_commit_new_subdir_child_selective(self):
330
366
wt = self.make_branch_and_tree('.')
385
420
wt = self.make_branch_and_tree('.')
386
421
branch = wt.branch
387
422
wt.commit("base", allow_pointless=True, rev_id='A')
388
self.failIf(branch.repository.has_signature_for_revision_id('A'))
423
self.assertFalse(branch.repository.has_signature_for_revision_id('A'))
390
425
from bzrlib.testament import Testament
391
426
# monkey patch gpg signing mechanism
392
427
bzrlib.gpg.GPGStrategy = bzrlib.gpg.LoopbackGPGStrategy
393
commit.Commit(config=MustSignConfig(branch)).commit(message="base",
394
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',
398
436
return bzrlib.gpg.LoopbackGPGStrategy(None).sign(text)
399
437
self.assertEqual(sign(Testament.from_revision(branch.repository,
400
'B').as_short_text()),
438
'B').as_short_text()),
401
439
branch.repository.get_signature_text('B'))
403
441
bzrlib.gpg.GPGStrategy = oldstrategy
409
447
wt = self.make_branch_and_tree('.')
410
448
branch = wt.branch
411
449
wt.commit("base", allow_pointless=True, rev_id='A')
412
self.failIf(branch.repository.has_signature_for_revision_id('A'))
450
self.assertFalse(branch.repository.has_signature_for_revision_id('A'))
414
from bzrlib.testament import Testament
415
452
# monkey patch gpg signing mechanism
416
453
bzrlib.gpg.GPGStrategy = bzrlib.gpg.DisabledGPGStrategy
417
config = MustSignConfig(branch)
454
conf = config.MemoryStack('''
455
gpg_signing_command=cat -
456
create_signatures=always
418
458
self.assertRaises(SigningFailed,
419
commit.Commit(config=config).commit,
459
commit.Commit(config_stack=conf).commit,
421
461
allow_pointless=True,
424
464
branch = Branch.open(self.get_url('.'))
425
self.assertEqual(branch.revision_history(), ['A'])
426
self.failIf(branch.repository.has_revision('B'))
465
self.assertEqual(branch.last_revision(), 'A')
466
self.assertFalse(branch.repository.has_revision('B'))
428
468
bzrlib.gpg.GPGStrategy = oldstrategy
436
476
calls.append('called')
437
477
bzrlib.ahook = called
439
config = BranchWithHooks(branch)
440
commit.Commit(config=config).commit(
442
allow_pointless=True,
443
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',
444
483
self.assertEqual(['called', 'called'], calls)