Merge 0.4.
[jelmer/subvertpy.git] / tests / test_fetch.py
1 # Copyright (C) 2007 Jelmer Vernooij <jelmer@samba.org>
2 # *-* coding: utf-8 *-*
3
4 # This program is free software; you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation; either version 3 of the License, or
7 # (at your option) any later version.
8
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 # GNU General Public License for more details.
13
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
18 """Subversion fetch tests."""
19
20 import shutil
21 from bzrlib.branch import Branch
22 from bzrlib.bzrdir import BzrDir
23 from bzrlib.osutils import has_symlinks
24 from bzrlib.repository import Repository
25 from bzrlib.revision import NULL_REVISION
26 from bzrlib.tests import TestSkipped, KnownFailure
27 from bzrlib.trace import mutter
28
29 from bzrlib.plugins.svn import format, remote
30 from bzrlib.plugins.svn.convert import load_dumpfile
31 from bzrlib.plugins.svn.errors import InvalidFileName
32 from bzrlib.plugins.svn.mapping3 import set_branching_scheme
33 from bzrlib.plugins.svn.mapping3.scheme import TrunkBranchingScheme, NoBranchingScheme
34 from bzrlib.plugins.svn.tests import TestCaseWithSubversionRepository
35 from bzrlib.plugins.svn.transport import SvnRaTransport
36
37 import os, sys
38
39 class TestFetchWorks(TestCaseWithSubversionRepository):
40     def test_fetch_fileid_renames(self):
41         repos_url = self.make_repository('d')
42
43         dc = self.commit_editor(repos_url)
44         dc.add_file("test", "data")
45         dc.change_dir_prop("", "bzr:file-ids", "test\tbla\n")
46         dc.change_dir_prop("", "bzr:revision-info", "")
47         dc.done()
48
49         oldrepos = Repository.open(repos_url)
50         dir = BzrDir.create("f", format.get_rich_root_format())
51         newrepos = dir.create_repository()
52         oldrepos.copy_content_into(newrepos)
53         mapping = oldrepos.get_mapping()
54         self.assertEqual("bla", newrepos.get_inventory(
55             oldrepos.generate_revision_id(1, "", mapping)).path2id("test"))
56
57     def test_fetch_trunk1(self):
58         repos_url = self.make_repository('d')
59
60         dc = self.commit_editor(repos_url)
61         dc.add_dir("proj1")
62         dc.add_dir("proj1/trunk")
63         dc.add_file("proj1/trunk/file", "data")
64         dc.done()
65
66         oldrepos = Repository.open(repos_url)
67         set_branching_scheme(oldrepos, TrunkBranchingScheme(1))
68         dir = BzrDir.create("f", format.get_rich_root_format())
69         newrepos = dir.create_repository()
70         oldrepos.copy_content_into(newrepos)
71
72     def test_replace_from_branch(self):
73         repos_url = self.make_repository('d')
74
75         dc = self.commit_editor(repos_url)
76         dc.add_dir("trunk")
77         dc.add_dir("trunk/check")
78         dc.add_dir("trunk/check/debian")
79         dc.add_file("trunk/check/stamp-h.in", "foo")
80         dc.add_dir("tags")
81         dc.done()
82
83         dc = self.commit_editor(repos_url)
84         dc.add_file("trunk/check/debian/pl", "bar")
85         dc.done()
86
87         dc = self.commit_editor(repos_url)
88         dc.add_file("trunk/check/debian/voo", "bar")
89         dc.done()
90
91         dc = self.commit_editor(repos_url)
92         dc.add_file("trunk/check/debian/blie", "oeh")
93         dc.done()
94
95         dc = self.commit_editor(repos_url)
96         dc.add_file("trunk/check/debian/bar", "oeh")
97         dc.add_file("trunk/check/bar", "bla")
98         dc.done()
99
100         self.make_checkout(repos_url, "dc")
101
102         self.client_copy("dc/trunk", "dc/tags/R_0_9_2", revnum=2)
103         self.client_delete("dc/tags/R_0_9_2/check/debian")
104         shutil.rmtree("dc/tags/R_0_9_2/check/debian")
105         self.client_copy("dc/trunk/check/debian", "dc/tags/R_0_9_2/check", 
106                          revnum=5)
107         self.client_delete("dc/tags/R_0_9_2/check/stamp-h.in")
108         self.client_copy("dc/trunk/check/stamp-h.in", "dc/tags/R_0_9_2/check", 
109                          revnum=4)
110         self.build_tree({"dc/tags/R_0_9_2/check/debian/blie": "oehha"})
111         self.client_update("dc")
112         self.client_commit("dc", "strange revision")
113         oldrepos = Repository.open(repos_url)
114         set_branching_scheme(oldrepos, TrunkBranchingScheme(0))
115         dir = BzrDir.create("f", format.get_rich_root_format())
116         newrepos = dir.create_repository()
117         oldrepos.copy_content_into(newrepos)
118
119     def test_fetch_backslash(self):
120         if sys.platform == 'win32':
121             raise TestSkipped("Unable to create filenames with backslash on Windows")
122         repos_url = self.make_repository('d')
123
124         dc = self.commit_editor(repos_url)
125         dc.add_dir("trunk")
126         dc.add_file("trunk/file\\part", "data")
127         dc.done()
128
129         oldrepos = Repository.open(repos_url)
130         set_branching_scheme(oldrepos, TrunkBranchingScheme())
131         dir = BzrDir.create("f", format.get_rich_root_format())
132         newrepos = dir.create_repository()
133         self.assertRaises(InvalidFileName, oldrepos.copy_content_into, newrepos)
134
135     def test_fetch_null(self):
136         repos_url = self.make_repository('d')
137         oldrepos = Repository.open(repos_url)
138         set_branching_scheme(oldrepos, TrunkBranchingScheme(1))
139         dir = BzrDir.create("f", format.get_rich_root_format())
140         newrepos = dir.create_repository()
141         oldrepos.copy_content_into(newrepos, NULL_REVISION)
142
143     def test_fetch_complex_ids_dirs(self):
144         repos_url = self.make_repository('d')
145
146         dc = self.commit_editor(repos_url)
147         dc.add_dir("dir")
148         dc.add_dir("dir/adir")
149         dc.change_dir_prop("", "bzr:revision-info", "")
150         dc.change_dir_prop("", "bzr:file-ids", "dir\tbloe\ndir/adir\tbla\n")
151         dc.done()
152
153         dc = self.commit_editor(repos_url)
154         dc.add_dir("bdir", "dir/adir")
155         dc.delete("dir/adir")
156         dc.change_dir_prop("", "bzr:revision-info", "properties: \n")
157         dc.change_dir_prop("", "bzr:file-ids", "bdir\tbla\n")
158         dc.done()
159
160         oldrepos = Repository.open(repos_url)
161         dir = BzrDir.create("f", format.get_rich_root_format())
162         newrepos = dir.create_repository()
163         oldrepos.copy_content_into(newrepos)
164         mapping = oldrepos.get_mapping()
165         tree = newrepos.revision_tree(oldrepos.generate_revision_id(2, "", mapping))
166         self.assertEquals("bloe", tree.path2id("dir"))
167         self.assertIs(None, tree.path2id("dir/adir"))
168         self.assertEquals("bla", tree.path2id("bdir"))
169
170     def test_fetch_complex_ids_files(self):
171         repos_url = self.make_client('d', 'dc')
172         self.build_tree({'dc/dir/adir': 'contents'})
173         self.client_add("dc/dir")
174         self.client_set_prop("dc", "bzr:revision-info", "")
175         self.client_set_prop("dc", "bzr:file-ids", "dir\tbloe\ndir/adir\tbla\n")
176         self.client_commit("dc", "My Message")
177         self.client_update("dc")
178         self.client_copy("dc/dir/adir", "dc/bdir")
179         self.client_delete("dc/dir/adir")
180         self.client_set_prop("dc", "bzr:revision-info", "properties: \n")
181         self.client_set_prop("dc", "bzr:file-ids", "bdir\tbla\n")
182         self.client_commit("dc", "My Message")
183         self.client_update("dc")
184         oldrepos = Repository.open(repos_url)
185         dir = BzrDir.create("f", format.get_rich_root_format())
186         newrepos = dir.create_repository()
187         oldrepos.copy_content_into(newrepos)
188         mapping = oldrepos.get_mapping()
189         tree = newrepos.revision_tree(oldrepos.generate_revision_id(2, "", mapping))
190         self.assertEquals("bloe", tree.path2id("dir"))
191         self.assertIs(None, tree.path2id("dir/adir"))
192         mutter('entries: %r' % tree.inventory.entries())
193         self.assertEquals("bla", tree.path2id("bdir"))
194
195     def test_fetch_copy_remove_old(self):
196         repos_url = self.make_client('d', 'dc')
197         self.build_tree({'dc/trunk/afile': 'foo', 'dc/tags': None, 
198                          'dc/branches': None})
199         self.client_add("dc/trunk")
200         self.client_add("dc/tags")
201         self.client_add("dc/branches")
202         self.client_commit("dc", "My Message")
203         self.client_update("dc")
204         self.client_copy("dc/trunk", "dc/branches/blal")
205         self.build_tree({'dc/branches/blal/afile': "bar"})
206         self.client_commit("dc", "Msg")
207         self.client_update("dc")
208         self.client_copy("dc/trunk", "dc/tags/bla")
209         self.client_delete("dc/tags/bla/afile")
210         self.client_copy("dc/branches/blal/afile", "dc/tags/bla/afile")
211         self.client_commit("dc", "My Message")
212         self.client_update("dc")
213         oldrepos = Repository.open(repos_url)
214         dir = BzrDir.create("f", format.get_rich_root_format())
215         newrepos = dir.create_repository()
216         oldrepos.copy_content_into(newrepos)
217
218     def test_fetch_special_char(self):
219         repos_url = self.make_repository('d')
220
221         dc = self.commit_editor(repos_url)
222         dc.add_dir("trunk")
223         dc.add_file(u"trunk/f\x2cle".encode("utf-8"), "data")
224         dc.done()
225
226         oldrepos = Repository.open(repos_url)
227         set_branching_scheme(oldrepos, TrunkBranchingScheme(0))
228         dir = BzrDir.create("f", format.get_rich_root_format())
229         newrepos = dir.create_repository()
230         oldrepos.copy_content_into(newrepos)
231
232     def test_fetch_signature(self):
233         repos_url = self.make_repository('d')
234         dc = self.commit_editor(repos_url)
235         dc.add_dir("trunk")
236         dc.add_file("trunk/bar", "data")
237         dc.done()
238
239         self.client_set_revprop(repos_url, 1, "bzr:gpg-signature", "SIGNATURE")
240         oldrepos = Repository.open(repos_url)
241         set_branching_scheme(oldrepos, TrunkBranchingScheme(0))
242         dir = BzrDir.create("f", format.get_rich_root_format())
243         newrepos = dir.create_repository()
244         oldrepos.copy_content_into(newrepos)
245         self.assertEquals("SIGNATURE", newrepos.get_signature_text(oldrepos.generate_revision_id(1, "trunk", oldrepos.get_mapping())))
246
247     def test_fetch_special_char_edit(self):
248         repos_url = self.make_repository('d')
249         
250         dc = self.commit_editor(repos_url)
251         dc.add_dir("trunk")
252         dc.add_dir(u'trunk/IöC'.encode("utf-8"))
253         dc.done()
254
255         dc = self.commit_editor(repos_url)
256         dc.add_file(u'trunk/IöC/bar'.encode("utf-8"), "more data")
257         dc.done()
258
259         oldrepos = Repository.open(repos_url)
260         set_branching_scheme(oldrepos, TrunkBranchingScheme(0))
261         dir = BzrDir.create("f", format.get_rich_root_format())
262         newrepos = dir.create_repository()
263         oldrepos.copy_content_into(newrepos)
264
265     def test_fetch_special_char_child(self):
266         repos_url = self.make_repository('d')
267         
268         dc = self.commit_editor(repos_url)
269         dc.add_dir("trunk")
270         dc.add_dir(u"trunk/é".encode("utf-8"))
271         dc.add_file(u'trunk/é/f\x2cle'.encode("utf-8"), "data")
272         dc.done()
273         oldrepos = Repository.open(repos_url)
274         set_branching_scheme(oldrepos, TrunkBranchingScheme(0))
275         dir = BzrDir.create("f", format.get_rich_root_format())
276         newrepos = dir.create_repository()
277         oldrepos.copy_content_into(newrepos)
278
279     def test_fetch_special_char_modify(self):
280         repos_url = self.make_repository('d')
281
282         dc = self.commit_editor(repos_url)
283         dc.add_dir("trunk")
284         dc.add_file(u"trunk/€\x2c".encode("utf-8"), "data")
285         dc.done()
286
287         dc = self.commit_editor(repos_url)
288         dc.change_file(u"trunk/€\x2c".encode("utf-8"), "bar")
289         revno = dc.done()
290
291         oldrepos = Repository.open(repos_url)
292         set_branching_scheme(oldrepos, TrunkBranchingScheme(0))
293         dir = BzrDir.create("f", format.get_rich_root_format())
294         newrepos = dir.create_repository()
295         oldrepos.copy_content_into(newrepos)
296         self.assertEquals(2, revno)
297
298     def test_fetch_delete(self):
299         repos_url = self.make_client('d', 'dc')
300         self.build_tree({'dc/foo/bla': "data"})
301         self.client_add("dc/foo")
302         self.client_commit("dc", "My Message")
303         oldrepos = Repository.open(repos_url)
304         dir = BzrDir.create("f", format.get_rich_root_format())
305         newrepos = dir.create_repository()
306         oldrepos.copy_content_into(newrepos)
307         self.client_delete("dc/foo/bla")
308         self.client_commit("dc", "Second Message")
309         newrepos = Repository.open("f")
310         oldrepos.copy_content_into(newrepos)
311         mapping = oldrepos.get_mapping()
312         self.assertTrue(oldrepos.has_revision(oldrepos.generate_revision_id(2, "", mapping)))
313
314     def test_fetch_delete_recursive(self):
315         repos_url = self.make_client('d', 'dc')
316         self.build_tree({'dc/foo/bla': "data"})
317         self.client_add("dc/foo")
318         self.client_commit("dc", "My Message")
319         self.client_delete("dc/foo")
320         self.client_commit("dc", "Second Message")
321         oldrepos = Repository.open(repos_url)
322         dir = BzrDir.create("f", format.get_rich_root_format())
323         newrepos = dir.create_repository()
324         oldrepos.copy_content_into(newrepos)
325         mapping = oldrepos.get_mapping()
326         tree = newrepos.revision_tree(oldrepos.generate_revision_id(1, "", mapping))
327         self.assertEquals(3, len(tree.inventory))
328         tree = newrepos.revision_tree(oldrepos.generate_revision_id(2, "", mapping))
329         self.assertEquals(1, len(tree.inventory))
330
331     def test_fetch_local(self):
332         repos_url = self.make_client('d', 'dc')
333         self.build_tree({'dc/foo/bla': "data"})
334         self.client_add("dc/foo")
335         self.client_commit("dc", "My Message")
336         self.build_tree({'dc/foo/blo': "data2", "dc/bar/foo": "data3", 'dc/foo/bla': "data"})
337         self.client_add("dc/foo/blo")
338         self.client_add("dc/bar")
339         self.client_commit("dc", "Second Message")
340         oldrepos = Repository.open(repos_url)
341         dir = BzrDir.create("f", format.get_rich_root_format())
342         newrepos = dir.create_repository()
343         oldrepos.copy_content_into(newrepos)
344         mapping = oldrepos.get_mapping()
345         self.assertTrue(newrepos.has_revision(
346             oldrepos.generate_revision_id(1, "", mapping)))
347         self.assertTrue(newrepos.has_revision(
348             oldrepos.generate_revision_id(2, "", mapping)))
349         newrepos.lock_read()
350         try:
351             tree = newrepos.revision_tree(
352                     oldrepos.generate_revision_id(2, "", mapping))
353             self.assertTrue(tree.has_filename("foo/bla"))
354             self.assertTrue(tree.has_filename("foo"))
355             self.assertEqual("data", tree.get_file_by_path("foo/bla").read())
356         finally:
357             newrepos.unlock()
358
359     def test_fetch_replace(self):
360         repos_url = self.make_client('d', 'dc')
361         self.build_tree({'dc/bla': "data"})
362         self.client_add("dc/bla")
363         self.client_commit("dc", "My Message")
364         self.client_delete("dc/bla")
365         self.build_tree({'dc/bla': "data2"})
366         self.client_add("dc/bla")
367         self.client_commit("dc", "Second Message")
368         oldrepos = Repository.open("svn+"+repos_url)
369         dir = BzrDir.create("f", format.get_rich_root_format())
370         newrepos = dir.create_repository()
371         oldrepos.copy_content_into(newrepos)
372         mapping = oldrepos.get_mapping()
373         self.assertTrue(newrepos.has_revision(
374             oldrepos.generate_revision_id(1, "", mapping)))
375         self.assertTrue(newrepos.has_revision(
376             oldrepos.generate_revision_id(2, "", mapping)))
377         inv1 = newrepos.get_inventory(
378                 oldrepos.generate_revision_id(1, "", mapping))
379         inv2 = newrepos.get_inventory(
380                 oldrepos.generate_revision_id(2, "", mapping))
381         self.assertNotEqual(inv1.path2id("bla"), inv2.path2id("bla"))
382
383     def test_fetch_copy_subdir(self):
384         repos_url = self.make_client('d', 'dc')
385         self.build_tree({'dc/trunk/mydir/a': "data"})
386         self.client_add("dc/trunk")
387         self.client_commit("dc", "My Message")
388         self.build_tree({'dc/branches/tmp': None})
389         self.client_add("dc/branches")
390         self.client_commit("dc", "Second Message")
391         self.client_copy("dc/trunk/mydir", "dc/branches/tmp/abranch")
392         self.client_commit("dc", "Third Message")
393         oldrepos = Repository.open("svn+"+repos_url)
394         set_branching_scheme(oldrepos, TrunkBranchingScheme())
395         dir = BzrDir.create("f", format.get_rich_root_format())
396         newrepos = dir.create_repository()
397         oldrepos.copy_content_into(newrepos)
398
399     def test_fetch_replace_nordic(self):
400         filename = os.path.join(self.test_dir, "dumpfile")
401         open(filename, 'w').write("""SVN-fs-dump-format-version: 2
402
403 UUID: 606c7b1f-987c-4826-b37d-eb556ceb87e1
404
405 Revision-number: 0
406 Prop-content-length: 56
407 Content-length: 56
408
409 K 8
410 svn:date
411 V 27
412 2006-12-26T00:04:55.850520Z
413 PROPS-END
414
415 Revision-number: 1
416 Prop-content-length: 103
417 Content-length: 103
418
419 K 7
420 svn:log
421 V 3
422 add
423 K 10
424 svn:author
425 V 6
426 jelmer
427 K 8
428 svn:date
429 V 27
430 2006-12-26T00:05:15.504335Z
431 PROPS-END
432
433 Node-path: x\xc3\xa1
434 Node-kind: dir
435 Node-action: add
436 Prop-content-length: 10
437 Content-length: 10
438
439 PROPS-END
440
441 Node-path: u\xc3\xa1
442 Node-path: bla
443 Node-kind: file
444 Node-action: add
445 Prop-content-length: 10
446 Text-content-length: 5
447 Text-content-md5: 49803c8f7913948eb3e30bae749ae6bd
448 Content-length: 15
449
450 PROPS-END
451 bloe
452
453
454 Revision-number: 2
455 Prop-content-length: 105
456 Content-length: 105
457
458 K 7
459 svn:log
460 V 5
461 readd
462 K 10
463 svn:author
464 V 6
465 jelmer
466 K 8
467 svn:date
468 V 27
469 2006-12-26T00:05:43.584249Z
470 PROPS-END
471
472 Node-path: x\xc3\xa1
473 Node-action: delete
474
475 """)
476         os.mkdir("old")
477
478         load_dumpfile("dumpfile", "old")
479         oldrepos = Repository.open("old")
480         dir = BzrDir.create("f", format.get_rich_root_format())
481         newrepos = dir.create_repository()
482         oldrepos.copy_content_into(newrepos)
483         mapping = oldrepos.get_mapping()
484         self.assertTrue(newrepos.has_revision(
485             oldrepos.generate_revision_id(1, "", mapping)))
486         inv1 = newrepos.get_inventory(
487                 oldrepos.generate_revision_id(1, "", mapping))
488         self.assertTrue(inv1.has_filename(u"x\xe1"))
489
490     def test_fetch_replace_with_subreplace(self):
491         filename = os.path.join(self.test_dir, "dumpfile")
492         open(filename, 'w').write("""SVN-fs-dump-format-version: 2
493
494 UUID: 606c7b1f-987c-4826-b37d-eb456ceb87e1
495
496 Revision-number: 0
497 Prop-content-length: 56
498 Content-length: 56
499
500 K 8
501 svn:date
502 V 27
503 2006-12-26T00:04:55.850520Z
504 PROPS-END
505
506 Revision-number: 1
507 Prop-content-length: 103
508 Content-length: 103
509
510 K 7
511 svn:log
512 V 3
513 add
514 K 10
515 svn:author
516 V 6
517 jelmer
518 K 8
519 svn:date
520 V 27
521 2006-12-26T00:05:15.504335Z
522 PROPS-END
523
524 Node-path: x
525 Node-kind: dir
526 Node-action: add
527 Prop-content-length: 10
528 Content-length: 10
529
530 PROPS-END
531
532 Node-path: x/t
533 Node-kind: dir
534 Node-action: add
535 Prop-content-length: 10
536 Content-length: 10
537
538 PROPS-END
539
540 Node-path: u
541 Node-kind: dir
542 Node-action: add
543 Prop-content-length: 10
544 Content-length: 10
545
546 PROPS-END
547
548 Revision-number: 2
549 Prop-content-length: 105
550 Content-length: 105
551
552 K 7
553 svn:log
554 V 5
555 readd
556 K 10
557 svn:author
558 V 6
559 jelmer
560 K 8
561 svn:date
562 V 27
563 2006-12-26T00:05:43.584249Z
564 PROPS-END
565
566 Node-path: x
567 Node-action: delete
568
569 Node-path: x
570 Node-kind: dir
571 Node-action: add
572 Prop-content-length: 10
573 Content-length: 10
574
575 PROPS-END
576
577
578 Revision-number: 3
579 Prop-content-length: 108
580 Content-length: 108
581
582 K 7
583 svn:log
584 V 8
585 Replace
586
587 K 10
588 svn:author
589 V 6
590 jelmer
591 K 8
592 svn:date
593 V 27
594 2006-12-25T04:30:06.383777Z
595 PROPS-END
596
597 Node-path: x
598 Node-action: delete
599
600 Node-path: y
601 Node-kind: dir
602 Node-action: add
603 Node-copyfrom-rev: 1
604 Node-copyfrom-path: x
605
606 Node-path: y/t
607 Node-action: delete
608
609 Node-path: y/t
610 Node-kind: dir
611 Node-action: add
612 Node-copyfrom-rev: 1
613 Node-copyfrom-path: u
614
615
616 """)
617         os.mkdir("old")
618
619         load_dumpfile("dumpfile", "old")
620         oldrepos = Repository.open("old")
621         dir = BzrDir.create("f", format.get_rich_root_format())
622         newrepos = dir.create_repository()
623         oldrepos.copy_content_into(newrepos)
624         mapping = oldrepos.get_mapping()
625         self.assertTrue(newrepos.has_revision(
626             oldrepos.generate_revision_id(1, "", mapping)))
627         self.assertTrue(newrepos.has_revision(
628             oldrepos.generate_revision_id(3, "", mapping)))
629         inv1 = newrepos.get_inventory(
630                 oldrepos.generate_revision_id(1, "", mapping))
631         inv2 = newrepos.get_inventory(
632                 oldrepos.generate_revision_id(3, "", mapping))
633
634     def test_fetch_replace_self(self):
635         filename = os.path.join(self.test_dir, "dumpfile")
636         open(filename, 'w').write("""SVN-fs-dump-format-version: 2
637
638 UUID: 6dcc86fc-ac21-4df7-a3a3-87616123c853
639
640 Revision-number: 0
641 Prop-content-length: 56
642 Content-length: 56
643
644 K 8
645 svn:date
646 V 27
647 2006-12-25T04:27:54.633666Z
648 PROPS-END
649
650 Revision-number: 1
651 Prop-content-length: 108
652 Content-length: 108
653
654 K 7
655 svn:log
656 V 8
657 Add dir
658
659 K 10
660 svn:author
661 V 6
662 jelmer
663 K 8
664 svn:date
665 V 27
666 2006-12-25T04:28:17.503039Z
667 PROPS-END
668
669 Node-path: bla
670 Node-kind: dir
671 Node-action: add
672 Prop-content-length: 10
673 Content-length: 10
674
675 PROPS-END
676
677
678 Revision-number: 2
679 Prop-content-length: 117
680 Content-length: 117
681
682 K 7
683 svn:log
684 V 16
685 Add another dir
686
687 K 10
688 svn:author
689 V 6
690 jelmer
691 K 8
692 svn:date
693 V 27
694 2006-12-25T04:28:30.160663Z
695 PROPS-END
696
697 Node-path: blie
698 Node-kind: dir
699 Node-action: add
700 Prop-content-length: 10
701 Content-length: 10
702
703 PROPS-END
704
705
706 Revision-number: 3
707 Prop-content-length: 105
708 Content-length: 105
709
710 K 7
711 svn:log
712 V 5
713 Copy
714
715 K 10
716 svn:author
717 V 6
718 jelmer
719 K 8
720 svn:date
721 V 27
722 2006-12-25T04:28:44.996894Z
723 PROPS-END
724
725 Node-path: bloe
726 Node-kind: dir
727 Node-action: add
728 Node-copyfrom-rev: 1
729 Node-copyfrom-path: bla
730
731
732 Revision-number: 4
733 Prop-content-length: 108
734 Content-length: 108
735
736 K 7
737 svn:log
738 V 8
739 Replace
740
741 K 10
742 svn:author
743 V 6
744 jelmer
745 K 8
746 svn:date
747 V 27
748 2006-12-25T04:30:06.383777Z
749 PROPS-END
750
751 Node-path: bla
752 Node-action: delete
753
754
755 Node-path: bla
756 Node-kind: dir
757 Node-action: add
758 Node-copyfrom-rev: 2
759 Node-copyfrom-path: bla
760
761
762 """)
763         os.mkdir("old")
764
765         load_dumpfile("dumpfile", "old")
766         oldrepos = Repository.open("old")
767         dir = BzrDir.create("f", format.get_rich_root_format())
768         newrepos = dir.create_repository()
769         oldrepos.copy_content_into(newrepos)
770         mapping = oldrepos.get_mapping()
771         self.assertTrue(newrepos.has_revision(
772             oldrepos.generate_revision_id(1, "", mapping)))
773         self.assertTrue(newrepos.has_revision(
774             oldrepos.generate_revision_id(3, "", mapping)))
775         inv1 = newrepos.get_inventory(
776                 oldrepos.generate_revision_id(1, "", mapping))
777         inv2 = newrepos.get_inventory(
778                 oldrepos.generate_revision_id(3, "", mapping))
779         self.assertEqual(inv1.path2id("bla"), inv2.path2id("bla"))
780
781     def test_fetch_replace_backup(self):
782         filename = os.path.join(self.test_dir, "dumpfile")
783         open(filename, 'w').write("""SVN-fs-dump-format-version: 2
784
785 UUID: 6dcc86fc-ac21-4df7-a3a3-87616123c853
786
787 Revision-number: 0
788 Prop-content-length: 56
789 Content-length: 56
790
791 K 8
792 svn:date
793 V 27
794 2006-12-25T04:27:54.633666Z
795 PROPS-END
796
797 Revision-number: 1
798 Prop-content-length: 108
799 Content-length: 108
800
801 K 7
802 svn:log
803 V 8
804 Add dir
805
806 K 10
807 svn:author
808 V 6
809 jelmer
810 K 8
811 svn:date
812 V 27
813 2006-12-25T04:28:17.503039Z
814 PROPS-END
815
816 Node-path: bla
817 Node-kind: dir
818 Node-action: add
819 Prop-content-length: 10
820 Content-length: 10
821
822 PROPS-END
823
824
825 Revision-number: 2
826 Prop-content-length: 117
827 Content-length: 117
828
829 K 7
830 svn:log
831 V 16
832 Add another dir
833
834 K 10
835 svn:author
836 V 6
837 jelmer
838 K 8
839 svn:date
840 V 27
841 2006-12-25T04:28:30.160663Z
842 PROPS-END
843
844 Node-path: blie
845 Node-kind: dir
846 Node-action: add
847 Prop-content-length: 10
848 Content-length: 10
849
850 PROPS-END
851
852
853 Revision-number: 3
854 Prop-content-length: 105
855 Content-length: 105
856
857 K 7
858 svn:log
859 V 5
860 Copy
861
862 K 10
863 svn:author
864 V 6
865 jelmer
866 K 8
867 svn:date
868 V 27
869 2006-12-25T04:28:44.996894Z
870 PROPS-END
871
872 Node-path: bloe
873 Node-kind: dir
874 Node-action: add
875 Node-copyfrom-rev: 1
876 Node-copyfrom-path: bla
877
878
879 Revision-number: 4
880 Prop-content-length: 112
881 Content-length: 112
882
883 K 7
884 svn:log
885 V 11
886 Change bla
887
888 K 10
889 svn:author
890 V 6
891 jelmer
892 K 8
893 svn:date
894 V 27
895 2006-12-25T23:51:09.678679Z
896 PROPS-END
897
898 Node-path: bla
899 Node-kind: dir
900 Node-action: change
901 Prop-content-length: 28
902 Content-length: 28
903
904 K 3
905 foo
906 V 5
907 bloe
908
909 PROPS-END
910
911
912 Revision-number: 5
913 Prop-content-length: 108
914 Content-length: 108
915
916 K 7
917 svn:log
918 V 8
919 Replace
920
921 K 10
922 svn:author
923 V 6
924 jelmer
925 K 8
926 svn:date
927 V 27
928 2006-12-25T04:30:06.383777Z
929 PROPS-END
930
931 Node-path: bla
932 Node-action: delete
933
934
935 Node-path: bla
936 Node-kind: dir
937 Node-action: add
938 Node-copyfrom-rev: 1
939 Node-copyfrom-path: bla
940
941
942 """)
943         os.mkdir("old")
944
945         load_dumpfile("dumpfile", "old")
946         oldrepos = Repository.open("old")
947         dir = BzrDir.create("f", format.get_rich_root_format())
948         newrepos = dir.create_repository()
949         oldrepos.copy_content_into(newrepos)
950         mapping = oldrepos.get_mapping()
951         self.assertTrue(newrepos.has_revision(
952             oldrepos.generate_revision_id(1, "", mapping)))
953         self.assertTrue(newrepos.has_revision(
954             oldrepos.generate_revision_id(3, "", mapping)))
955         inv1 = newrepos.get_inventory(
956                 oldrepos.generate_revision_id(1, "", mapping))
957         inv2 = newrepos.get_inventory(
958                 oldrepos.generate_revision_id(3, "", mapping))
959         self.assertEqual(inv1.path2id("bla"), inv2.path2id("bla"))
960
961     def test_fetch_replace_unrelated(self):
962         filename = os.path.join(self.test_dir, "dumpfile")
963         open(filename, 'w').write("""SVN-fs-dump-format-version: 2
964
965 UUID: 606c7b1f-987c-4826-b37d-eb456ceb87e1
966
967 Revision-number: 0
968 Prop-content-length: 56
969 Content-length: 56
970
971 K 8
972 svn:date
973 V 27
974 2006-12-26T00:04:55.850520Z
975 PROPS-END
976
977 Revision-number: 1
978 Prop-content-length: 103
979 Content-length: 103
980
981 K 7
982 svn:log
983 V 3
984 add
985 K 10
986 svn:author
987 V 6
988 jelmer
989 K 8
990 svn:date
991 V 27
992 2006-12-26T00:05:15.504335Z
993 PROPS-END
994
995 Node-path: x
996 Node-kind: dir
997 Node-action: add
998 Prop-content-length: 10
999 Content-length: 10
1000
1001 PROPS-END
1002
1003
1004 Revision-number: 2
1005 Prop-content-length: 102
1006 Content-length: 102
1007
1008 K 7
1009 svn:log
1010 V 2
1011 rm
1012 K 10
1013 svn:author
1014 V 6
1015 jelmer
1016 K 8
1017 svn:date
1018 V 27
1019 2006-12-26T00:05:30.775369Z
1020 PROPS-END
1021
1022 Node-path: x
1023 Node-action: delete
1024
1025
1026 Revision-number: 3
1027 Prop-content-length: 105
1028 Content-length: 105
1029
1030 K 7
1031 svn:log
1032 V 5
1033 readd
1034 K 10
1035 svn:author
1036 V 6
1037 jelmer
1038 K 8
1039 svn:date
1040 V 27
1041 2006-12-26T00:05:43.584249Z
1042 PROPS-END
1043
1044 Node-path: x
1045 Node-kind: dir
1046 Node-action: add
1047 Prop-content-length: 10
1048 Content-length: 10
1049
1050 PROPS-END
1051
1052
1053 Revision-number: 4
1054 Prop-content-length: 108
1055 Content-length: 108
1056
1057 K 7
1058 svn:log
1059 V 8
1060 Replace
1061
1062 K 10
1063 svn:author
1064 V 6
1065 jelmer
1066 K 8
1067 svn:date
1068 V 27
1069 2006-12-25T04:30:06.383777Z
1070 PROPS-END
1071
1072 Node-path: x
1073 Node-action: delete
1074
1075
1076 Node-path: x
1077 Node-kind: dir
1078 Node-action: add
1079 Node-copyfrom-rev: 1
1080 Node-copyfrom-path: x
1081
1082                 
1083 """)
1084         os.mkdir("old")
1085
1086         load_dumpfile("dumpfile", "old")
1087         oldrepos = Repository.open("old")
1088         dir = BzrDir.create("f", format.get_rich_root_format())
1089         newrepos = dir.create_repository()
1090         oldrepos.copy_content_into(newrepos)
1091         mapping = oldrepos.get_mapping()
1092         self.assertTrue(newrepos.has_revision(
1093             oldrepos.generate_revision_id(1, "", mapping)))
1094         self.assertTrue(newrepos.has_revision(
1095             oldrepos.generate_revision_id(4, "", mapping)))
1096         inv1 = newrepos.get_inventory(
1097                 oldrepos.generate_revision_id(1, "", mapping))
1098         inv2 = newrepos.get_inventory(
1099                 oldrepos.generate_revision_id(4, "", mapping))
1100         self.assertNotEqual(inv1.path2id("x"), inv2.path2id("x"))
1101
1102     def test_fetch_replace_related(self):
1103         filename = os.path.join(self.test_dir, "dumpfile")
1104         open(filename, 'w').write("""SVN-fs-dump-format-version: 2
1105
1106 UUID: 606c7b1f-987c-4826-b37d-eb456ceb87e1
1107
1108 Revision-number: 0
1109 Prop-content-length: 56
1110 Content-length: 56
1111
1112 K 8
1113 svn:date
1114 V 27
1115 2006-12-26T00:04:55.850520Z
1116 PROPS-END
1117
1118 Revision-number: 1
1119 Prop-content-length: 103
1120 Content-length: 103
1121
1122 K 7
1123 svn:log
1124 V 3
1125 add
1126 K 10
1127 svn:author
1128 V 6
1129 jelmer
1130 K 8
1131 svn:date
1132 V 27
1133 2006-12-26T00:05:15.504335Z
1134 PROPS-END
1135
1136 Node-path: x
1137 Node-kind: dir
1138 Node-action: add
1139 Prop-content-length: 10
1140 Content-length: 10
1141
1142 PROPS-END
1143
1144
1145 Revision-number: 2
1146 Prop-content-length: 102
1147 Content-length: 102
1148
1149 K 7
1150 svn:log
1151 V 2
1152 rm
1153 K 10
1154 svn:author
1155 V 6
1156 jelmer
1157 K 8
1158 svn:date
1159 V 27
1160 2006-12-26T00:05:30.775369Z
1161 PROPS-END
1162
1163 Node-path: x
1164 Node-action: delete
1165
1166
1167 Revision-number: 3
1168 Prop-content-length: 105
1169 Content-length: 105
1170
1171 K 7
1172 svn:log
1173 V 5
1174 readd
1175 K 10
1176 svn:author
1177 V 6
1178 jelmer
1179 K 8
1180 svn:date
1181 V 27
1182 2006-12-26T00:05:43.584249Z
1183 PROPS-END
1184
1185 Node-path: y
1186 Node-kind: dir
1187 Node-action: add
1188 Node-copyfrom-rev: 1
1189 Node-copyfrom-path: x
1190 Prop-content-length: 10
1191 Content-length: 10
1192
1193 PROPS-END
1194
1195
1196 Revision-number: 4
1197 Prop-content-length: 108
1198 Content-length: 108
1199
1200 K 7
1201 svn:log
1202 V 8
1203 Replace
1204
1205 K 10
1206 svn:author
1207 V 6
1208 jelmer
1209 K 8
1210 svn:date
1211 V 27
1212 2006-12-25T04:30:06.383777Z
1213 PROPS-END
1214
1215 Node-path: y
1216 Node-action: delete
1217
1218
1219 Revision-number: 5
1220 Prop-content-length: 108
1221 Content-length: 108
1222
1223 K 7
1224 svn:log
1225 V 8
1226 Replace
1227
1228 K 10
1229 svn:author
1230 V 6
1231 jelmer
1232 K 8
1233 svn:date
1234 V 27
1235 2006-12-25T04:30:06.383777Z
1236 PROPS-END
1237
1238
1239 Node-path: y
1240 Node-kind: dir
1241 Node-action: add
1242 Node-copyfrom-rev: 1
1243 Node-copyfrom-path: x
1244
1245
1246 """)
1247         os.mkdir("old")
1248
1249         load_dumpfile("dumpfile", "old")
1250         oldrepos = Repository.open("old")
1251         dir = BzrDir.create("f", format.get_rich_root_format())
1252         newrepos = dir.create_repository()
1253         oldrepos.copy_content_into(newrepos)
1254         mapping = oldrepos.get_mapping()
1255         self.assertTrue(newrepos.has_revision(
1256             oldrepos.generate_revision_id(1, "", mapping)))
1257         self.assertTrue(newrepos.has_revision(
1258             oldrepos.generate_revision_id(5, "", mapping)))
1259         inv1 = newrepos.get_inventory(
1260                 oldrepos.generate_revision_id(1, "", mapping))
1261         inv2 = newrepos.get_inventory(
1262                 oldrepos.generate_revision_id(5, "", mapping))
1263         self.assertNotEqual(inv1.path2id("y"), inv2.path2id("y"))
1264
1265     def test_fetch_dir_upgrade(self):
1266         repos_url = self.make_repository('d')
1267
1268         dc = self.commit_editor(repos_url)
1269         dc.add_dir("trunk")
1270         dc.add_dir("trunk/lib")
1271         dc.add_file("trunk/lib/file", 'data')
1272         dc.done()
1273
1274         dc = self.commit_editor(repos_url)
1275         dc.add_dir("branches")
1276         dc.add_dir("branches/mybranch", "trunk/lib")
1277         dc.done()
1278
1279         oldrepos = Repository.open(repos_url)
1280         set_branching_scheme(oldrepos, TrunkBranchingScheme())
1281         dir = BzrDir.create("f", format.get_rich_root_format())
1282         newrepos = dir.create_repository()
1283         oldrepos.copy_content_into(newrepos)
1284
1285         branch = Branch.open("%s/branches/mybranch" % repos_url)
1286         mapping = oldrepos.get_mapping()
1287         self.assertEqual([oldrepos.generate_revision_id(2, "branches/mybranch", mapping)], 
1288                          branch.revision_history())
1289
1290     def test_fetch_file_from_non_branch(self):
1291         repos_url = self.make_client('d', 'dc')
1292
1293         self.build_tree({'dc/old-trunk/lib/file': 'data'})
1294         self.client_add("dc/old-trunk")
1295         self.client_commit("dc", "trunk data")
1296
1297         self.build_tree({'dc/trunk/lib': None})
1298         self.client_add("dc/trunk")
1299         self.client_copy("dc/old-trunk/lib/file", "dc/trunk/lib/file")
1300         self.client_commit("dc", "revive old trunk")
1301
1302         oldrepos = Repository.open(repos_url)
1303         set_branching_scheme(oldrepos, TrunkBranchingScheme())
1304         dir = BzrDir.create("f", format.get_rich_root_format())
1305         newrepos = dir.create_repository()
1306         oldrepos.copy_content_into(newrepos)
1307
1308         branch = Branch.open("%s/trunk" % repos_url)
1309         self.assertEqual([oldrepos.generate_revision_id(2, "trunk", oldrepos.get_mapping())], 
1310                          branch.revision_history())
1311
1312     def test_fetch_dir_from_non_branch(self):
1313         repos_url = self.make_client('d', 'dc')
1314
1315         self.build_tree({'dc/old-trunk/lib/file': 'data'})
1316         self.client_add("dc/old-trunk")
1317         self.client_commit("dc", "trunk data")
1318
1319         self.client_copy("dc/old-trunk", "dc/trunk")
1320         self.client_commit("dc", "revive old trunk")
1321
1322         oldrepos = Repository.open(repos_url)
1323         set_branching_scheme(oldrepos, TrunkBranchingScheme())
1324         dir = BzrDir.create("f", format.get_rich_root_format())
1325         newrepos = dir.create_repository()
1326         oldrepos.copy_content_into(newrepos)
1327
1328         branch = Branch.open("%s/trunk" % repos_url)
1329         self.assertEqual([oldrepos.generate_revision_id(2, "trunk", oldrepos.get_mapping())],
1330                          branch.revision_history())
1331
1332     def test_fetch_from_non_branch(self):
1333         repos_url = self.make_repository('d')
1334
1335         dc = self.commit_editor(repos_url)
1336         dc.add_dir("old-trunk")
1337         dc.add_dir("old-trunk/lib")
1338         dc.add_file("old-trunk/lib/file", "data")
1339         dc.done()
1340
1341         dc = self.commit_editor(repos_url)
1342         dc.add_dir("trunk", "old-trunk")
1343         dc.done()
1344
1345         oldrepos = Repository.open(repos_url)
1346         set_branching_scheme(oldrepos, TrunkBranchingScheme())
1347         dir = BzrDir.create("f", format.get_rich_root_format())
1348         newrepos = dir.create_repository()
1349         oldrepos.copy_content_into(newrepos)
1350
1351         branch = Branch.open("%s/trunk" % repos_url)
1352         self.assertEqual([oldrepos.generate_revision_id(2, "trunk", oldrepos.get_mapping())],
1353                          branch.revision_history())
1354
1355
1356
1357     def test_fetch_branch_downgrade(self):
1358         repos_url = self.make_client('d', 'dc')
1359
1360         self.build_tree({'dc/trunk/file': 'data'})
1361         self.client_add("dc/trunk")
1362         self.client_commit("dc", "trunk data")
1363
1364         self.build_tree({'dc/branches/mybranch': None})
1365         self.client_add("dc/branches")
1366         self.client_copy("dc/trunk", "dc/branches/mybranch/lib")
1367         self.client_commit("dc", "split out lib")
1368
1369         oldrepos = Repository.open(repos_url)
1370         set_branching_scheme(oldrepos, TrunkBranchingScheme())
1371         dir = BzrDir.create("f", format.get_rich_root_format())
1372         newrepos = dir.create_repository()
1373         oldrepos.copy_content_into(newrepos)
1374
1375     def test_fetch_all(self):
1376         repos_url = self.make_repository('d')
1377
1378         dc = self.commit_editor(repos_url)
1379         dc.add_dir("trunk")
1380         dc.add_file("trunk/hosts", 'hej1')
1381         dc.done()
1382
1383         dc = self.commit_editor(repos_url)
1384         dc.change_file('trunk/hosts', 'hej2')
1385         dc.done()
1386
1387         dc = self.commit_editor(repos_url)
1388         dc.change_file('trunk/hosts', 'hej3')
1389         dc.done()
1390
1391         dc = self.commit_editor(repos_url)
1392         dc.add_dir("branches")
1393         dc.add_dir("branches/foobranch")
1394         dc.add_file("branches/foobranch/file", 'foohosts')
1395         dc.done()
1396
1397         oldrepos = Repository.open(repos_url)
1398         set_branching_scheme(oldrepos, TrunkBranchingScheme())
1399         dir = BzrDir.create("f", format.get_rich_root_format())
1400         newrepos = dir.create_repository()
1401         oldrepos.copy_content_into(newrepos)
1402
1403         mapping = oldrepos.get_mapping()
1404
1405         self.assertTrue(newrepos.has_revision(
1406             oldrepos.generate_revision_id(1, "trunk", mapping)))
1407         self.assertTrue(newrepos.has_revision(
1408             oldrepos.generate_revision_id(2, "trunk", mapping)))
1409         self.assertTrue(newrepos.has_revision(
1410             oldrepos.generate_revision_id(3, "trunk", mapping)))
1411         self.assertTrue(newrepos.has_revision(
1412             oldrepos.generate_revision_id(4, "branches/foobranch", mapping)))
1413         self.assertFalse(newrepos.has_revision(
1414             oldrepos.generate_revision_id(4, "trunk", mapping)))
1415         self.assertFalse(newrepos.has_revision(
1416             oldrepos.generate_revision_id(2, "", mapping)))
1417
1418     def test_fetch_copy_root_id_kept(self):
1419         repos_url = self.make_client('d', 'dc')
1420
1421         self.build_tree({'dc/trunk': None, 
1422                          'dc/trunk/hosts': 'hej1'})
1423         self.client_add("dc/trunk")
1424         self.client_commit("dc", "created trunk and added hosts") #1
1425
1426         self.build_tree({'dc/branches': None})
1427         self.client_add("dc/branches")
1428         self.client_commit("dc", "added branches") #2
1429
1430         self.client_copy("dc/trunk", "dc/branches/foobranch")
1431         self.client_commit("dc", "added branch foobranch") #3
1432
1433         repos = remote.SvnRemoteAccess(SvnRaTransport("svn+"+repos_url), format.SvnRemoteFormat()).find_repository()
1434         set_branching_scheme(repos, TrunkBranchingScheme())
1435
1436         mapping = repos.get_mapping()
1437
1438         tree = repos.revision_tree(
1439              repos.generate_revision_id(3, "branches/foobranch", mapping))
1440
1441         self.assertEqual(mapping.generate_file_id(repos.uuid, 1, "trunk", u""), tree.inventory.root.file_id)
1442
1443     def test_fetch_odd(self):
1444         repos_url = self.make_client('d', 'dc')
1445
1446         self.build_tree({'dc/trunk': None, 
1447                          'dc/trunk/hosts': 'hej1'})
1448         self.client_add("dc/trunk")
1449         self.client_commit("dc", "created trunk and added hosts") #1
1450         self.client_update("dc")
1451
1452         self.build_tree({'dc/trunk/hosts': 'hej2'})
1453         self.client_commit("dc", "rev 2") #2
1454         self.client_update("dc")
1455
1456         self.build_tree({'dc/trunk/hosts': 'hej3'})
1457         self.client_commit("dc", "rev 3") #3
1458         self.client_update("dc")
1459
1460         self.build_tree({'dc/branches': None})
1461         self.client_add("dc/branches")
1462         self.client_commit("dc", "added branches") #4
1463         self.client_update("dc")
1464
1465         self.client_copy("dc/trunk", "dc/branches/foobranch")
1466         self.client_commit("dc", "added branch foobranch") #5
1467         self.client_update("dc")
1468
1469         self.build_tree({'dc/branches/foobranch/hosts': 'foohosts'})
1470         self.client_commit("dc", "foohosts") #6
1471
1472         repos = remote.SvnRemoteAccess(SvnRaTransport("svn+"+repos_url), format.SvnRemoteFormat()).find_repository()
1473         set_branching_scheme(repos, TrunkBranchingScheme())
1474
1475         mapping = repos.get_mapping()
1476
1477         tree = repos.revision_tree(
1478              repos.generate_revision_id(6, "branches/foobranch", mapping))
1479
1480     def test_fetch_consistent(self):
1481         repos_url = self.make_repository('d')
1482
1483         dc = self.commit_editor(repos_url)
1484         dc.add_file("bla", "data")
1485         dc.change_file_prop("bla", "svn:executable", "*")
1486         dc.done()
1487
1488         oldrepos = Repository.open("svn+"+repos_url)
1489         dir1 = BzrDir.create("f", format.get_rich_root_format())
1490         dir2 = BzrDir.create("g", format.get_rich_root_format())
1491         newrepos1 = dir1.create_repository()
1492         newrepos2 = dir2.create_repository()
1493         oldrepos.copy_content_into(newrepos1)
1494         oldrepos.copy_content_into(newrepos2)
1495         mapping = oldrepos.get_mapping()
1496         inv1 = newrepos1.get_inventory(
1497                 oldrepos.generate_revision_id(1, "", mapping))
1498         inv2 = newrepos2.get_inventory(
1499                 oldrepos.generate_revision_id(1, "", mapping))
1500         self.assertEqual(inv1, inv2)
1501
1502     def test_fetch_executable(self):
1503         repos_url = self.make_client('d', 'dc')
1504         self.build_tree({'dc/bla': "data", 'dc/blie': "data2"})
1505         self.client_add("dc/bla")
1506         self.client_add("dc/blie")
1507         self.client_set_prop("dc/bla", "svn:executable", "*")
1508         self.client_set_prop("dc/blie", "svn:executable", "")
1509         self.client_commit("dc", "My Message")
1510         oldrepos = Repository.open("svn+"+repos_url)
1511         dir = BzrDir.create("f", format.get_rich_root_format())
1512         newrepos = dir.create_repository()
1513         oldrepos.copy_content_into(newrepos)
1514         mapping = oldrepos.get_mapping()
1515         self.assertTrue(newrepos.has_revision(
1516             oldrepos.generate_revision_id(1, "", mapping)))
1517         inv1 = newrepos.get_inventory(
1518                 oldrepos.generate_revision_id(1, "", mapping))
1519         self.assertTrue(inv1[inv1.path2id("bla")].executable)
1520         self.assertTrue(inv1[inv1.path2id("blie")].executable)
1521
1522     def test_fetch_symlink(self):
1523         if not has_symlinks():
1524             return
1525         repos_url = self.make_client('d', 'dc')
1526         self.build_tree({'dc/bla': "data"})
1527         os.symlink('bla', 'dc/mylink')
1528         self.client_add("dc/bla")
1529         self.client_add("dc/mylink")
1530         self.client_commit("dc", "My Message")
1531         oldrepos = Repository.open("svn+"+repos_url)
1532         dir = BzrDir.create("f", format.get_rich_root_format())
1533         newrepos = dir.create_repository()
1534         oldrepos.copy_content_into(newrepos)
1535         mapping = oldrepos.get_mapping()
1536         self.assertTrue(newrepos.has_revision(
1537             oldrepos.generate_revision_id(1, "", mapping)))
1538         inv1 = newrepos.get_inventory(
1539                 oldrepos.generate_revision_id(1, "", mapping))
1540         self.assertEqual('symlink', inv1[inv1.path2id("mylink")].kind)
1541         self.assertEqual('bla', inv1[inv1.path2id("mylink")].symlink_target)
1542
1543     def test_fetch_symlink_kind_change(self):
1544         repos_url = self.make_client('d', 'dc')
1545         self.build_tree({'dc/bla': "data", "dc/mylink": "link bla"})
1546         self.client_add("dc/bla")
1547         self.client_add("dc/mylink")
1548         self.client_commit("dc", "My Message")
1549         ra = SvnRaTransport(repos_url)
1550         def done(info, pool):
1551             pass
1552         editor = ra.get_commit_editor({"svn:log": "msg"}, done, None, False)
1553         root_baton = editor.open_root(1)
1554         baton = root_baton.open_file("mylink", 1)
1555         baton.change_prop("svn:special", "*")
1556         baton.close()
1557         root_baton.close()
1558         editor.close()
1559         oldrepos = Repository.open("svn+"+repos_url)
1560         dir = BzrDir.create("f", format.get_rich_root_format())
1561         newrepos = dir.create_repository()
1562         oldrepos.copy_content_into(newrepos)
1563         mapping = oldrepos.get_mapping()
1564         self.assertTrue(newrepos.has_revision(
1565             oldrepos.generate_revision_id(1, "", mapping)))
1566         inv1 = newrepos.get_inventory(
1567                 oldrepos.generate_revision_id(1, "", mapping))
1568         inv2 = newrepos.get_inventory(
1569                 oldrepos.generate_revision_id(2, "", mapping))
1570         self.assertEqual('file', inv1[inv1.path2id("mylink")].kind)
1571         self.assertEqual('symlink', inv2[inv2.path2id("mylink")].kind)
1572         self.assertEqual('bla', inv2[inv2.path2id("mylink")].symlink_target)
1573
1574     def test_fetch_executable_separate(self):
1575         repos_url = self.make_client('d', 'dc')
1576         self.build_tree({'dc/bla': "data"})
1577         self.client_add("dc/bla")
1578         self.client_commit("dc", "My Message")
1579         self.client_set_prop("dc/bla", "svn:executable", "*")
1580         self.client_commit("dc", "Make executable")
1581         oldrepos = Repository.open("svn+"+repos_url)
1582         dir = BzrDir.create("f", format.get_rich_root_format())
1583         newrepos = dir.create_repository()
1584         oldrepos.copy_content_into(newrepos)
1585         mapping = oldrepos.get_mapping()
1586         self.assertTrue(newrepos.has_revision(
1587             oldrepos.generate_revision_id(1, "", mapping)))
1588         inv1 = newrepos.get_inventory(
1589                 oldrepos.generate_revision_id(1, "", mapping))
1590         self.assertFalse(inv1[inv1.path2id("bla")].executable)
1591         inv2 = newrepos.get_inventory(
1592                 oldrepos.generate_revision_id(2, "", mapping))
1593         self.assertTrue(inv2[inv2.path2id("bla")].executable)
1594         self.assertEqual(oldrepos.generate_revision_id(2, "", mapping), 
1595                          inv2[inv2.path2id("bla")].revision)
1596
1597     def test_fetch_ghosts(self):
1598         repos_url = self.make_repository('d')
1599
1600         dc = self.commit_editor(repos_url)
1601         dc.add_file("bla", "data")
1602         dc.change_dir_prop("", "bzr:ancestry:v3-none", "aghost\n")
1603         dc.done()
1604
1605         oldrepos = Repository.open("svn+"+repos_url)
1606         dir = BzrDir.create("f", format.get_rich_root_format())
1607         newrepos = dir.create_repository()
1608         oldrepos.copy_content_into(newrepos)
1609         mapping = oldrepos.get_mapping()
1610
1611         rev = newrepos.get_revision(oldrepos.generate_revision_id(1, "", mapping))
1612         self.assertTrue("aghost" in rev.parent_ids)
1613
1614     def test_fetch_svk_merge(self):
1615         repos_url = self.make_client('d', 'dc')
1616         self.build_tree({'dc/trunk/bla': "data", "dc/branches": None})
1617         self.client_add("dc/trunk")
1618         self.client_commit("dc", "My Message")
1619
1620         self.client_add("dc/branches")
1621         self.client_copy("dc/trunk", "dc/branches/foo")
1622         self.build_tree({'dc/branches/foo/bla': "more data"})
1623         self.client_commit("dc", "Branch")
1624
1625         oldrepos = Repository.open("svn+"+repos_url)
1626         self.client_set_prop("dc/trunk", "svk:merge", 
1627                              "%s:/branches/foo:2\n" % oldrepos.uuid)
1628         self.client_commit("dc", "Merge")
1629
1630         dir = BzrDir.create("f", format.get_rich_root_format())
1631         newrepos = dir.create_repository()
1632         oldrepos.copy_content_into(newrepos)
1633
1634         mapping = oldrepos.get_mapping()
1635
1636         rev = newrepos.get_revision(oldrepos.generate_revision_id(3, "trunk", mapping))
1637         mutter('parent ids: %r' % rev.parent_ids)
1638         self.assertTrue(oldrepos.generate_revision_id(2, "branches/foo", mapping) in rev.parent_ids)
1639
1640     def test_fetch_invalid_ghosts(self):
1641         repos_url = self.make_client('d', 'dc')
1642         self.build_tree({'dc/bla': "data"})
1643         self.client_add("dc/bla")
1644         self.client_set_prop("dc", "bzr:ancestry:v3-none", "a ghost\n")
1645         self.client_commit("dc", "My Message")
1646         oldrepos = Repository.open("svn+"+repos_url)
1647         dir = BzrDir.create("f", format.get_rich_root_format())
1648         newrepos = dir.create_repository()
1649         oldrepos.copy_content_into(newrepos)
1650         
1651         mapping = oldrepos.get_mapping()
1652
1653         rev = newrepos.get_revision(oldrepos.generate_revision_id(1, "", mapping))
1654         self.assertEqual([oldrepos.generate_revision_id(0, "", mapping)], rev.parent_ids)
1655
1656     def test_fetch_property_change_only(self):
1657         repos_url = self.make_repository('d')
1658         dc = self.commit_editor(repos_url)
1659         dc.add_dir("trunk")
1660         dc.add_file("trunk/bla", "data")
1661         dc.done()
1662
1663         dc = self.commit_editor(repos_url)
1664         dc.change_dir_prop("", "some:property", "some data\n")
1665         dc.done()
1666
1667         dc = self.commit_editor(repos_url)
1668         dc.change_dir_prop("", "some2:property", "some data\n")
1669         dc.done()
1670
1671         dc = self.commit_editor(repos_url)
1672         dc.change_dir_prop("", "some:property", "some data4\n")
1673         dc.done()
1674
1675         oldrepos = Repository.open("svn+"+repos_url)
1676         dir = BzrDir.create("f", format.get_rich_root_format())
1677         newrepos = dir.create_repository()
1678         oldrepos.copy_content_into(newrepos)
1679         mapping = oldrepos.get_mapping()
1680         self.assertEquals([
1681             oldrepos.generate_revision_id(0, "", mapping),
1682             oldrepos.generate_revision_id(1, "", mapping),
1683             oldrepos.generate_revision_id(2, "", mapping),
1684             oldrepos.generate_revision_id(3, "", mapping),
1685             oldrepos.generate_revision_id(4, "", mapping),
1686             ], newrepos.all_revision_ids())
1687
1688     def test_fetch_property_change_only_trunk(self):
1689         repos_url = self.make_repository('d')
1690         dc = self.commit_editor(repos_url)
1691         dc.add_dir("trunk")
1692         dc.add_file("trunk/bla", "data")
1693         dc.done()
1694
1695         dc = self.commit_editor(repos_url)
1696         dc.change_dir_prop("trunk", "some:property", "some data\n")
1697         dc.done()
1698
1699         dc = self.commit_editor(repos_url)
1700         dc.change_dir_prop("trunk", "some2:property", "some data\n")
1701         dc.done()
1702
1703         dc = self.commit_editor(repos_url)
1704         dc.change_dir_prop("trunk", "some:property", "some data3\n")
1705         dc.done()
1706
1707         oldrepos = Repository.open("svn+"+repos_url)
1708         set_branching_scheme(oldrepos, TrunkBranchingScheme())
1709         dir = BzrDir.create("f", format.get_rich_root_format())
1710         newrepos = dir.create_repository()
1711         oldrepos.copy_content_into(newrepos)
1712         mapping = oldrepos.get_mapping()
1713         self.assertEquals([
1714             oldrepos.generate_revision_id(1, "trunk", mapping),
1715             oldrepos.generate_revision_id(2, "trunk", mapping),
1716             oldrepos.generate_revision_id(3, "trunk", mapping),
1717             oldrepos.generate_revision_id(4, "trunk", mapping),
1718             ], newrepos.all_revision_ids())
1719
1720     def test_fetch_crosscopy(self):
1721         repos_url = self.make_client('d', 'dc')
1722         self.build_tree({'dc/trunk/adir/afile': "data", 
1723                          'dc/trunk/adir/stationary': None,
1724                          'dc/branches/abranch': None})
1725         self.client_add("dc/trunk")
1726         self.client_add("dc/branches")
1727         self.client_commit("dc", "Initial commit")
1728
1729         # copyrev
1730         self.client_copy("dc/trunk/adir", "dc/branches/abranch/bdir")
1731         self.client_commit("dc", "Cross copy commit")
1732
1733         # prevrev
1734         self.build_tree({"dc/branches/abranch/bdir/afile": "otherdata"})
1735         self.client_commit("dc", "Change data")
1736
1737         # lastrev
1738         self.build_tree({"dc/branches/abranch/bdir/bfile": "camel",
1739                       "dc/branches/abranch/bdir/stationary/traveller": "data"})
1740         self.client_add("dc/branches/abranch/bdir/bfile")
1741         self.client_add("dc/branches/abranch/bdir/stationary/traveller")
1742         self.client_commit("dc", "Change dir")
1743
1744         oldrepos = Repository.open("svn+"+repos_url)
1745         set_branching_scheme(oldrepos, TrunkBranchingScheme())
1746         dir = BzrDir.create("f", format.get_rich_root_format())
1747         newrepos = dir.create_repository()
1748         mapping = oldrepos.get_mapping()
1749         copyrev = oldrepos.generate_revision_id(2, "branches/abranch", mapping)
1750         prevrev = oldrepos.generate_revision_id(3, "branches/abranch", mapping)
1751         lastrev = oldrepos.generate_revision_id(4, "branches/abranch", mapping)
1752         oldrepos.copy_content_into(newrepos, lastrev)
1753
1754         inventory = newrepos.get_inventory(lastrev)
1755         self.assertEqual(prevrev, 
1756                          inventory[inventory.path2id("bdir/afile")].revision)
1757
1758         inventory = newrepos.get_inventory(prevrev)
1759         self.assertEqual(copyrev, 
1760                          inventory[inventory.path2id("bdir/stationary")].revision)
1761
1762