19
from io import BytesIO
28
from ..branch import Branch
29
from ..bzr.bzrdir import BzrDirMetaFormat1
30
from ..commit import (
31
CannotCommitSelectedFileMerge,
37
from ..errors import (
41
from ..tree import TreeChange
25
from bzrlib.branch import Branch
26
from bzrlib.bzrdir import BzrDirMetaFormat1
27
from bzrlib.commit import Commit, NullCommitReporter
28
from bzrlib.config import BranchConfig
29
from bzrlib.errors import (PointlessCommit, BzrError, SigningFailed,
31
from bzrlib.tests import (
44
33
TestCaseWithTransport,
47
from .features import (
50
from .matchers import MatchesAncestry
53
38
# TODO: Test commit with some added, and added-but-missing files
55
class MustSignConfig(config.MemoryStack):
58
super(MustSignConfig, self).__init__(b'''
59
create_signatures=always
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"
63
55
class CapturingReporter(NullCommitReporter):
89
81
"""Commit and check two versions of a single file."""
90
82
wt = self.make_branch_and_tree('.')
92
with open('hello', 'w') as f:
93
f.write('hello world')
84
file('hello', 'w').write('hello world')
95
rev1 = wt.commit(message='add hello')
97
with open('hello', 'w') as f:
99
rev2 = wt.commit(message='commit 2')
101
eq = self.assertEqual
86
wt.commit(message='add hello')
87
file_id = wt.path2id('hello')
89
file('hello', 'w').write('version 2')
90
wt.commit(message='commit 2')
92
eq = self.assertEquals
103
rev = b.repository.get_revision(rev1)
94
rh = b.revision_history()
95
rev = b.repository.get_revision(rh[0])
104
96
eq(rev.message, 'add hello')
106
tree1 = b.repository.revision_tree(rev1)
98
tree1 = b.repository.revision_tree(rh[0])
108
text = tree1.get_file_text('hello')
100
text = tree1.get_file_text(file_id)
110
self.assertEqual(b'hello world', text)
102
self.assertEqual('hello world', text)
112
tree2 = b.repository.revision_tree(rev2)
104
tree2 = b.repository.revision_tree(rh[1])
113
105
tree2.lock_read()
114
text = tree2.get_file_text('hello')
106
text = tree2.get_file_text(file_id)
116
self.assertEqual(b'version 2', text)
108
self.assertEqual('version 2', text)
118
110
def test_commit_lossy_native(self):
119
111
"""Attempt a lossy commit to a native branch."""
120
112
wt = self.make_branch_and_tree('.')
122
with open('hello', 'w') as f:
123
f.write('hello world')
114
file('hello', 'w').write('hello world')
125
revid = wt.commit(message='add hello', rev_id=b'revid', lossy=True)
126
self.assertEqual(b'revid', revid)
116
revid = wt.commit(message='add hello', rev_id='revid', lossy=True)
117
self.assertEquals('revid', revid)
128
119
def test_commit_lossy_foreign(self):
129
120
"""Attempt a lossy commit to a foreign branch."""
130
121
test_foreign.register_dummy_foreign_for_test(self)
131
122
wt = self.make_branch_and_tree('.',
132
format=test_foreign.DummyForeignVcsDirFormat())
123
format=test_foreign.DummyForeignVcsDirFormat())
134
with open('hello', 'w') as f:
135
f.write('hello world')
125
file('hello', 'w').write('hello world')
137
127
revid = wt.commit(message='add hello', lossy=True,
138
timestamp=1302659388, timezone=0)
139
self.assertEqual(b'dummy-v1:1302659388-0-UNKNOWN', revid)
128
timestamp=1302659388, timezone=0)
129
self.assertEquals('dummy-v1:1302659388.0-0-UNKNOWN', revid)
141
131
def test_commit_bound_lossy_foreign(self):
142
132
"""Attempt a lossy commit to a bzr branch bound to a foreign branch."""
143
133
test_foreign.register_dummy_foreign_for_test(self)
144
134
foreign_branch = self.make_branch('foreign',
145
format=test_foreign.DummyForeignVcsDirFormat())
135
format=test_foreign.DummyForeignVcsDirFormat())
146
136
wt = foreign_branch.create_checkout("local")
148
with open('local/hello', 'w') as f:
149
f.write('hello world')
138
file('local/hello', 'w').write('hello world')
151
140
revid = wt.commit(message='add hello', lossy=True,
152
timestamp=1302659388, timezone=0)
153
self.assertEqual(b'dummy-v1:1302659388-0-0', revid)
154
self.assertEqual(b'dummy-v1:1302659388-0-0',
155
foreign_branch.last_revision())
156
self.assertEqual(b'dummy-v1:1302659388-0-0',
157
wt.branch.last_revision())
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())
159
148
def test_missing_commit(self):
160
149
"""Test a commit with a missing file"""
161
150
wt = self.make_branch_and_tree('.')
163
with open('hello', 'w') as f:
164
f.write('hello world')
165
wt.add(['hello'], [b'hello-id'])
152
file('hello', 'w').write('hello world')
153
wt.add(['hello'], ['hello-id'])
166
154
wt.commit(message='add hello')
168
156
os.remove('hello')
169
reporter = CapturingReporter()
170
wt.commit('removed hello', rev_id=b'rev2', reporter=reporter)
172
[('missing', u'hello'), ('deleted', u'hello')],
157
wt.commit('removed hello', rev_id='rev2')
175
tree = b.repository.revision_tree(b'rev2')
176
self.assertFalse(tree.has_filename('hello'))
159
tree = b.repository.revision_tree('rev2')
160
self.assertFalse(tree.has_id('hello-id'))
178
162
def test_partial_commit_move(self):
179
163
"""Test a partial commit where a file was renamed but not committed.
189
173
self.build_tree(['annotate/', 'annotate/foo.py',
190
174
'olive/', 'olive/dialog.py'
192
176
wt.add(['annotate', 'olive', 'annotate/foo.py', 'olive/dialog.py'])
193
177
wt.commit(message='add files')
194
178
wt.rename_one("olive/dialog.py", "aaa")
195
self.build_tree_contents([('annotate/foo.py', b'modified\n')])
179
self.build_tree_contents([('annotate/foo.py', 'modified\n')])
196
180
wt.commit('renamed hello', specific_files=["annotate"])
198
182
def test_pointless_commit(self):
199
183
"""Commit refuses unless there are changes or it's forced."""
200
184
wt = self.make_branch_and_tree('.')
202
with open('hello', 'w') as f:
186
file('hello', 'w').write('hello')
204
187
wt.add(['hello'])
205
188
wt.commit(message='add hello')
206
self.assertEqual(b.revno(), 1)
189
self.assertEquals(b.revno(), 1)
207
190
self.assertRaises(PointlessCommit,
210
193
allow_pointless=False)
211
self.assertEqual(b.revno(), 1)
194
self.assertEquals(b.revno(), 1)
213
196
def test_commit_empty(self):
214
197
"""Commiting an empty tree works."""
220
203
message='empty tree',
221
204
allow_pointless=False)
222
205
wt.commit(message='empty tree', allow_pointless=True)
223
self.assertEqual(b.revno(), 2)
206
self.assertEquals(b.revno(), 2)
225
208
def test_selective_delete(self):
226
209
"""Selective commit in tree with deletions"""
227
210
wt = self.make_branch_and_tree('.')
229
with open('hello', 'w') as f:
231
with open('buongia', 'w') as f:
212
file('hello', 'w').write('hello')
213
file('buongia', 'w').write('buongia')
233
214
wt.add(['hello', 'buongia'],
234
[b'hello-id', b'buongia-id'])
215
['hello-id', 'buongia-id'])
235
216
wt.commit(message='add files',
236
rev_id=b'test@rev-1')
238
219
os.remove('hello')
239
with open('buongia', 'w') as f:
220
file('buongia', 'w').write('new text')
241
221
wt.commit(message='update text',
242
specific_files=['buongia'],
243
allow_pointless=False,
244
rev_id=b'test@rev-2')
222
specific_files=['buongia'],
223
allow_pointless=False,
246
226
wt.commit(message='remove hello',
247
specific_files=['hello'],
248
allow_pointless=False,
249
rev_id=b'test@rev-3')
227
specific_files=['hello'],
228
allow_pointless=False,
251
eq = self.assertEqual
231
eq = self.assertEquals
254
tree2 = b.repository.revision_tree(b'test@rev-2')
234
tree2 = b.repository.revision_tree('test@rev-2')
255
235
tree2.lock_read()
256
236
self.addCleanup(tree2.unlock)
257
237
self.assertTrue(tree2.has_filename('hello'))
258
self.assertEqual(tree2.get_file_text('hello'), b'hello')
259
self.assertEqual(tree2.get_file_text('buongia'), b'new text')
238
self.assertEquals(tree2.get_file_text('hello-id'), 'hello')
239
self.assertEquals(tree2.get_file_text('buongia-id'), 'new text')
261
tree3 = b.repository.revision_tree(b'test@rev-3')
241
tree3 = b.repository.revision_tree('test@rev-3')
262
242
tree3.lock_read()
263
243
self.addCleanup(tree3.unlock)
264
244
self.assertFalse(tree3.has_filename('hello'))
265
self.assertEqual(tree3.get_file_text('buongia'), b'new text')
245
self.assertEquals(tree3.get_file_text('buongia-id'), 'new text')
267
247
def test_commit_rename(self):
268
248
"""Test commit of a revision where a file is renamed."""
269
249
tree = self.make_branch_and_tree('.')
271
251
self.build_tree(['hello'], line_endings='binary')
272
tree.add(['hello'], [b'hello-id'])
273
tree.commit(message='one', rev_id=b'test@rev-1', allow_pointless=False)
252
tree.add(['hello'], ['hello-id'])
253
tree.commit(message='one', rev_id='test@rev-1', allow_pointless=False)
275
255
tree.rename_one('hello', 'fruity')
276
tree.commit(message='renamed', rev_id=b'test@rev-2',
277
allow_pointless=False)
256
tree.commit(message='renamed', rev_id='test@rev-2', allow_pointless=False)
279
eq = self.assertEqual
280
tree1 = b.repository.revision_tree(b'test@rev-1')
258
eq = self.assertEquals
259
tree1 = b.repository.revision_tree('test@rev-1')
281
260
tree1.lock_read()
282
261
self.addCleanup(tree1.unlock)
283
eq(tree1.id2path(b'hello-id'), 'hello')
284
eq(tree1.get_file_text('hello'), b'contents of hello\n')
262
eq(tree1.id2path('hello-id'), 'hello')
263
eq(tree1.get_file_text('hello-id'), 'contents of hello\n')
285
264
self.assertFalse(tree1.has_filename('fruity'))
286
265
self.check_tree_shape(tree1, ['hello'])
287
eq(tree1.get_file_revision('hello'), b'test@rev-1')
266
eq(tree1.get_file_revision('hello-id'), 'test@rev-1')
289
tree2 = b.repository.revision_tree(b'test@rev-2')
268
tree2 = b.repository.revision_tree('test@rev-2')
290
269
tree2.lock_read()
291
270
self.addCleanup(tree2.unlock)
292
eq(tree2.id2path(b'hello-id'), 'fruity')
293
eq(tree2.get_file_text('fruity'), b'contents of hello\n')
271
eq(tree2.id2path('hello-id'), 'fruity')
272
eq(tree2.get_file_text('hello-id'), 'contents of hello\n')
294
273
self.check_tree_shape(tree2, ['fruity'])
295
eq(tree2.get_file_revision('fruity'), b'test@rev-2')
274
eq(tree2.get_file_revision('hello-id'), 'test@rev-2')
297
276
def test_reused_rev_id(self):
298
277
"""Test that a revision id cannot be reused in a branch"""
299
278
wt = self.make_branch_and_tree('.')
301
wt.commit('initial', rev_id=b'test@rev-1', allow_pointless=True)
280
wt.commit('initial', rev_id='test@rev-1', allow_pointless=True)
302
281
self.assertRaises(Exception,
304
283
message='reused id',
305
rev_id=b'test@rev-1',
306
285
allow_pointless=True)
308
287
def test_commit_move(self):
309
288
"""Test commit of revisions with moved files and directories"""
310
eq = self.assertEqual
289
eq = self.assertEquals
311
290
wt = self.make_branch_and_tree('.')
314
293
self.build_tree(['hello', 'a/', 'b/'])
315
wt.add(['hello', 'a', 'b'], [b'hello-id', b'a-id', b'b-id'])
294
wt.add(['hello', 'a', 'b'], ['hello-id', 'a-id', 'b-id'])
316
295
wt.commit('initial', rev_id=r1, allow_pointless=False)
317
296
wt.move(['hello'], 'a')
319
298
wt.commit('two', rev_id=r2, allow_pointless=False)
347
326
inv = b.repository.get_inventory(r4)
348
eq(inv.get_entry(b'hello-id').revision, r4)
349
eq(inv.get_entry(b'a-id').revision, r1)
350
eq(inv.get_entry(b'b-id').revision, r3)
327
eq(inv['hello-id'].revision, r4)
328
eq(inv['a-id'].revision, r1)
329
eq(inv['b-id'].revision, r3)
352
331
def test_removed_commit(self):
353
332
"""Commit with a removed file"""
354
333
wt = self.make_branch_and_tree('.')
356
with open('hello', 'w') as f:
357
f.write('hello world')
358
wt.add(['hello'], [b'hello-id'])
335
file('hello', 'w').write('hello world')
336
wt.add(['hello'], ['hello-id'])
359
337
wt.commit(message='add hello')
360
338
wt.remove('hello')
361
wt.commit('removed hello', rev_id=b'rev2')
339
wt.commit('removed hello', rev_id='rev2')
363
tree = b.repository.revision_tree(b'rev2')
364
self.assertFalse(tree.has_filename('hello'))
341
tree = b.repository.revision_tree('rev2')
342
self.assertFalse(tree.has_id('hello-id'))
366
344
def test_committed_ancestry(self):
367
345
"""Test commit appends revisions to ancestry."""
371
349
for i in range(4):
372
with open('hello', 'w') as f:
373
f.write((str(i) * 4) + '\n')
350
file('hello', 'w').write((str(i) * 4) + '\n')
375
wt.add(['hello'], [b'hello-id'])
376
rev_id = b'test@rev-%d' % (i + 1)
352
wt.add(['hello'], ['hello-id'])
353
rev_id = 'test@rev-%d' % (i+1)
377
354
rev_ids.append(rev_id)
378
wt.commit(message='rev %d' % (i + 1),
355
wt.commit(message='rev %d' % (i+1),
357
eq = self.assertEquals
358
eq(b.revision_history(), rev_ids)
380
359
for i in range(4):
381
self.assertThat(rev_ids[:i + 1],
382
MatchesAncestry(b.repository, rev_ids[i]))
360
anc = b.repository.get_ancestry(rev_ids[i])
361
eq(anc, [None] + rev_ids[:i+1])
384
363
def test_commit_new_subdir_child_selective(self):
385
364
wt = self.make_branch_and_tree('.')
387
366
self.build_tree(['dir/', 'dir/file1', 'dir/file2'])
388
367
wt.add(['dir', 'dir/file1', 'dir/file2'],
389
[b'dirid', b'file1id', b'file2id'])
390
wt.commit('dir/file1', specific_files=['dir/file1'], rev_id=b'1')
391
inv = b.repository.get_inventory(b'1')
392
self.assertEqual(b'1', inv.get_entry(b'dirid').revision)
393
self.assertEqual(b'1', inv.get_entry(b'file1id').revision)
368
['dirid', 'file1id', 'file2id'])
369
wt.commit('dir/file1', specific_files=['dir/file1'], rev_id='1')
370
inv = b.repository.get_inventory('1')
371
self.assertEqual('1', inv['dirid'].revision)
372
self.assertEqual('1', inv['file1id'].revision)
394
373
# FIXME: This should raise a KeyError I think, rbc20051006
395
self.assertRaises(BzrError, inv.get_entry, b'file2id')
374
self.assertRaises(BzrError, inv.__getitem__, 'file2id')
397
376
def test_strict_commit(self):
398
377
"""Try and commit with unknown files and strict = True, should fail."""
399
from ..errors import StrictCommitFailed
378
from bzrlib.errors import StrictCommitFailed
400
379
wt = self.make_branch_and_tree('.')
402
with open('hello', 'w') as f:
403
f.write('hello world')
381
file('hello', 'w').write('hello world')
405
with open('goodbye', 'w') as f:
406
f.write('goodbye cruel world!')
383
file('goodbye', 'w').write('goodbye cruel world!')
407
384
self.assertRaises(StrictCommitFailed, wt.commit,
408
message='add hello but not goodbye', strict=True)
385
message='add hello but not goodbye', strict=True)
410
387
def test_strict_commit_without_unknowns(self):
411
388
"""Try and commit with no unknown files and strict = True,
413
390
wt = self.make_branch_and_tree('.')
415
with open('hello', 'w') as f:
416
f.write('hello world')
392
file('hello', 'w').write('hello world')
418
394
wt.commit(message='add hello', strict=True)
434
408
wt = self.make_branch_and_tree('.')
436
with open('hello', 'w') as f:
437
f.write('hello world')
410
file('hello', 'w').write('hello world')
439
412
wt.commit(message='add hello', strict=False)
441
414
def test_signed_commit(self):
443
import breezy.commit as commit
444
oldstrategy = breezy.gpg.GPGStrategy
416
import bzrlib.commit as commit
417
oldstrategy = bzrlib.gpg.GPGStrategy
445
418
wt = self.make_branch_and_tree('.')
446
419
branch = wt.branch
447
wt.commit("base", allow_pointless=True, rev_id=b'A')
448
self.assertFalse(branch.repository.has_signature_for_revision_id(b'A'))
420
wt.commit("base", allow_pointless=True, rev_id='A')
421
self.assertFalse(branch.repository.has_signature_for_revision_id('A'))
450
from ..bzr.testament import Testament
423
from bzrlib.testament import Testament
451
424
# monkey patch gpg signing mechanism
452
breezy.gpg.GPGStrategy = breezy.gpg.LoopbackGPGStrategy
453
conf = config.MemoryStack(b'''
454
create_signatures=always
456
commit.Commit(config_stack=conf).commit(
457
message="base", allow_pointless=True, rev_id=b'B',
425
bzrlib.gpg.GPGStrategy = bzrlib.gpg.LoopbackGPGStrategy
426
commit.Commit(config=MustSignConfig(branch)).commit(message="base",
427
allow_pointless=True,
461
return breezy.gpg.LoopbackGPGStrategy(None).sign(
462
text, breezy.gpg.MODE_CLEAR)
431
return bzrlib.gpg.LoopbackGPGStrategy(None).sign(text)
463
432
self.assertEqual(sign(Testament.from_revision(branch.repository,
464
b'B').as_short_text()),
465
branch.repository.get_signature_text(b'B'))
433
'B').as_short_text()),
434
branch.repository.get_signature_text('B'))
467
breezy.gpg.GPGStrategy = oldstrategy
436
bzrlib.gpg.GPGStrategy = oldstrategy
469
438
def test_commit_failed_signature(self):
471
import breezy.commit as commit
472
oldstrategy = breezy.gpg.GPGStrategy
440
import bzrlib.commit as commit
441
oldstrategy = bzrlib.gpg.GPGStrategy
473
442
wt = self.make_branch_and_tree('.')
474
443
branch = wt.branch
475
wt.commit("base", allow_pointless=True, rev_id=b'A')
476
self.assertFalse(branch.repository.has_signature_for_revision_id(b'A'))
444
wt.commit("base", allow_pointless=True, rev_id='A')
445
self.assertFalse(branch.repository.has_signature_for_revision_id('A'))
478
447
# monkey patch gpg signing mechanism
479
breezy.gpg.GPGStrategy = breezy.gpg.DisabledGPGStrategy
480
conf = config.MemoryStack(b'''
481
create_signatures=always
483
self.assertRaises(breezy.gpg.SigningFailed,
484
commit.Commit(config_stack=conf).commit,
448
bzrlib.gpg.GPGStrategy = bzrlib.gpg.DisabledGPGStrategy
449
config = MustSignConfig(branch)
450
self.assertRaises(SigningFailed,
451
commit.Commit(config=config).commit,
486
453
allow_pointless=True,
489
456
branch = Branch.open(self.get_url('.'))
490
self.assertEqual(branch.last_revision(), b'A')
491
self.assertFalse(branch.repository.has_revision(b'B'))
457
self.assertEqual(branch.revision_history(), ['A'])
458
self.assertFalse(branch.repository.has_revision('B'))
493
breezy.gpg.GPGStrategy = oldstrategy
460
bzrlib.gpg.GPGStrategy = oldstrategy
495
462
def test_commit_invokes_hooks(self):
496
import breezy.commit as commit
463
import bzrlib.commit as commit
497
464
wt = self.make_branch_and_tree('.')
498
465
branch = wt.branch
501
467
def called(branch, rev_id):
502
468
calls.append('called')
503
breezy.ahook = called
469
bzrlib.ahook = called
505
conf = config.MemoryStack(b'post_commit=breezy.ahook breezy.ahook')
506
commit.Commit(config_stack=conf).commit(
507
message="base", allow_pointless=True, rev_id=b'A',
471
config = BranchWithHooks(branch)
472
commit.Commit(config=config).commit(
474
allow_pointless=True,
475
rev_id='A', working_tree = wt)
509
476
self.assertEqual(['called', 'called'], calls)
513
480
def test_commit_object_doesnt_set_nick(self):
514
481
# using the Commit object directly does not set the branch nick.
515
482
wt = self.make_branch_and_tree('.')
517
484
c.commit(working_tree=wt, message='empty tree', allow_pointless=True)
518
self.assertEqual(wt.branch.revno(), 1)
485
self.assertEquals(wt.branch.revno(), 1)
519
486
self.assertEqual({},
520
487
wt.branch.repository.get_revision(
521
wt.branch.last_revision()).properties)
488
wt.branch.last_revision()).properties)
523
490
def test_safe_master_lock(self):
524
491
os.mkdir('master')
539
509
bound_tree = self.make_branch_and_tree('bound')
540
510
bound_tree.branch.bind(master_branch)
542
self.build_tree_contents(
543
[('bound/content_file', b'initial contents\n')])
512
self.build_tree_contents([('bound/content_file', 'initial contents\n')])
544
513
bound_tree.add(['content_file'])
545
514
bound_tree.commit(message='woo!')
547
other_bzrdir = master_branch.controldir.sprout('other')
516
other_bzrdir = master_branch.bzrdir.sprout('other')
548
517
other_tree = other_bzrdir.open_workingtree()
550
519
# do a commit to the other branch changing the content file so
551
520
# that our commit after merging will have a merged revision in the
552
521
# content file history.
553
self.build_tree_contents(
554
[('other/content_file', b'change in other\n')])
522
self.build_tree_contents([('other/content_file', 'change in other\n')])
555
523
other_tree.commit('change in other')
557
525
# do a merge into the bound branch from other, and then change the
558
526
# content file locally to force a new revision (rather than using the
559
527
# revision from other). This forces extra processing in commit.
560
528
bound_tree.merge_from_branch(other_tree.branch)
561
self.build_tree_contents(
562
[('bound/content_file', b'change in bound\n')])
529
self.build_tree_contents([('bound/content_file', 'change in bound\n')])
564
531
# before #34959 was fixed, this failed with 'revision not present in
565
532
# weave' when trying to implicitly push from the bound branch to the master
661
630
tree = self.make_branch_and_tree('.')
662
631
self.build_tree(['a'])
664
tree.commit('added a', rev_id=b'a1')
633
tree.commit('added a', rev_id='a1')
666
rev = tree.branch.repository.get_revision(b'a1')
635
rev = tree.branch.repository.get_revision('a1')
667
636
timestamp = rev.timestamp
668
637
timestamp_1ms = round(timestamp, 3)
669
638
self.assertEqual(timestamp_1ms, timestamp)
671
def assertBasisTreeKind(self, kind, tree, path):
640
def assertBasisTreeKind(self, kind, tree, file_id):
672
641
basis = tree.basis_tree()
673
642
basis.lock_read()
675
self.assertEqual(kind, basis.kind(path))
644
self.assertEqual(kind, basis.kind(file_id))
679
def test_unsupported_symlink_commit(self):
680
self.requireFeature(SymlinkFeature)
681
tree = self.make_branch_and_tree('.')
682
self.build_tree(['hello'])
684
tree.commit('added hello', rev_id=b'hello_id')
685
os.symlink('hello', 'foo')
687
tree.commit('added foo', rev_id=b'foo_id')
689
trace.push_log_file(log)
690
os_symlink = getattr(os, 'symlink', None)
693
# At this point as bzr thinks symlinks are not supported
694
# we should get a warning about symlink foo and bzr should
695
# not think its removed.
697
self.build_tree(['world'])
699
tree.commit('added world', rev_id=b'world_id')
702
os.symlink = os_symlink
703
self.assertContainsRe(
705
b'Ignoring "foo" as symlinks are not '
706
b'supported on this filesystem\\.')
708
648
def test_commit_kind_changes(self):
709
649
self.requireFeature(SymlinkFeature)
710
650
tree = self.make_branch_and_tree('.')
711
651
os.symlink('target', 'name')
712
tree.add('name', b'a-file-id')
652
tree.add('name', 'a-file-id')
713
653
tree.commit('Added a symlink')
714
self.assertBasisTreeKind('symlink', tree, 'name')
654
self.assertBasisTreeKind('symlink', tree, 'a-file-id')
716
656
os.unlink('name')
717
657
self.build_tree(['name'])
718
658
tree.commit('Changed symlink to file')
719
self.assertBasisTreeKind('file', tree, 'name')
659
self.assertBasisTreeKind('file', tree, 'a-file-id')
721
661
os.unlink('name')
722
662
os.symlink('target', 'name')
723
663
tree.commit('file to symlink')
724
self.assertBasisTreeKind('symlink', tree, 'name')
664
self.assertBasisTreeKind('symlink', tree, 'a-file-id')
726
666
os.unlink('name')
728
668
tree.commit('symlink to directory')
729
self.assertBasisTreeKind('directory', tree, 'name')
669
self.assertBasisTreeKind('directory', tree, 'a-file-id')
732
672
os.symlink('target', 'name')
733
673
tree.commit('directory to symlink')
734
self.assertBasisTreeKind('symlink', tree, 'name')
674
self.assertBasisTreeKind('symlink', tree, 'a-file-id')
736
676
# prepare for directory <-> file tests
737
677
os.unlink('name')
739
679
tree.commit('symlink to directory')
740
self.assertBasisTreeKind('directory', tree, 'name')
680
self.assertBasisTreeKind('directory', tree, 'a-file-id')
743
683
self.build_tree(['name'])
744
684
tree.commit('Changed directory to file')
745
self.assertBasisTreeKind('file', tree, 'name')
685
self.assertBasisTreeKind('file', tree, 'a-file-id')
747
687
os.unlink('name')
749
689
tree.commit('file to directory')
750
self.assertBasisTreeKind('directory', tree, 'name')
690
self.assertBasisTreeKind('directory', tree, 'a-file-id')
752
692
def test_commit_unversioned_specified(self):
753
693
"""Commit should raise if specified files isn't in basis or worktree"""
867
806
def test_multiple_authors(self):
868
807
tree = self.make_branch_and_tree('foo')
869
808
rev_id = tree.commit('commit 1',
870
authors=['John Doe <jdoe@example.com>',
871
'Jane Rey <jrey@example.com>'])
809
authors=['John Doe <jdoe@example.com>',
810
'Jane Rey <jrey@example.com>'])
872
811
rev = tree.branch.repository.get_revision(rev_id)
873
812
self.assertEqual('John Doe <jdoe@example.com>\n'
874
'Jane Rey <jrey@example.com>', rev.properties['authors'])
813
'Jane Rey <jrey@example.com>', rev.properties['authors'])
875
814
self.assertFalse('author' in rev.properties)
816
def test_author_and_authors_incompatible(self):
817
tree = self.make_branch_and_tree('foo')
818
self.assertRaises(AssertionError, tree.commit, 'commit 1',
819
authors=['John Doe <jdoe@example.com>',
820
'Jane Rey <jrey@example.com>'],
821
author="Jack Me <jme@example.com>")
877
823
def test_author_with_newline_rejected(self):
878
824
tree = self.make_branch_and_tree('foo')
879
825
self.assertRaises(AssertionError, tree.commit, 'commit 1',
880
authors=['John\nDoe <jdoe@example.com>'])
826
authors=['John\nDoe <jdoe@example.com>'])
882
828
def test_commit_with_checkout_and_branch_sharing_repo(self):
883
829
repo = self.make_repository('repo', shared=True)
884
830
# make_branch_and_tree ignores shared repos
885
branch = controldir.ControlDir.create_branch_convenience('repo/branch')
831
branch = bzrdir.BzrDir.create_branch_convenience('repo/branch')
886
832
tree2 = branch.create_checkout('repo/tree2')
887
tree2.commit('message', rev_id=b'rev1')
888
self.assertTrue(tree2.branch.repository.has_revision(b'rev1'))
891
class FilterExcludedTests(TestCase):
893
def test_add_file_not_excluded(self):
896
'fid', (None, 'newpath'),
897
0, (False, False), ('pid', 'pid'), ('newpath', 'newpath'),
898
('file', 'file'), (True, True))]
899
self.assertEqual(changes, list(
900
filter_excluded(changes, ['otherpath'])))
902
def test_add_file_excluded(self):
905
'fid', (None, 'newpath'),
906
0, (False, False), ('pid', 'pid'), ('newpath', 'newpath'),
907
('file', 'file'), (True, True))]
908
self.assertEqual([], list(filter_excluded(changes, ['newpath'])))
910
def test_delete_file_excluded(self):
913
'fid', ('somepath', None),
914
0, (False, None), ('pid', None), ('newpath', None),
915
('file', None), (True, None))]
916
self.assertEqual([], list(filter_excluded(changes, ['somepath'])))
918
def test_move_from_or_to_excluded(self):
921
'fid', ('oldpath', 'newpath'),
922
0, (False, False), ('pid', 'pid'), ('oldpath', 'newpath'),
923
('file', 'file'), (True, True))]
924
self.assertEqual([], list(filter_excluded(changes, ['oldpath'])))
925
self.assertEqual([], list(filter_excluded(changes, ['newpath'])))
833
tree2.commit('message', rev_id='rev1')
834
self.assertTrue(tree2.branch.repository.has_revision('rev1'))