35
from bzrlib.symbol_versioning import deprecated_in
36
from bzrlib.tests import test_win32utils
39
class _AttribFeature(tests.Feature):
42
if (sys.platform not in ('cygwin', 'win32')):
45
proc = subprocess.Popen(['attrib', '.'], stdout=subprocess.PIPE)
48
return (0 == proc.wait())
50
def feature_name(self):
51
return 'attrib Windows command-line tool'
53
AttribFeature = _AttribFeature()
56
compiled_patiencediff_feature = tests.ModuleAvailableFeature(
57
'bzrlib._patiencediff_c')
33
from ..sixish import (
40
from ..tests.blackbox.test_diff import subst_dates
41
from ..tests.scenarios import load_tests_apply_scenarios
44
load_tests = load_tests_apply_scenarios
60
47
def udiff_lines(old, new, allow_binary=False):
62
49
diff.internal_diff('old', old, 'new', new, output, allow_binary)
64
51
return output.readlines()
71
"""Simple file-like object that allows writes with any type and records."""
74
self.write_record = []
76
def write(self, data):
77
self.write_record.append(data)
79
def check_types(self, testcase, expected_type):
81
any(not isinstance(o, expected_type) for o in self.write_record),
82
"Not all writes of type %s: %r" % (
83
expected_type.__name__, self.write_record))
86
class TestDiffOptions(tests.TestCase):
88
def test_unified_added(self):
89
"""Check for default style '-u' only if no other style specified
92
# Verify that style defaults to unified, id est '-u' appended
93
# to option list, in the absence of an alternative style.
94
self.assertEqual(['-a', '-u'], diff.default_style_unified(['-a']))
97
class TestDiffOptionsScenarios(tests.TestCase):
99
scenarios = [(s, dict(style=s)) for s in diff.style_option_list]
100
style = None # Set by load_tests_apply_scenarios from scenarios
102
def test_unified_not_added(self):
103
# Verify that for all valid style options, '-u' is not
104
# appended to option list.
105
ret_opts = diff.default_style_unified(diff_opts=["%s" % (self.style,)])
106
self.assertEqual(["%s" % (self.style,)], ret_opts)
83
109
class TestDiff(tests.TestCase):
85
111
def test_add_nl(self):
86
112
"""diff generates a valid diff for patches that add a newline"""
87
113
lines = udiff_lines(['boo'], ['boo\n'])
88
114
self.check_patch(lines)
89
self.assertEquals(lines[4], '\\ No newline at end of file\n')
115
self.assertEqual(lines[4], '\\ No newline at end of file\n')
90
116
## "expected no-nl, got %r" % lines[4]
92
118
def test_add_nl_2(self):
105
131
lines = udiff_lines(['boo\n'], ['boo'])
106
132
self.check_patch(lines)
107
self.assertEquals(lines[5], '\\ No newline at end of file\n')
133
self.assertEqual(lines[5], '\\ No newline at end of file\n')
108
134
## "expected no-nl, got %r" % lines[5]
110
136
def check_patch(self, lines):
111
self.assert_(len(lines) > 1)
137
self.assertTrue(len(lines) > 1)
112
138
## "Not enough lines for a file header for patch:\n%s" % "".join(lines)
113
self.assert_(lines[0].startswith ('---'))
139
self.assertTrue(lines[0].startswith ('---'))
114
140
## 'No orig line for patch:\n%s' % "".join(lines)
115
self.assert_(lines[1].startswith ('+++'))
141
self.assertTrue(lines[1].startswith ('+++'))
116
142
## 'No mod line for patch:\n%s' % "".join(lines)
117
self.assert_(len(lines) > 2)
143
self.assertTrue(len(lines) > 2)
118
144
## "No hunks for patch:\n%s" % "".join(lines)
119
self.assert_(lines[2].startswith('@@'))
145
self.assertTrue(lines[2].startswith('@@'))
120
146
## "No hunk header for patch:\n%s" % "".join(lines)
121
self.assert_('@@' in lines[2][2:])
147
self.assertTrue('@@' in lines[2][2:])
122
148
## "Unterminated hunk header for patch:\n%s" % "".join(lines)
124
150
def test_binary_lines(self):
143
169
self.check_patch(lines)
145
171
def test_external_diff_binary_lang_c(self):
147
172
for lang in ('LANG', 'LC_ALL', 'LANGUAGE'):
148
old_env[lang] = osutils.set_or_unset_env(lang, 'C')
150
lines = external_udiff_lines(['\x00foobar\n'], ['foo\x00bar\n'])
151
# Older versions of diffutils say "Binary files", newer
152
# versions just say "Files".
153
self.assertContainsRe(lines[0],
154
'(Binary f|F)iles old and new differ\n')
155
self.assertEquals(lines[1:], ['\n'])
157
for lang, old_val in old_env.iteritems():
158
osutils.set_or_unset_env(lang, old_val)
173
self.overrideEnv(lang, 'C')
174
lines = external_udiff_lines(['\x00foobar\n'], ['foo\x00bar\n'])
175
# Older versions of diffutils say "Binary files", newer
176
# versions just say "Files".
177
self.assertContainsRe(lines[0], '(Binary f|F)iles old and new differ\n')
178
self.assertEqual(lines[1:], ['\n'])
160
180
def test_no_external_diff(self):
161
181
"""Check that NoDiff is raised when diff is not available"""
162
# Use os.environ['PATH'] to make sure no 'diff' command is available
163
orig_path = os.environ['PATH']
165
os.environ['PATH'] = ''
166
self.assertRaises(errors.NoDiff, diff.external_diff,
167
'old', ['boo\n'], 'new', ['goo\n'],
168
StringIO(), diff_opts=['-u'])
170
os.environ['PATH'] = orig_path
182
# Make sure no 'diff' command is available
183
# XXX: Weird, using None instead of '' breaks the test -- vila 20101216
184
self.overrideEnv('PATH', '')
185
self.assertRaises(errors.NoDiff, diff.external_diff,
186
'old', ['boo\n'], 'new', ['goo\n'],
187
BytesIO(), diff_opts=['-u'])
172
189
def test_internal_diff_default(self):
173
190
# Default internal diff encoding is utf8
175
192
diff.internal_diff(u'old_\xb5', ['old_text\n'],
176
193
u'new_\xe5', ['new_text\n'], output)
177
194
lines = output.getvalue().splitlines(True)
178
195
self.check_patch(lines)
179
self.assertEquals(['--- old_\xc2\xb5\n',
196
self.assertEqual(['--- old_\xc2\xb5\n',
180
197
'+++ new_\xc3\xa5\n',
181
198
'@@ -1,1 +1,1 @@\n',
220
237
def test_internal_diff_no_content(self):
222
239
diff.internal_diff(u'old', [], u'new', [], output)
223
240
self.assertEqual('', output.getvalue())
225
242
def test_internal_diff_no_changes(self):
227
244
diff.internal_diff(u'old', ['text\n', 'contents\n'],
228
245
u'new', ['text\n', 'contents\n'],
230
247
self.assertEqual('', output.getvalue())
232
249
def test_internal_diff_returns_bytes(self):
234
output = StringIO.StringIO()
235
251
diff.internal_diff(u'old_\xb5', ['old_text\n'],
236
252
u'new_\xe5', ['new_text\n'], output)
237
self.failUnless(isinstance(output.getvalue(), str),
238
'internal_diff should return bytestrings')
253
output.check_types(self, bytes)
255
def test_internal_diff_default_context(self):
257
diff.internal_diff('old', ['same_text\n','same_text\n','same_text\n',
258
'same_text\n','same_text\n','old_text\n'],
259
'new', ['same_text\n','same_text\n','same_text\n',
260
'same_text\n','same_text\n','new_text\n'], output)
261
lines = output.getvalue().splitlines(True)
262
self.check_patch(lines)
263
self.assertEqual(['--- old\n',
275
def test_internal_diff_no_context(self):
277
diff.internal_diff('old', ['same_text\n','same_text\n','same_text\n',
278
'same_text\n','same_text\n','old_text\n'],
279
'new', ['same_text\n','same_text\n','same_text\n',
280
'same_text\n','same_text\n','new_text\n'], output,
282
lines = output.getvalue().splitlines(True)
283
self.check_patch(lines)
284
self.assertEqual(['--- old\n',
293
def test_internal_diff_more_context(self):
295
diff.internal_diff('old', ['same_text\n','same_text\n','same_text\n',
296
'same_text\n','same_text\n','old_text\n'],
297
'new', ['same_text\n','same_text\n','same_text\n',
298
'same_text\n','same_text\n','new_text\n'], output,
300
lines = output.getvalue().splitlines(True)
301
self.check_patch(lines)
302
self.assertEqual(['--- old\n',
241
319
class TestDiffFiles(tests.TestCaseInTempDir):
243
321
def test_external_diff_binary(self):
244
322
"""The output when using external diff should use diff's i18n error"""
323
for lang in ('LANG', 'LC_ALL', 'LANGUAGE'):
324
self.overrideEnv(lang, 'C')
245
325
# Make sure external_diff doesn't fail in the current LANG
246
326
lines = external_udiff_lines(['\x00foobar\n'], ['foo\x00bar\n'])
248
328
cmd = ['diff', '-u', '--binary', 'old', 'new']
249
open('old', 'wb').write('\x00foobar\n')
250
open('new', 'wb').write('foo\x00bar\n')
329
with open('old', 'wb') as f: f.write('\x00foobar\n')
330
with open('new', 'wb') as f: f.write('foo\x00bar\n')
251
331
pipe = subprocess.Popen(cmd, stdout=subprocess.PIPE,
252
332
stdin=subprocess.PIPE)
253
333
out, err = pipe.communicate()
254
# Diff returns '2' on Binary files.
255
self.assertEqual(2, pipe.returncode)
256
334
# We should output whatever diff tells us, plus a trailing newline
257
335
self.assertEqual(out.splitlines(True) + ['\n'], lines)
260
class TestShowDiffTreesHelper(tests.TestCaseWithTransport):
261
"""Has a helper for running show_diff_trees"""
263
def get_diff(self, tree1, tree2, specific_files=None, working_tree=None):
265
if working_tree is not None:
266
extra_trees = (working_tree,)
269
diff.show_diff_trees(tree1, tree2, output,
270
specific_files=specific_files,
271
extra_trees=extra_trees, old_label='old/',
273
return output.getvalue()
276
class TestDiffDates(TestShowDiffTreesHelper):
338
def get_diff_as_string(tree1, tree2, specific_files=None, working_tree=None):
340
if working_tree is not None:
341
extra_trees = (working_tree,)
344
diff.show_diff_trees(tree1, tree2, output,
345
specific_files=specific_files,
346
extra_trees=extra_trees, old_label='old/',
348
return output.getvalue()
351
class TestDiffDates(tests.TestCaseWithTransport):
279
354
super(TestDiffDates, self).setUp()
394
469
self.wt.rename_one('file1', 'dir1/file1')
395
470
old_tree = self.b.repository.revision_tree('rev-1')
396
471
new_tree = self.b.repository.revision_tree('rev-4')
397
out = self.get_diff(old_tree, new_tree, specific_files=['dir1'],
472
out = get_diff_as_string(old_tree, new_tree, specific_files=['dir1'],
398
473
working_tree=self.wt)
399
474
self.assertContainsRe(out, 'file1\t')
400
out = self.get_diff(old_tree, new_tree, specific_files=['dir2'],
475
out = get_diff_as_string(old_tree, new_tree, specific_files=['dir2'],
401
476
working_tree=self.wt)
402
477
self.assertNotContainsRe(out, 'file1\t')
406
class TestShowDiffTrees(TestShowDiffTreesHelper):
480
class TestShowDiffTrees(tests.TestCaseWithTransport):
407
481
"""Direct tests for show_diff_trees"""
409
483
def test_modified_file(self):
508
582
tree.rename_one('c', 'new-c')
509
583
tree.rename_one('d', 'new-d')
511
d = self.get_diff(tree.basis_tree(), tree)
585
d = get_diff_as_string(tree.basis_tree(), tree)
513
587
self.assertContainsRe(d, r"file 'a'.*\(properties changed:"
515
589
self.assertContainsRe(d, r"file 'b'.*\(properties changed:"
517
591
self.assertContainsRe(d, r"file 'c'.*\(properties changed:"
519
593
self.assertContainsRe(d, r"file 'd'.*\(properties changed:"
521
595
self.assertNotContainsRe(d, r"file 'e'")
522
596
self.assertNotContainsRe(d, r"file 'f'")
525
598
def test_binary_unicode_filenames(self):
526
599
"""Test that contents of files are *not* encoded in UTF-8 when there
527
600
is a binary file in the diff.
529
602
# See https://bugs.launchpad.net/bugs/110092.
530
self.requireFeature(tests.UnicodeFilenameFeature)
603
self.requireFeature(features.UnicodeFilenameFeature)
532
# This bug isn't triggered with cStringIO.
533
from StringIO import StringIO
534
605
tree = self.make_branch_and_tree('tree')
535
606
alpha, omega = u'\u03b1', u'\u03c9'
536
607
alpha_utf8, omega_utf8 = alpha.encode('utf8'), omega.encode('utf8')
573
645
tree.add(['add_'+alpha], ['file-id'])
574
646
self.build_tree_contents([('tree/mod_'+alpha, 'contents_mod\n')])
576
d = self.get_diff(tree.basis_tree(), tree)
648
d = get_diff_as_string(tree.basis_tree(), tree)
577
649
self.assertContainsRe(d,
578
650
"=== renamed file 'ren_%s' => 'ren_%s'\n"%(autf8, outf8))
579
651
self.assertContainsRe(d, "=== added file 'add_%s'"%autf8)
580
652
self.assertContainsRe(d, "=== modified file 'mod_%s'"%autf8)
581
653
self.assertContainsRe(d, "=== removed file 'del_%s'"%autf8)
655
def test_unicode_filename_path_encoding(self):
656
"""Test for bug #382699: unicode filenames on Windows should be shown
659
self.requireFeature(features.UnicodeFilenameFeature)
660
# The word 'test' in Russian
661
_russian_test = u'\u0422\u0435\u0441\u0442'
662
directory = _russian_test + u'/'
663
test_txt = _russian_test + u'.txt'
664
u1234 = u'\u1234.txt'
666
tree = self.make_branch_and_tree('.')
667
self.build_tree_contents([
672
tree.add([test_txt, u1234, directory])
675
diff.show_diff_trees(tree.basis_tree(), tree, sio,
676
path_encoding='cp1251')
678
output = subst_dates(sio.getvalue())
680
=== added directory '%(directory)s'
681
=== added file '%(test_txt)s'
682
--- a/%(test_txt)s\tYYYY-MM-DD HH:MM:SS +ZZZZ
683
+++ b/%(test_txt)s\tYYYY-MM-DD HH:MM:SS +ZZZZ
687
=== added file '?.txt'
688
--- a/?.txt\tYYYY-MM-DD HH:MM:SS +ZZZZ
689
+++ b/?.txt\tYYYY-MM-DD HH:MM:SS +ZZZZ
693
''' % {'directory': _russian_test.encode('cp1251'),
694
'test_txt': test_txt.encode('cp1251'),
696
self.assertEqualDiff(output, shouldbe)
584
699
class DiffWasIs(diff.DiffPath):
644
759
self.new_tree.add('file', 'file-id')
645
760
os.unlink('old-tree/file')
646
761
self.differ.show_diff(None)
647
self.assertContainsRe(self.differ.to_file.getvalue(), '\+contents')
762
self.assertContainsRe(self.differ.to_file.getvalue(), r'\+contents')
649
764
def test_diff_symlink(self):
650
differ = diff.DiffSymlink(self.old_tree, self.new_tree, StringIO())
765
differ = diff.DiffSymlink(self.old_tree, self.new_tree, BytesIO())
651
766
differ.diff_symlink('old target', None)
652
767
self.assertEqual("=== target was 'old target'\n",
653
768
differ.to_file.getvalue())
655
differ = diff.DiffSymlink(self.old_tree, self.new_tree, StringIO())
770
differ = diff.DiffSymlink(self.old_tree, self.new_tree, BytesIO())
656
771
differ.diff_symlink(None, 'new target')
657
772
self.assertEqual("=== target is 'new target'\n",
658
773
differ.to_file.getvalue())
660
differ = diff.DiffSymlink(self.old_tree, self.new_tree, StringIO())
775
differ = diff.DiffSymlink(self.old_tree, self.new_tree, BytesIO())
661
776
differ.diff_symlink('old target', 'new target')
662
777
self.assertEqual("=== target changed 'old target' => 'new target'\n",
663
778
differ.to_file.getvalue())
717
832
diff.DiffTree.diff_factories=old_diff_factories[:]
718
833
diff.DiffTree.diff_factories.insert(0, DiffWasIs.from_diff_tree)
720
differ = diff.DiffTree(self.old_tree, self.new_tree, StringIO())
835
differ = diff.DiffTree(self.old_tree, self.new_tree, BytesIO())
722
837
diff.DiffTree.diff_factories = old_diff_factories
723
838
differ.diff('file-id', 'olddir/oldfile', 'newdir/newfile')
724
839
self.assertNotContainsRe(
725
840
differ.to_file.getvalue(),
726
841
r'--- olddir/oldfile.*\n\+\+\+ newdir/newfile.*\n\@\@ -1,1 \+1,1'
727
' \@\@\n-old\n\+new\n\n')
842
r' \@\@\n-old\n\+new\n\n')
728
843
self.assertContainsRe(differ.to_file.getvalue(),
729
844
'was: old\nis: new\n')
731
846
def test_extra_factories(self):
732
847
self.create_old_new()
733
differ = diff.DiffTree(self.old_tree, self.new_tree, StringIO(),
848
differ = diff.DiffTree(self.old_tree, self.new_tree, BytesIO(),
734
849
extra_factories=[DiffWasIs.from_diff_tree])
735
850
differ.diff('file-id', 'olddir/oldfile', 'newdir/newfile')
736
851
self.assertNotContainsRe(
737
852
differ.to_file.getvalue(),
738
853
r'--- olddir/oldfile.*\n\+\+\+ newdir/newfile.*\n\@\@ -1,1 \+1,1'
739
' \@\@\n-old\n\+new\n\n')
854
r' \@\@\n-old\n\+new\n\n')
740
855
self.assertContainsRe(differ.to_file.getvalue(),
741
856
'was: old\nis: new\n')
764
879
b = ''.join([unichr(i) for i in range(4300, 4800, 2)])
765
880
sm = self._PatienceSequenceMatcher(None, a, b)
766
881
mb = sm.get_matching_blocks()
767
self.assertEquals(35, len(mb))
882
self.assertEqual(35, len(mb))
769
884
def test_unique_lcs(self):
770
885
unique_lcs = self._unique_lcs
771
self.assertEquals(unique_lcs('', ''), [])
772
self.assertEquals(unique_lcs('', 'a'), [])
773
self.assertEquals(unique_lcs('a', ''), [])
774
self.assertEquals(unique_lcs('a', 'a'), [(0,0)])
775
self.assertEquals(unique_lcs('a', 'b'), [])
776
self.assertEquals(unique_lcs('ab', 'ab'), [(0,0), (1,1)])
777
self.assertEquals(unique_lcs('abcde', 'cdeab'), [(2,0), (3,1), (4,2)])
778
self.assertEquals(unique_lcs('cdeab', 'abcde'), [(0,2), (1,3), (2,4)])
779
self.assertEquals(unique_lcs('abXde', 'abYde'), [(0,0), (1,1),
886
self.assertEqual(unique_lcs('', ''), [])
887
self.assertEqual(unique_lcs('', 'a'), [])
888
self.assertEqual(unique_lcs('a', ''), [])
889
self.assertEqual(unique_lcs('a', 'a'), [(0,0)])
890
self.assertEqual(unique_lcs('a', 'b'), [])
891
self.assertEqual(unique_lcs('ab', 'ab'), [(0,0), (1,1)])
892
self.assertEqual(unique_lcs('abcde', 'cdeab'), [(2,0), (3,1), (4,2)])
893
self.assertEqual(unique_lcs('cdeab', 'abcde'), [(0,2), (1,3), (2,4)])
894
self.assertEqual(unique_lcs('abXde', 'abYde'), [(0,0), (1,1),
781
self.assertEquals(unique_lcs('acbac', 'abc'), [(2,1)])
896
self.assertEqual(unique_lcs('acbac', 'abc'), [(2,1)])
783
898
def test_recurse_matches(self):
784
899
def test_one(a, b, matches):
785
900
test_matches = []
786
901
self._recurse_matches(
787
902
a, b, 0, 0, len(a), len(b), test_matches, 10)
788
self.assertEquals(test_matches, matches)
903
self.assertEqual(test_matches, matches)
790
905
test_one(['a', '', 'b', '', 'c'], ['a', 'a', 'b', 'c', 'c'],
791
906
[(0, 0), (2, 2), (4, 4)])
1250
1364
class TestUsingCompiledIfAvailable(tests.TestCase):
1252
1366
def test_PatienceSequenceMatcher(self):
1253
if compiled_patiencediff_feature.available():
1254
from bzrlib._patiencediff_c import PatienceSequenceMatcher_c
1367
if features.compiled_patiencediff_feature.available():
1368
from breezy._patiencediff_c import PatienceSequenceMatcher_c
1255
1369
self.assertIs(PatienceSequenceMatcher_c,
1256
1370
patiencediff.PatienceSequenceMatcher)
1258
from bzrlib._patiencediff_py import PatienceSequenceMatcher_py
1372
from breezy._patiencediff_py import PatienceSequenceMatcher_py
1259
1373
self.assertIs(PatienceSequenceMatcher_py,
1260
1374
patiencediff.PatienceSequenceMatcher)
1262
1376
def test_unique_lcs(self):
1263
if compiled_patiencediff_feature.available():
1264
from bzrlib._patiencediff_c import unique_lcs_c
1377
if features.compiled_patiencediff_feature.available():
1378
from breezy._patiencediff_c import unique_lcs_c
1265
1379
self.assertIs(unique_lcs_c,
1266
1380
patiencediff.unique_lcs)
1268
from bzrlib._patiencediff_py import unique_lcs_py
1382
from breezy._patiencediff_py import unique_lcs_py
1269
1383
self.assertIs(unique_lcs_py,
1270
1384
patiencediff.unique_lcs)
1272
1386
def test_recurse_matches(self):
1273
if compiled_patiencediff_feature.available():
1274
from bzrlib._patiencediff_c import recurse_matches_c
1387
if features.compiled_patiencediff_feature.available():
1388
from breezy._patiencediff_c import recurse_matches_c
1275
1389
self.assertIs(recurse_matches_c,
1276
1390
patiencediff.recurse_matches)
1278
from bzrlib._patiencediff_py import recurse_matches_py
1392
from breezy._patiencediff_py import recurse_matches_py
1279
1393
self.assertIs(recurse_matches_py,
1280
1394
patiencediff.recurse_matches)
1391
1505
diff_obj._prepare_files('file2-id', 'oldname2', 'newname2')
1508
class TestDiffFromToolEncodedFilename(tests.TestCaseWithTransport):
1510
def test_encodable_filename(self):
1511
# Just checks file path for external diff tool.
1512
# We cannot change CPython's internal encoding used by os.exec*.
1513
diffobj = diff.DiffFromTool(['dummy', '@old_path', '@new_path'],
1515
for _, scenario in EncodingAdapter.encoding_scenarios:
1516
encoding = scenario['encoding']
1517
dirname = scenario['info']['directory']
1518
filename = scenario['info']['filename']
1520
self.overrideAttr(diffobj, '_fenc', lambda: encoding)
1521
relpath = dirname + u'/' + filename
1522
fullpath = diffobj._safe_filename('safe', relpath)
1523
self.assertEqual(fullpath,
1524
fullpath.encode(encoding).decode(encoding))
1525
self.assertTrue(fullpath.startswith(diffobj._root + '/safe'))
1527
def test_unencodable_filename(self):
1528
diffobj = diff.DiffFromTool(['dummy', '@old_path', '@new_path'],
1530
for _, scenario in EncodingAdapter.encoding_scenarios:
1531
encoding = scenario['encoding']
1532
dirname = scenario['info']['directory']
1533
filename = scenario['info']['filename']
1535
if encoding == 'iso-8859-1':
1536
encoding = 'iso-8859-2'
1538
encoding = 'iso-8859-1'
1540
self.overrideAttr(diffobj, '_fenc', lambda: encoding)
1541
relpath = dirname + u'/' + filename
1542
fullpath = diffobj._safe_filename('safe', relpath)
1543
self.assertEqual(fullpath,
1544
fullpath.encode(encoding).decode(encoding))
1545
self.assertTrue(fullpath.startswith(diffobj._root + '/safe'))
1394
1548
class TestGetTreesAndBranchesToDiffLocked(tests.TestCaseWithTransport):
1396
1550
def call_gtabtd(self, path_list, revision_specs, old_url, new_url):
1397
"""Call get_trees_and_branches_to_diff_locked. Overridden by
1398
TestGetTreesAndBranchesToDiff.
1551
"""Call get_trees_and_branches_to_diff_locked."""
1400
1552
return diff.get_trees_and_branches_to_diff_locked(
1401
1553
path_list, revision_specs, old_url, new_url, self.addCleanup)