1
# Copyright (C) 2006-2012, 2016 Canonical Ltd
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
# GNU General Public License for more details.
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
from io import BytesIO
21
revision as _mod_revision,
25
from ...diff import show_diff_trees
26
from ...merge import Merger, Merge3Merger
27
from ...transform import (
36
from breezy.tests.per_tree import TestCaseWithTree
39
from ..features import (
42
UnicodeFilenameFeature,
47
class TestTransformPreview(TestCaseWithTree):
50
super(TestTransformPreview, self).setUp()
51
if not self.workingtree_format.supports_setting_file_ids:
52
self.skipTest('test not compatible with non-file-id trees yet')
54
def create_tree(self):
55
tree = self.make_branch_and_tree('.')
56
self.build_tree_contents([('a', b'content 1')])
58
revid1 = tree.commit('rev1')
59
return tree.branch.repository.revision_tree(revid1)
61
def get_empty_preview(self):
62
repository = self.make_repository('repo')
63
tree = repository.revision_tree(_mod_revision.NULL_REVISION)
64
preview = tree.preview_transform()
65
self.addCleanup(preview.finalize)
68
def test_transform_preview(self):
69
revision_tree = self.create_tree()
70
preview = revision_tree.preview_transform()
71
self.addCleanup(preview.finalize)
73
def test_transform_preview_tree(self):
74
revision_tree = self.create_tree()
75
preview = revision_tree.preview_transform()
76
self.addCleanup(preview.finalize)
77
preview.get_preview_tree()
79
def test_transform_new_file(self):
80
revision_tree = self.create_tree()
81
preview = revision_tree.preview_transform()
82
self.addCleanup(preview.finalize)
83
preview.new_file('file2', preview.root, [b'content B\n'], b'file2-id')
84
preview_tree = preview.get_preview_tree()
85
self.assertEqual(preview_tree.kind('file2'), 'file')
86
with preview_tree.get_file('file2') as f:
87
self.assertEqual(f.read(), b'content B\n')
89
def test_diff_preview_tree(self):
90
revision_tree = self.create_tree()
91
preview = revision_tree.preview_transform()
92
self.addCleanup(preview.finalize)
93
preview.new_file('file2', preview.root, [b'content B\n'], b'file2-id')
94
preview_tree = preview.get_preview_tree()
96
show_diff_trees(revision_tree, preview_tree, out)
97
lines = out.getvalue().splitlines()
98
self.assertEqual(lines[0], b"=== added file 'file2'")
99
# 3 lines of diff administrivia
100
self.assertEqual(lines[4], b"+content B")
102
def test_unsupported_symlink_diff(self):
103
self.requireFeature(SymlinkFeature)
104
tree = self.make_branch_and_tree('.')
105
self.build_tree_contents([('a', 'content 1')])
107
os.symlink('a', 'foo')
109
revid1 = tree.commit('rev1')
110
revision_tree = tree.branch.repository.revision_tree(revid1)
111
preview = revision_tree.preview_transform()
112
self.addCleanup(preview.finalize)
113
preview.delete_versioned(preview.trans_id_tree_path('foo'))
114
preview_tree = preview.get_preview_tree()
117
trace.push_log_file(log)
118
os_symlink = getattr(os, 'symlink', None)
121
show_diff_trees(revision_tree, preview_tree, out)
122
lines = out.getvalue().splitlines()
124
os.symlink = os_symlink
125
self.assertContainsRe(
127
b'Ignoring "foo" as symlinks are not supported on this filesystem')
129
def test_transform_conflicts(self):
130
revision_tree = self.create_tree()
131
preview = revision_tree.preview_transform()
132
self.addCleanup(preview.finalize)
133
preview.new_file('a', preview.root, [b'content 2'])
134
resolve_conflicts(preview)
135
trans_id = preview.trans_id_tree_path('a')
136
self.assertEqual('a.moved', preview.final_name(trans_id))
138
def get_tree_and_preview_tree(self):
139
revision_tree = self.create_tree()
140
preview = revision_tree.preview_transform()
141
self.addCleanup(preview.finalize)
142
a_trans_id = preview.trans_id_tree_path('a')
143
preview.delete_contents(a_trans_id)
144
preview.create_file([b'b content'], a_trans_id)
145
preview_tree = preview.get_preview_tree()
146
return revision_tree, preview_tree
148
def test_iter_changes(self):
149
revision_tree, preview_tree = self.get_tree_and_preview_tree()
150
root = revision_tree.path2id('')
151
self.assertEqual([(revision_tree.path2id('a'), ('a', 'a'), True, (True, True),
152
(root, root), ('a', 'a'), ('file', 'file'),
153
(False, False), False)],
154
list(preview_tree.iter_changes(revision_tree)))
156
def test_include_unchanged_succeeds(self):
157
revision_tree, preview_tree = self.get_tree_and_preview_tree()
158
changes = preview_tree.iter_changes(revision_tree,
159
include_unchanged=True)
161
root_id = revision_tree.path2id('')
162
root_entry = (root_id, ('', ''), False, (True, True), (None, None),
163
('', ''), ('directory', 'directory'), (False, False), False)
164
a_entry = (revision_tree.path2id('a'), ('a', 'a'), True, (True, True),
165
(root_id, root_id), ('a', 'a'), ('file', 'file'),
166
(False, False), False)
169
self.assertEqual([root_entry, a_entry], list(changes))
171
def test_specific_files(self):
172
revision_tree, preview_tree = self.get_tree_and_preview_tree()
173
changes = preview_tree.iter_changes(revision_tree,
175
root_id = revision_tree.path2id('')
176
a_entry = (revision_tree.path2id('a'), ('a', 'a'), True, (True, True),
177
(root_id, root_id), ('a', 'a'), ('file', 'file'),
178
(False, False), False)
181
self.assertEqual([a_entry], list(changes))
183
def test_want_unversioned(self):
184
revision_tree, preview_tree = self.get_tree_and_preview_tree()
185
changes = preview_tree.iter_changes(revision_tree,
186
want_unversioned=True)
187
root_id = revision_tree.path2id('')
188
a_entry = (revision_tree.path2id('a'), ('a', 'a'), True, (True, True),
189
(root_id, root_id), ('a', 'a'), ('file', 'file'),
190
(False, False), False)
192
self.assertEqual([a_entry], list(changes))
194
def test_ignore_extra_trees_no_specific_files(self):
195
# extra_trees is harmless without specific_files, so we'll silently
196
# accept it, even though we won't use it.
197
revision_tree, preview_tree = self.get_tree_and_preview_tree()
198
preview_tree.iter_changes(revision_tree, extra_trees=[preview_tree])
200
def test_ignore_require_versioned_no_specific_files(self):
201
# require_versioned is meaningless without specific_files.
202
revision_tree, preview_tree = self.get_tree_and_preview_tree()
203
preview_tree.iter_changes(revision_tree, require_versioned=False)
205
def test_ignore_pb(self):
206
# pb could be supported, but TT.iter_changes doesn't support it.
207
revision_tree, preview_tree = self.get_tree_and_preview_tree()
208
preview_tree.iter_changes(revision_tree)
211
revision_tree = self.create_tree()
212
preview = revision_tree.preview_transform()
213
self.addCleanup(preview.finalize)
214
preview.new_file('file', preview.root, [b'contents'], b'file-id')
215
preview.new_directory('directory', preview.root, b'dir-id')
216
preview_tree = preview.get_preview_tree()
217
self.assertEqual('file', preview_tree.kind('file'))
218
self.assertEqual('directory', preview_tree.kind('directory'))
220
def test_get_file_mtime(self):
221
preview = self.get_empty_preview()
222
file_trans_id = preview.new_file('file', preview.root, [b'contents'],
224
limbo_path = preview._limbo_name(file_trans_id)
225
preview_tree = preview.get_preview_tree()
226
self.assertEqual(os.stat(limbo_path).st_mtime,
227
preview_tree.get_file_mtime('file'))
229
def test_get_file_mtime_renamed(self):
230
work_tree = self.make_branch_and_tree('tree')
231
self.build_tree(['tree/file'])
232
work_tree.add('file')
233
preview = work_tree.preview_transform()
234
self.addCleanup(preview.finalize)
235
file_trans_id = preview.trans_id_tree_path('file')
236
preview.adjust_path('renamed', preview.root, file_trans_id)
237
preview_tree = preview.get_preview_tree()
238
preview_mtime = preview_tree.get_file_mtime('renamed')
239
work_mtime = work_tree.get_file_mtime('file')
241
def test_get_file_size(self):
242
work_tree = self.make_branch_and_tree('tree')
243
self.build_tree_contents([('tree/old', b'old')])
245
preview = work_tree.preview_transform()
246
self.addCleanup(preview.finalize)
247
preview.new_file('name', preview.root, [b'contents'], b'new-id',
249
tree = preview.get_preview_tree()
250
self.assertEqual(len('old'), tree.get_file_size('old'))
251
self.assertEqual(len('contents'), tree.get_file_size('name'))
253
def test_get_file(self):
254
preview = self.get_empty_preview()
255
preview.new_file('file', preview.root, [b'contents'], b'file-id')
256
preview_tree = preview.get_preview_tree()
257
with preview_tree.get_file('file') as tree_file:
258
self.assertEqual(b'contents', tree_file.read())
260
def test_get_symlink_target(self):
261
self.requireFeature(SymlinkFeature)
262
preview = self.get_empty_preview()
263
preview.new_symlink('symlink', preview.root, 'target', b'symlink-id')
264
preview_tree = preview.get_preview_tree()
265
self.assertEqual('target',
266
preview_tree.get_symlink_target('symlink'))
268
def test_all_file_ids(self):
269
if not self.workingtree_format.supports_setting_file_ids:
270
raise tests.TestNotApplicable(
271
'format does not support setting file ids')
272
tree = self.make_branch_and_tree('tree')
273
self.build_tree(['tree/a', 'tree/b', 'tree/c'])
274
tree.add(['a', 'b', 'c'], [b'a-id', b'b-id', b'c-id'])
275
preview = tree.preview_transform()
276
self.addCleanup(preview.finalize)
277
preview.unversion_file(preview.trans_id_file_id(b'b-id'))
278
c_trans_id = preview.trans_id_file_id(b'c-id')
279
preview.unversion_file(c_trans_id)
280
preview.version_file(c_trans_id, file_id=b'c-id')
281
preview_tree = preview.get_preview_tree()
282
self.assertEqual({b'a-id', b'c-id', tree.path2id('')},
283
preview_tree.all_file_ids())
285
def test_path2id_deleted_unchanged(self):
286
tree = self.make_branch_and_tree('tree')
287
self.build_tree(['tree/unchanged', 'tree/deleted'])
288
tree.add(['unchanged', 'deleted'])
289
preview = tree.preview_transform()
290
self.addCleanup(preview.finalize)
291
preview.unversion_file(preview.trans_id_tree_path('deleted'))
292
preview_tree = preview.get_preview_tree()
295
find_previous_path(preview_tree, tree, 'unchanged'))
296
self.assertFalse(preview_tree.is_versioned('deleted'))
298
def test_path2id_created(self):
299
tree = self.make_branch_and_tree('tree')
300
self.build_tree(['tree/unchanged'])
301
tree.add(['unchanged'])
302
preview = tree.preview_transform()
303
self.addCleanup(preview.finalize)
304
preview.new_file('new', preview.trans_id_tree_path('unchanged'),
305
[b'contents'], b'new-id')
306
preview_tree = preview.get_preview_tree()
307
self.assertEqual(b'new-id', preview_tree.path2id('unchanged/new'))
309
def test_path2id_moved(self):
310
tree = self.make_branch_and_tree('tree')
311
self.build_tree(['tree/old_parent/', 'tree/old_parent/child'])
312
tree.add(['old_parent', 'old_parent/child'])
313
preview = tree.preview_transform()
314
self.addCleanup(preview.finalize)
315
new_parent = preview.new_directory('new_parent', preview.root,
317
preview.adjust_path('child', new_parent,
318
preview.trans_id_tree_path('old_parent/child'))
319
preview_tree = preview.get_preview_tree()
320
self.assertFalse(preview_tree.is_versioned('old_parent/child'))
323
find_previous_path(tree, preview_tree, 'old_parent/child'))
324
if self.workingtree_format.supports_setting_file_ids:
326
tree.path2id('old_parent/child'),
327
preview_tree.path2id('new_parent/child'))
329
def test_path2id_renamed_parent(self):
330
tree = self.make_branch_and_tree('tree')
331
self.build_tree(['tree/old_name/', 'tree/old_name/child'])
332
tree.add(['old_name', 'old_name/child'])
333
preview = tree.preview_transform()
334
self.addCleanup(preview.finalize)
335
preview.adjust_path('new_name', preview.root,
336
preview.trans_id_tree_path('old_name'))
337
preview_tree = preview.get_preview_tree()
338
self.assertFalse(preview_tree.is_versioned('old_name/child'))
341
find_previous_path(tree, preview_tree, 'old_name/child'))
342
if tree.supports_setting_file_ids:
344
tree.path2id('old_name/child'),
345
preview_tree.path2id('new_name/child'))
347
def assertMatchingIterEntries(self, tt, specific_files=None):
348
preview_tree = tt.get_preview_tree()
349
preview_result = list(preview_tree.iter_entries_by_dir(
350
specific_files=specific_files))
353
actual_result = list(tree.iter_entries_by_dir(
354
specific_files=specific_files))
355
self.assertEqual(actual_result, preview_result)
357
def test_iter_entries_by_dir_new(self):
358
tree = self.make_branch_and_tree('tree')
359
tt = tree.transform()
360
tt.new_file('new', tt.root, [b'contents'], b'new-id')
361
self.assertMatchingIterEntries(tt)
363
def test_iter_entries_by_dir_deleted(self):
364
tree = self.make_branch_and_tree('tree')
365
self.build_tree(['tree/deleted'])
367
tt = tree.transform()
368
tt.delete_contents(tt.trans_id_tree_path('deleted'))
369
self.assertMatchingIterEntries(tt)
371
def test_iter_entries_by_dir_unversioned(self):
372
tree = self.make_branch_and_tree('tree')
373
self.build_tree(['tree/removed'])
375
tt = tree.transform()
376
tt.unversion_file(tt.trans_id_tree_path('removed'))
377
self.assertMatchingIterEntries(tt)
379
def test_iter_entries_by_dir_moved(self):
380
tree = self.make_branch_and_tree('tree')
381
self.build_tree(['tree/moved', 'tree/new_parent/'])
382
tree.add(['moved', 'new_parent'])
383
tt = tree.transform()
385
'moved', tt.trans_id_tree_path('new_parent'),
386
tt.trans_id_tree_path('moved'))
387
self.assertMatchingIterEntries(tt)
389
def test_iter_entries_by_dir_specific_files(self):
390
tree = self.make_branch_and_tree('tree')
391
self.build_tree(['tree/parent/', 'tree/parent/child'])
392
tree.add(['parent', 'parent/child'])
393
tt = tree.transform()
394
self.assertMatchingIterEntries(tt, ['', 'parent/child'])
396
def test_symlink_content_summary(self):
397
self.requireFeature(SymlinkFeature)
398
preview = self.get_empty_preview()
399
preview.new_symlink('path', preview.root, 'target', b'path-id')
400
summary = preview.get_preview_tree().path_content_summary('path')
401
self.assertEqual(('symlink', None, None, 'target'), summary)
403
def test_missing_content_summary(self):
404
preview = self.get_empty_preview()
405
summary = preview.get_preview_tree().path_content_summary('path')
406
self.assertEqual(('missing', None, None, None), summary)
408
def test_deleted_content_summary(self):
409
tree = self.make_branch_and_tree('tree')
410
self.build_tree(['tree/path/'])
412
preview = tree.preview_transform()
413
self.addCleanup(preview.finalize)
414
preview.delete_contents(preview.trans_id_tree_path('path'))
415
summary = preview.get_preview_tree().path_content_summary('path')
416
self.assertEqual(('missing', None, None, None), summary)
418
def test_file_content_summary_executable(self):
419
preview = self.get_empty_preview()
420
path_id = preview.new_file('path', preview.root, [
421
b'contents'], b'path-id')
422
preview.set_executability(True, path_id)
423
summary = preview.get_preview_tree().path_content_summary('path')
424
self.assertEqual(4, len(summary))
425
self.assertEqual('file', summary[0])
427
self.assertEqual(len('contents'), summary[1])
429
self.assertEqual(True, summary[2])
430
# will not have hash (not cheap to determine)
431
self.assertIs(None, summary[3])
433
def test_change_executability(self):
434
tree = self.make_branch_and_tree('tree')
435
self.build_tree(['tree/path'])
437
preview = tree.preview_transform()
438
self.addCleanup(preview.finalize)
439
path_id = preview.trans_id_tree_path('path')
440
preview.set_executability(True, path_id)
441
summary = preview.get_preview_tree().path_content_summary('path')
442
self.assertEqual(True, summary[2])
444
def test_file_content_summary_non_exec(self):
445
preview = self.get_empty_preview()
446
preview.new_file('path', preview.root, [b'contents'], b'path-id')
447
summary = preview.get_preview_tree().path_content_summary('path')
448
self.assertEqual(4, len(summary))
449
self.assertEqual('file', summary[0])
451
self.assertEqual(len('contents'), summary[1])
453
self.assertEqual(False, summary[2])
454
# will not have hash (not cheap to determine)
455
self.assertIs(None, summary[3])
457
def test_dir_content_summary(self):
458
preview = self.get_empty_preview()
459
preview.new_directory('path', preview.root, b'path-id')
460
summary = preview.get_preview_tree().path_content_summary('path')
461
self.assertEqual(('directory', None, None, None), summary)
463
def test_tree_content_summary(self):
464
preview = self.get_empty_preview()
465
path = preview.new_directory('path', preview.root, b'path-id')
466
preview.set_tree_reference(b'rev-1', path)
467
summary = preview.get_preview_tree().path_content_summary('path')
468
self.assertEqual(4, len(summary))
469
self.assertEqual('tree-reference', summary[0])
471
def test_annotate(self):
472
tree = self.make_branch_and_tree('tree')
473
self.build_tree_contents([('tree/file', b'a\n')])
475
revid1 = tree.commit('a')
476
self.build_tree_contents([('tree/file', b'a\nb\n')])
477
preview = tree.preview_transform()
478
self.addCleanup(preview.finalize)
479
file_trans_id = preview.trans_id_tree_path('file')
480
preview.delete_contents(file_trans_id)
481
preview.create_file([b'a\nb\nc\n'], file_trans_id)
482
preview_tree = preview.get_preview_tree()
488
annotation = preview_tree.annotate_iter(
489
'file', default_revision=b'me:')
490
self.assertEqual(expected, annotation)
492
def test_annotate_missing(self):
493
preview = self.get_empty_preview()
494
preview.new_file('file', preview.root, [b'a\nb\nc\n'], b'file-id')
495
preview_tree = preview.get_preview_tree()
501
annotation = preview_tree.annotate_iter(
502
'file', default_revision=b'me:')
503
self.assertEqual(expected, annotation)
505
def test_annotate_rename(self):
506
tree = self.make_branch_and_tree('tree')
507
self.build_tree_contents([('tree/file', b'a\n')])
509
revid1 = tree.commit('a')
510
preview = tree.preview_transform()
511
self.addCleanup(preview.finalize)
512
file_trans_id = preview.trans_id_tree_path('file')
513
preview.adjust_path('newname', preview.root, file_trans_id)
514
preview_tree = preview.get_preview_tree()
518
annotation = preview_tree.annotate_iter(
519
'file', default_revision=b'me:')
520
self.assertEqual(expected, annotation)
522
def test_annotate_deleted(self):
523
tree = self.make_branch_and_tree('tree')
524
self.build_tree_contents([('tree/file', b'a\n')])
527
self.build_tree_contents([('tree/file', b'a\nb\n')])
528
preview = tree.preview_transform()
529
self.addCleanup(preview.finalize)
530
file_trans_id = preview.trans_id_tree_path('file')
531
preview.delete_contents(file_trans_id)
532
preview_tree = preview.get_preview_tree()
533
annotation = preview_tree.annotate_iter(
534
'file', default_revision=b'me:')
535
self.assertIs(None, annotation)
537
def test_stored_kind(self):
538
preview = self.get_empty_preview()
539
preview.new_file('file', preview.root, [b'a\nb\nc\n'], b'file-id')
540
preview_tree = preview.get_preview_tree()
541
self.assertEqual('file', preview_tree.stored_kind('file'))
543
def test_is_executable(self):
544
preview = self.get_empty_preview()
545
preview.new_file('file', preview.root, [b'a\nb\nc\n'], b'file-id')
546
preview.set_executability(True, preview.trans_id_file_id(b'file-id'))
547
preview_tree = preview.get_preview_tree()
548
self.assertEqual(True, preview_tree.is_executable('file'))
550
def test_get_set_parent_ids(self):
551
revision_tree, preview_tree = self.get_tree_and_preview_tree()
552
self.assertEqual([], preview_tree.get_parent_ids())
553
preview_tree.set_parent_ids([revision_tree.get_revision_id()])
555
[revision_tree.get_revision_id()],
556
preview_tree.get_parent_ids())
558
def test_plan_file_merge(self):
559
work_a = self.make_branch_and_tree('wta')
560
self.build_tree_contents([('wta/file', b'a\nb\nc\nd\n')])
562
base_id = work_a.commit('base version')
563
tree_b = work_a.controldir.sprout('wtb').open_workingtree()
564
preview = work_a.preview_transform()
565
self.addCleanup(preview.finalize)
566
trans_id = preview.trans_id_tree_path('file')
567
preview.delete_contents(trans_id)
568
preview.create_file([b'b\nc\nd\ne\n'], trans_id)
569
self.build_tree_contents([('wtb/file', b'a\nc\nd\nf\n')])
570
tree_a = preview.get_preview_tree()
571
tree_a.set_parent_ids([base_id])
572
self.addCleanup(tree_b.lock_read().unlock)
574
('killed-a', b'a\n'),
575
('killed-b', b'b\n'),
576
('unchanged', b'c\n'),
577
('unchanged', b'd\n'),
580
], list(tree_a.plan_file_merge('file', tree_b)))
582
def test_plan_file_merge_revision_tree(self):
583
work_a = self.make_branch_and_tree('wta')
584
self.build_tree_contents([('wta/file', b'a\nb\nc\nd\n')])
586
base_id = work_a.commit('base version')
587
tree_b = work_a.controldir.sprout('wtb').open_workingtree()
588
preview = work_a.basis_tree().preview_transform()
589
self.addCleanup(preview.finalize)
590
trans_id = preview.trans_id_tree_path('file')
591
preview.delete_contents(trans_id)
592
preview.create_file([b'b\nc\nd\ne\n'], trans_id)
593
self.build_tree_contents([('wtb/file', b'a\nc\nd\nf\n')])
594
tree_a = preview.get_preview_tree()
595
tree_a.set_parent_ids([base_id])
596
self.addCleanup(tree_b.lock_read().unlock)
598
('killed-a', b'a\n'),
599
('killed-b', b'b\n'),
600
('unchanged', b'c\n'),
601
('unchanged', b'd\n'),
604
], list(tree_a.plan_file_merge('file', tree_b)))
606
def test_walkdirs(self):
607
preview = self.get_empty_preview()
608
preview.new_directory('', ROOT_PARENT, b'tree-root')
609
# FIXME: new_directory should mark root.
610
preview.fixup_new_roots()
611
preview_tree = preview.get_preview_tree()
612
preview.new_file('a', preview.root, [b'contents'], b'a-id')
613
expected = [(('', b'tree-root'),
614
[('a', 'a', 'file', None, b'a-id', 'file')])]
615
self.assertEqual(expected, list(preview_tree.walkdirs()))
617
def test_extras(self):
618
work_tree = self.make_branch_and_tree('tree')
619
self.build_tree(['tree/removed-file', 'tree/existing-file',
620
'tree/not-removed-file'])
621
work_tree.add(['removed-file', 'not-removed-file'])
622
preview = work_tree.preview_transform()
623
self.addCleanup(preview.finalize)
624
preview.new_file('new-file', preview.root, [b'contents'])
625
preview.new_file('new-versioned-file', preview.root, [b'contents'],
627
tree = preview.get_preview_tree()
628
preview.unversion_file(preview.trans_id_tree_path('removed-file'))
629
self.assertEqual({'new-file', 'removed-file', 'existing-file'},
632
def test_merge_into_preview(self):
633
work_tree = self.make_branch_and_tree('tree')
634
self.build_tree_contents([('tree/file', b'b\n')])
635
work_tree.add('file')
636
work_tree.commit('first commit')
637
child_tree = work_tree.controldir.sprout('child').open_workingtree()
638
self.build_tree_contents([('child/file', b'b\nc\n')])
639
child_tree.commit('child commit')
640
child_tree.lock_write()
641
self.addCleanup(child_tree.unlock)
642
work_tree.lock_write()
643
self.addCleanup(work_tree.unlock)
644
preview = work_tree.preview_transform()
645
self.addCleanup(preview.finalize)
646
file_trans_id = preview.trans_id_tree_path('file')
647
preview.delete_contents(file_trans_id)
648
preview.create_file([b'a\nb\n'], file_trans_id)
649
preview_tree = preview.get_preview_tree()
650
merger = Merger.from_revision_ids(preview_tree,
651
child_tree.branch.last_revision(),
652
other_branch=child_tree.branch,
653
tree_branch=work_tree.branch)
654
merger.merge_type = Merge3Merger
655
tt = merger.make_merger().make_preview_transform()
656
self.addCleanup(tt.finalize)
657
final_tree = tt.get_preview_tree()
660
final_tree.get_file_text('file'))
662
def test_merge_preview_into_workingtree(self):
663
tree = self.make_branch_and_tree('tree')
664
if tree.supports_setting_file_ids():
665
tree.set_root_id(b'TREE_ROOT')
666
tt = tree.preview_transform()
667
self.addCleanup(tt.finalize)
668
tt.new_file('name', tt.root, [b'content'], b'file-id')
669
tree2 = self.make_branch_and_tree('tree2')
670
if tree.supports_setting_file_ids():
671
tree2.set_root_id(b'TREE_ROOT')
672
merger = Merger.from_uncommitted(tree2, tt.get_preview_tree(),
674
merger.merge_type = Merge3Merger
677
def test_merge_preview_into_workingtree_handles_conflicts(self):
678
tree = self.make_branch_and_tree('tree')
679
self.build_tree_contents([('tree/foo', b'bar')])
682
tt = tree.preview_transform()
683
self.addCleanup(tt.finalize)
684
trans_id = tt.trans_id_tree_path('foo')
685
tt.delete_contents(trans_id)
686
tt.create_file([b'baz'], trans_id)
687
tree2 = tree.controldir.sprout('tree2').open_workingtree()
688
self.build_tree_contents([('tree2/foo', b'qux')])
689
merger = Merger.from_uncommitted(tree2, tt.get_preview_tree(),
691
merger.merge_type = Merge3Merger
694
def test_has_filename(self):
695
wt = self.make_branch_and_tree('tree')
696
self.build_tree(['tree/unmodified', 'tree/removed', 'tree/modified'])
697
tt = wt.preview_transform()
698
removed_id = tt.trans_id_tree_path('removed')
699
tt.delete_contents(removed_id)
700
tt.new_file('new', tt.root, [b'contents'])
701
modified_id = tt.trans_id_tree_path('modified')
702
tt.delete_contents(modified_id)
703
tt.create_file([b'modified-contents'], modified_id)
704
self.addCleanup(tt.finalize)
705
tree = tt.get_preview_tree()
706
self.assertTrue(tree.has_filename('unmodified'))
707
self.assertFalse(tree.has_filename('not-present'))
708
self.assertFalse(tree.has_filename('removed'))
709
self.assertTrue(tree.has_filename('new'))
710
self.assertTrue(tree.has_filename('modified'))
712
def test_is_executable2(self):
713
tree = self.make_branch_and_tree('tree')
714
preview = tree.preview_transform()
715
self.addCleanup(preview.finalize)
716
preview.new_file('foo', preview.root, [b'bar'], b'baz-id')
717
preview_tree = preview.get_preview_tree()
718
self.assertEqual(False, preview_tree.is_executable('tree/foo'))
720
def test_commit_preview_tree(self):
721
tree = self.make_branch_and_tree('tree')
722
rev_id = tree.commit('rev1')
723
tree.branch.lock_write()
724
self.addCleanup(tree.branch.unlock)
725
tt = tree.preview_transform()
726
tt.new_file('file', tt.root, [b'contents'], b'file_id')
727
self.addCleanup(tt.finalize)
728
preview = tt.get_preview_tree()
729
preview.set_parent_ids([rev_id])
730
builder = tree.branch.get_commit_builder([rev_id])
731
list(builder.record_iter_changes(preview, rev_id, tt.iter_changes()))
732
builder.finish_inventory()
733
rev2_id = builder.commit('rev2')
734
rev2_tree = tree.branch.repository.revision_tree(rev2_id)
735
self.assertEqual(b'contents', rev2_tree.get_file_text('file'))
737
def test_ascii_limbo_paths(self):
738
self.requireFeature(UnicodeFilenameFeature)
739
branch = self.make_branch('any')
740
tree = branch.repository.revision_tree(_mod_revision.NULL_REVISION)
741
tt = tree.preview_transform()
742
self.addCleanup(tt.finalize)
743
foo_id = tt.new_directory('', ROOT_PARENT)
744
bar_id = tt.new_file(u'\u1234bar', foo_id, [b'contents'])
745
limbo_path = tt._limbo_name(bar_id)
746
self.assertEqual(limbo_path, limbo_path)