f42ae30680175d7370c0aa39625363d0730ee86a
[jelmer/subvertpy.git] / tests / test_repos.py
1 # Copyright (C) 2006-2007 Jelmer Vernooij <jelmer@samba.org>
2
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.
7
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.
12
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
17 from bzrlib.branch import Branch
18 from bzrlib.bzrdir import BzrDir
19 from bzrlib.errors import NoSuchRevision, UninitializableFormat
20 from bzrlib.inventory import Inventory
21 from bzrlib.repository import Repository
22 from bzrlib.revision import NULL_REVISION
23 from bzrlib.tests import TestCase
24
25 import os
26
27 import svn.fs
28
29 from convert import load_dumpfile
30 from fileids import generate_svn_file_id, generate_file_id
31 import format
32 from scheme import TrunkBranchingScheme, NoBranchingScheme
33 from transport import SvnRaTransport
34 from tests import TestCaseWithSubversionRepository
35 from repository import (svk_feature_to_revision_id, revision_id_to_svk_feature,
36                         SvnRepositoryFormat)
37 from revids import (MAPPING_VERSION, escape_svn_path, unescape_svn_path,
38                     parse_svn_revision_id, generate_svn_revision_id)
39
40
41 class TestSubversionRepositoryWorks(TestCaseWithSubversionRepository):
42     def test_format(self):
43         """ Test repository format is correct """
44         bzrdir = self.make_local_bzrdir('a', 'ac')
45         self.assertEqual(bzrdir._format.get_format_string(), \
46                 "Subversion Local Checkout")
47         
48         self.assertEqual(bzrdir._format.get_format_description(), \
49                 "Subversion Local Checkout")
50
51     def test_get_branch_log(self):
52         repos_url = self.make_client("a", "dc")
53         self.build_tree({'dc/foo': "data"})
54         self.client_add("dc/foo")
55         self.client_commit("dc", "My Message")
56
57         repos = Repository.open(repos_url)
58
59         self.assertEqual(2, len(list(repos.follow_branch_history("", 1))))
60
61     def test_make_working_trees(self):
62         repos_url = self.make_client("a", "dc")
63         repos = Repository.open(repos_url)
64         self.assertFalse(repos.make_working_trees())
65
66     def test_set_make_working_trees(self):
67         repos_url = self.make_client("a", "dc")
68         repos = Repository.open(repos_url)
69         repos.set_make_working_trees(True)
70         self.assertFalse(repos.make_working_trees())
71
72     def test_get_fileid_map(self):
73         repos_url = self.make_client("a", "dc")
74         repos = Repository.open(repos_url)
75         revid = repos.generate_revision_id(0, "")
76         self.assertEqual({"": (generate_file_id(revid, ""), revid)}, repos.get_fileid_map(0, ""))
77
78     def test_add_revision(self):
79         repos_url = self.make_client("a", "dc")
80         repos = Repository.open(repos_url)
81         self.assertRaises(NotImplementedError, repos.add_revision, "revid", 
82                 None)
83
84     def test_has_signature_for_revision_id(self):
85         repos_url = self.make_client("a", "dc")
86         repos = Repository.open(repos_url)
87         self.assertFalse(repos.has_signature_for_revision_id("foo"))
88
89     def test_repr(self):
90         repos_url = self.make_client("a", "dc")
91         self.build_tree({'dc/foo': "data"})
92         self.client_add("dc/foo")
93         self.client_commit("dc", "My Message")
94
95         repos = Repository.open(repos_url)
96
97         self.assertEqual("SvnRepository('file://%s/')" % os.path.join(self.test_dir, "a"), repos.__repr__())
98
99     def test_get_branch_invalid_revision(self):
100         repos_url = self.make_client("a", "dc")
101         repos = Repository.open(repos_url)
102         self.assertRaises(NoSuchRevision, list, 
103                           repos.follow_branch_history("/", 20))
104
105     def test_history_all(self):
106         repos_url = self.make_client("a", "dc")
107         self.build_tree({'dc/trunk/file': "data", "dc/foo/file":"data"})
108         self.client_add("dc/trunk")
109         self.client_add("dc/foo")
110         self.client_commit("dc", "My Message")
111
112         repos = Repository.open(repos_url)
113
114         self.assertEqual(2, len(list(repos.follow_history(1))))
115
116     def test_all_revs_empty(self):
117         repos_url = self.make_client("a", "dc")
118         repos = Repository.open(repos_url)
119         repos.set_branching_scheme(TrunkBranchingScheme())
120         self.assertEqual([], list(repos.all_revision_ids()))
121
122     def test_all_revs(self):
123         repos_url = self.make_client("a", "dc")
124         self.build_tree({'dc/trunk/file': "data", "dc/foo/file":"data"})
125         self.client_add("dc/trunk")
126         self.client_commit("dc", "add trunk")
127         self.build_tree({'dc/branches/somebranch/somefile': 'data'})
128         self.client_add("dc/branches")
129         self.client_commit("dc", "add a branch")
130         self.client_delete("dc/branches/somebranch")
131         self.client_commit("dc", "remove branch")
132
133         repos = Repository.open(repos_url)
134         repos.set_branching_scheme(TrunkBranchingScheme())
135         self.assertEqual([
136             repos.generate_revision_id(2, "branches/somebranch"),
137             repos.generate_revision_id(1, "trunk")], 
138             list(repos.all_revision_ids()))
139
140     def test_follow_history_empty(self):
141         repos_url = self.make_client("a", "dc")
142         self.assertEqual([('', 0)], 
143                 list(Repository.open(repos_url).follow_history(0)))
144
145     def test_follow_history_empty_branch(self):
146         repos_url = self.make_client("a", "dc")
147         self.build_tree({'dc/trunk/afile': "data", "dc/branches": None})
148         self.client_add("dc/trunk")
149         self.client_add("dc/branches")
150         self.client_commit("dc", "My Message")
151         repos = Repository.open(repos_url)
152         repos.set_branching_scheme(TrunkBranchingScheme())
153         self.assertEqual([('trunk', 1)], list(repos.follow_history(1)))
154
155     def test_follow_history_follow(self):
156         repos_url = self.make_client("a", "dc")
157         self.build_tree({'dc/trunk/afile': "data", "dc/branches": None})
158         self.client_add("dc/trunk")
159         self.client_add("dc/branches")
160         self.client_commit("dc", "My Message")
161
162         self.client_copy("dc/trunk", "dc/branches/abranch")
163         self.client_commit("dc", "Create branch")
164
165         repos = Repository.open(repos_url)
166         repos.set_branching_scheme(TrunkBranchingScheme())
167
168         items = list(repos.follow_history(2))
169         self.assertEqual([('branches/abranch', 2), 
170                           ('trunk', 1)], items)
171
172     def test_branch_log_specific(self):
173         repos_url = self.make_client("a", "dc")
174         self.build_tree({
175             'dc/branches': None,
176             'dc/branches/brancha': None,
177             'dc/branches/branchab': None,
178             'dc/branches/brancha/data': "data", 
179             "dc/branches/branchab/data":"data"})
180         self.client_add("dc/branches")
181         self.client_commit("dc", "My Message")
182
183         repos = Repository.open(repos_url)
184         repos.set_branching_scheme(TrunkBranchingScheme())
185
186         self.assertEqual(1, len(list(repos.follow_branch_history("branches/brancha",
187             1))))
188
189     def test_branch_log_specific_ignore(self):
190         repos_url = self.make_client("a", "dc")
191         self.build_tree({'dc/branches': None})
192         self.client_add("dc/branches")
193         self.build_tree({
194             'dc/branches/brancha': None,
195             'dc/branches/branchab': None,
196             'dc/branches/brancha/data': "data", 
197             "dc/branches/branchab/data":"data"})
198         self.client_add("dc/branches/brancha")
199         self.client_commit("dc", "My Message")
200
201         self.client_add("dc/branches/branchab")
202         self.client_commit("dc", "My Message2")
203
204         repos = Repository.open(repos_url)
205         repos.set_branching_scheme(TrunkBranchingScheme())
206
207         self.assertEqual(1, len(list(repos.follow_branch_history("branches/brancha",
208             2))))
209
210     def test_find_branches_moved(self):
211         repos_url = self.make_client("a", "dc")
212         self.build_tree({
213             'dc/tmp/branches/brancha': None,
214             'dc/tmp/branches/branchab': None,
215             'dc/tmp/branches/brancha/data': "data", 
216             "dc/tmp/branches/branchab/data":"data"})
217         self.client_add("dc/tmp")
218         self.client_commit("dc", "My Message")
219         self.client_copy("dc/tmp/branches", "dc/tags")
220         self.client_commit("dc", "My Message 2")
221
222         repos = Repository.open(repos_url)
223         repos.set_branching_scheme(TrunkBranchingScheme())
224
225         self.assertEqual([("tags/branchab", 2, True), 
226                           ("tags/brancha", 2, True)], 
227                 list(repos.find_branches(2)))
228
229     def test_find_branches_moved_nobranch(self):
230         repos_url = self.make_client("a", "dc")
231         self.build_tree({
232             'dc/tmp/nested/foobar': None,
233             'dc/tmp/nested/branches/brancha': None,
234             'dc/tmp/nested/branches/branchab': None,
235             'dc/tmp/nested/branches/brancha/data': "data", 
236             "dc/tmp/nested/branches/branchab/data":"data"})
237         self.client_add("dc/tmp")
238         self.client_commit("dc", "My Message")
239         self.client_copy("dc/tmp/nested", "dc/t2")
240         self.client_commit("dc", "My Message 2")
241
242         repos = Repository.open(repos_url)
243         repos.set_branching_scheme(TrunkBranchingScheme(1))
244
245         self.assertEqual([("t2/branches/brancha", 2, True), 
246                           ("t2/branches/branchab", 2, True)], 
247                 list(repos.find_branches(2)))
248
249     def test_find_branches_no(self):
250         repos_url = self.make_client("a", "dc")
251
252         repos = Repository.open(repos_url)
253         repos.set_branching_scheme(NoBranchingScheme())
254
255         self.assertEqual([("", 0, True)], list(repos.find_branches(0)))
256
257     def test_find_branches_no_later(self):
258         repos_url = self.make_client("a", "dc")
259
260         repos = Repository.open(repos_url)
261         repos.set_branching_scheme(NoBranchingScheme())
262
263         self.assertEqual([("", 0, True)], list(repos.find_branches(0)))
264
265     def test_find_branches_trunk_empty(self):
266         repos_url = self.make_client("a", "dc")
267
268         repos = Repository.open(repos_url)
269         repos.set_branching_scheme(TrunkBranchingScheme())
270
271         self.assertEqual([], list(repos.find_branches(0)))
272
273     def test_find_branches_trunk_one(self):
274         repos_url = self.make_client("a", "dc")
275
276         repos = Repository.open(repos_url)
277         repos.set_branching_scheme(TrunkBranchingScheme())
278
279         self.build_tree({'dc/trunk/foo': "data"})
280         self.client_add("dc/trunk")
281         self.client_commit("dc", "My Message")
282
283         self.assertEqual([("trunk", 1, True)], list(repos.find_branches(1)))
284
285     def test_find_branches_removed(self):
286         repos_url = self.make_client("a", "dc")
287
288         repos = Repository.open(repos_url)
289         repos.set_branching_scheme(TrunkBranchingScheme())
290
291         self.build_tree({'dc/trunk/foo': "data"})
292         self.client_add("dc/trunk")
293         self.client_commit("dc", "My Message")
294
295         self.client_delete("dc/trunk")
296         self.client_commit("dc", "remove")
297
298         self.assertEqual([("trunk", 1, True)], list(repos.find_branches(1)))
299         self.assertEqual([("trunk", 2, False)], list(repos.find_branches(2)))
300
301     def test_url(self):
302         """ Test repository URL is kept """
303         bzrdir = self.make_local_bzrdir('b', 'bc')
304         self.assertTrue(isinstance(bzrdir, BzrDir))
305
306     def test_uuid(self):
307         """ Test UUID is retrieved correctly """
308         bzrdir = self.make_local_bzrdir('c', 'cc')
309         self.assertTrue(isinstance(bzrdir, BzrDir))
310         repository = bzrdir.find_repository()
311         fs = self.open_fs('c')
312         self.assertEqual(svn.fs.get_uuid(fs), repository.uuid)
313
314     def test_get_inventory_weave(self):
315         bzrdir = self.make_client_and_bzrdir('d', 'dc')
316         repository = bzrdir.find_repository()
317         self.assertRaises(NotImplementedError, repository.get_inventory_weave)
318
319     def test_has_revision(self):
320         bzrdir = self.make_client_and_bzrdir('d', 'dc')
321         repository = bzrdir.find_repository()
322         self.build_tree({'dc/foo': "data"})
323         self.client_add("dc/foo")
324         self.client_commit("dc", "My Message")
325         self.assertTrue(repository.has_revision(
326             repository.generate_revision_id(1, "")))
327         self.assertFalse(repository.has_revision("some-other-revision"))
328
329     def test_has_revision_none(self):
330         bzrdir = self.make_client_and_bzrdir('d', 'dc')
331         repository = bzrdir.find_repository()
332         self.assertTrue(repository.has_revision(None))
333
334     def test_revision_parents(self):
335         repos_url = self.make_client('d', 'dc')
336         self.build_tree({'dc/foo': "data"})
337         self.client_add("dc/foo")
338         self.client_commit("dc", "My Message")
339         self.build_tree({'dc/foo': "data2"})
340         self.client_commit("dc", "Second Message")
341         repository = Repository.open("svn+%s" % repos_url)
342         self.assertEqual([],
343                 repository.revision_parents(
344                     repository.generate_revision_id(0, "")))
345         self.assertEqual([repository.generate_revision_id(0, "")],
346                 repository.revision_parents(
347                     repository.generate_revision_id(1, "")))
348         self.assertEqual([
349             repository.generate_revision_id(1, "")],
350             repository.revision_parents(
351                 repository.generate_revision_id(2, "")))
352
353     def test_revision_fileidmap(self):
354         repos_url = self.make_client('d', 'dc')
355         self.build_tree({'dc/foo': "data"})
356         self.client_add("dc/foo")
357         self.client_set_prop("dc", "bzr:file-ids", "foo\tsomeid\n")
358         self.client_commit("dc", "My Message")
359         repository = Repository.open("svn+%s" % repos_url)
360         tree = repository.revision_tree(Branch.open(repos_url).last_revision())
361         self.assertEqual("someid", tree.inventory.path2id("foo"))
362         self.assertFalse("1@%s::foo" % repository.uuid in tree.inventory)
363
364     def test_revision_ghost_parents(self):
365         repos_url = self.make_client('d', 'dc')
366         self.build_tree({'dc/foo': "data"})
367         self.client_add("dc/foo")
368         self.client_commit("dc", "My Message")
369         self.build_tree({'dc/foo': "data2"})
370         self.client_set_prop("dc", "bzr:merge", "ghostparent\n")
371         self.client_commit("dc", "Second Message")
372         repository = Repository.open("svn+%s" % repos_url)
373         self.assertEqual([],
374                 repository.revision_parents(
375                     repository.generate_revision_id(0, "")))
376         self.assertEqual([repository.generate_revision_id(0, "")],
377                 repository.revision_parents(
378                     repository.generate_revision_id(1, "")))
379         self.assertEqual([repository.generate_revision_id(1, ""),
380             "ghostparent"], 
381                 repository.revision_parents(
382                     repository.generate_revision_id(2, "")))
383  
384     
385     def test_get_revision(self):
386         repos_url = self.make_client('d', 'dc')
387         repository = Repository.open("svn+%s" % repos_url)
388         self.assertRaises(NoSuchRevision, repository.get_revision, "nonexisting")
389         self.build_tree({'dc/foo': "data"})
390         self.client_add("dc/foo")
391         self.client_commit("dc", "My Message")
392         self.build_tree({'dc/foo': "data2"})
393         (num, date, author) = self.client_commit("dc", "Second Message")
394         repository = Repository.open("svn+%s" % repos_url)
395         rev = repository.get_revision(
396             repository.generate_revision_id(2, ""))
397         self.assertEqual([repository.generate_revision_id(1, "")],
398                 rev.parent_ids)
399         self.assertEqual(rev.revision_id, repository.generate_revision_id(2, ""))
400         self.assertEqual(author, rev.committer)
401         self.assertIsInstance(rev.properties, dict)
402
403     def test_get_revision_id_overriden(self):
404         repos_url = self.make_client('d', 'dc')
405         repository = Repository.open("svn+%s" % repos_url)
406         self.assertRaises(NoSuchRevision, repository.get_revision, "nonexisting")
407         self.build_tree({'dc/foo': "data"})
408         self.client_add("dc/foo")
409         self.client_commit("dc", "My Message")
410         self.build_tree({'dc/foo': "data2"})
411         self.client_set_prop("dc", "bzr:revision-id-v%d" % MAPPING_VERSION, 
412                             "myrevid")
413         (num, date, author) = self.client_commit("dc", "Second Message")
414         repository = Repository.open("svn+%s" % repos_url)
415         self.assertRaises(NoSuchRevision,
416                 repository.get_revision, repository.generate_revision_id(2, ""))
417         rev = repository.get_revision("myrevid")
418         self.assertEqual([repository.generate_revision_id(1, "")],
419                 rev.parent_ids)
420         self.assertEqual(rev.revision_id, repository.generate_revision_id(2, ""))
421         self.assertEqual(author, rev.committer)
422         self.assertIsInstance(rev.properties, dict)
423
424     def test_get_revision_zero(self):
425         repos_url = self.make_client('d', 'dc')
426         repository = Repository.open("svn+%s" % repos_url)
427         rev = repository.get_revision(
428             repository.generate_revision_id(0, ""))
429         self.assertEqual(repository.generate_revision_id(0, ""), rev.revision_id)
430         self.assertEqual("", rev.committer)
431         self.assertEqual({}, rev.properties)
432         self.assertEqual(None, rev.timezone)
433         self.assertEqual(0.0, rev.timestamp)
434
435     def test_get_ancestry(self):
436         repos_url = self.make_client('d', 'dc')
437         repository = Repository.open("svn+%s" % repos_url)
438         self.assertRaises(NoSuchRevision, repository.get_revision, "nonexisting")
439         self.build_tree({'dc/foo': "data"})
440         self.client_add("dc/foo")
441         self.client_commit("dc", "My Message")
442         self.build_tree({'dc/foo': "data2"})
443         self.client_commit("dc", "Second Message")
444         self.build_tree({'dc/foo': "data3"})
445         self.client_commit("dc", "Third Message")
446         repository = Repository.open("svn+%s" % repos_url)
447         self.assertEqual([None, 
448             repository.generate_revision_id(0, ""),
449             repository.generate_revision_id(1, ""),
450             repository.generate_revision_id(2, "")],
451                 repository.get_ancestry(
452                     repository.generate_revision_id(3, "")))
453         self.assertEqual([None, 
454             repository.generate_revision_id(0, ""),
455             repository.generate_revision_id(1, "")],
456                 repository.get_ancestry(
457                     repository.generate_revision_id(2, "")))
458         self.assertEqual([None,
459                     repository.generate_revision_id(0, "")],
460                 repository.get_ancestry(
461                     repository.generate_revision_id(1, "")))
462         self.assertEqual([None],
463                 repository.get_ancestry(
464                     repository.generate_revision_id(0, "")))
465         self.assertEqual([None], repository.get_ancestry(None))
466
467     def test_get_revision_graph_empty(self):
468         repos_url = self.make_client('d', 'dc')
469         repository = Repository.open("svn+%s" % repos_url)
470         self.assertEqual({}, 
471                 repository.get_revision_graph(NULL_REVISION))
472
473     def test_get_revision_graph_invalid(self):
474         repos_url = self.make_client('d', 'dc')
475         repository = Repository.open("svn+%s" % repos_url)
476         self.assertRaises(NoSuchRevision, repository.get_revision_graph, 
477                           "nonexisting")
478
479     def test_get_revision_graph_all_empty(self):
480         repos_url = self.make_client('d', 'dc')
481         repository = Repository.open(repos_url)
482         self.assertEqual({repository.generate_revision_id(0, ""): []}, 
483                 repository.get_revision_graph())
484
485     def test_get_revision_graph_zero(self):
486         repos_url = self.make_client('d', 'dc')
487         repository = Repository.open(repos_url)
488         self.assertEqual({repository.generate_revision_id(0, ""): []}, 
489                 repository.get_revision_graph(repository.generate_revision_id(0, "")))
490
491     def test_get_revision_graph_all(self):
492         repos_url = self.make_client('d', 'dc')
493         self.build_tree({'dc/trunk/a': 'data', 'dc/branches/foo/b': 'alsodata'})
494         self.client_add("dc/trunk")
495         self.client_add("dc/branches")
496         self.client_commit("dc", "initial commit")
497         self.build_tree({'dc/trunk/a': "bloe"})
498         self.client_commit("dc", "second commit")
499         repository = Repository.open(repos_url)
500         repository.set_branching_scheme(TrunkBranchingScheme())
501         self.assertEqual({repository.generate_revision_id(1, "trunk"): [],
502                           repository.generate_revision_id(2, "trunk"): [repository.generate_revision_id(1, "trunk")],
503                           repository.generate_revision_id(1, "branches/foo"): []
504                           }, repository.get_revision_graph())
505
506     def test_get_revision_graph(self):
507         repos_url = self.make_client('d', 'dc')
508         repository = Repository.open("svn+%s" % repos_url)
509         self.build_tree({'dc/foo': "data"})
510         self.client_add("dc/foo")
511         self.client_commit("dc", "My Message")
512         self.build_tree({'dc/foo': "data2"})
513         self.client_commit("dc", "Second Message")
514         self.build_tree({'dc/foo': "data3"})
515         self.client_commit("dc", "Third Message")
516         repository = Repository.open("svn+%s" % repos_url)
517         self.assertEqual({
518             repository.generate_revision_id(0, ""): [],
519            repository.generate_revision_id(3, ""): [
520                repository.generate_revision_id(2, "")],
521            repository.generate_revision_id(2, ""): [
522                repository.generate_revision_id(1, "")], 
523            repository.generate_revision_id(1, ""): [
524                repository.generate_revision_id(0, "")]},
525                 repository.get_revision_graph(
526                     repository.generate_revision_id(3, "")))
527         self.assertEqual({
528             repository.generate_revision_id(0, ""): [],
529            repository.generate_revision_id(2, ""): [
530                repository.generate_revision_id(1, "")],
531            repository.generate_revision_id(1, ""): [
532                 repository.generate_revision_id(0, "")
533                ]},
534                 repository.get_revision_graph(
535                     repository.generate_revision_id(2, "")))
536         self.assertEqual({
537             repository.generate_revision_id(0, ""): [],
538             repository.generate_revision_id(1, ""): [
539                 repository.generate_revision_id(0, "")
540                 ]},
541                 repository.get_revision_graph(
542                     repository.generate_revision_id(1, "")))
543
544     def test_get_ancestry2(self):
545         repos_url = self.make_client('d', 'dc')
546         self.build_tree({'dc/foo': "data"})
547         self.client_add("dc/foo")
548         self.client_commit("dc", "My Message")
549         self.build_tree({'dc/foo': "data2"})
550         self.client_commit("dc", "Second Message")
551         repository = Repository.open("svn+%s" % repos_url)
552         self.assertEqual([None],
553                 repository.get_ancestry(
554                     repository.generate_revision_id(0, "")))
555         self.assertEqual([None, repository.generate_revision_id(0, "")],
556                 repository.get_ancestry(
557                     repository.generate_revision_id(1, "")))
558         self.assertEqual([None, 
559             repository.generate_revision_id(0, ""),
560             repository.generate_revision_id(1, "")], 
561                 repository.get_ancestry(
562                     repository.generate_revision_id(2, "")))
563
564     def test_get_ancestry_merged(self):
565         repos_url = self.make_client('d', 'dc')
566         self.build_tree({'dc/foo': "data"})
567         self.client_add("dc/foo")
568         self.client_commit("dc", "My Message")
569         self.client_set_prop("dc", "bzr:merge", "a-parent\n")
570         self.build_tree({'dc/foo': "data2"})
571         self.client_commit("dc", "Second Message")
572         repository = Repository.open("svn+%s" % repos_url)
573         self.assertEqual([None],
574                 repository.get_ancestry(
575                     repository.generate_revision_id(0, "")))
576         self.assertEqual([None, repository.generate_revision_id(0, "")],
577                 repository.get_ancestry(
578                     repository.generate_revision_id(1, "")))
579         self.assertEqual([None, 
580             repository.generate_revision_id(0, ""),
581             repository.generate_revision_id(1, ""), 
582                           "a-parent"], 
583                 repository.get_ancestry(
584                     repository.generate_revision_id(2, "")))
585
586     def test_get_inventory(self):
587         repos_url = self.make_client('d', 'dc')
588         repository = Repository.open("svn+%s" % repos_url)
589         self.assertRaises(NoSuchRevision, repository.get_inventory, "nonexisting")
590         self.build_tree({'dc/foo': "data", 'dc/blah': "other data"})
591         self.client_add("dc/foo")
592         self.client_add("dc/blah")
593         self.client_commit("dc", "My Message")
594         self.build_tree({'dc/foo': "data2", "dc/bar/foo": "data3"})
595         self.client_add("dc/bar")
596         self.client_commit("dc", "Second Message")
597         self.build_tree({'dc/foo': "data3"})
598         self.client_commit("dc", "Third Message")
599         repository = Repository.open("svn+%s" % repos_url)
600         inv = repository.get_inventory(
601                 repository.generate_revision_id(1, ""))
602         self.assertIsInstance(inv, Inventory)
603         self.assertIsInstance(inv.path2id("foo"), basestring)
604         inv = repository.get_inventory(
605                 repository.generate_revision_id(2, ""))
606         self.assertEqual(repository.generate_revision_id(2, ""), 
607                          inv[inv.path2id("foo")].revision)
608         self.assertEqual(repository.generate_revision_id(1, ""), 
609                          inv[inv.path2id("blah")].revision)
610         self.assertIsInstance(inv, Inventory)
611         self.assertIsInstance(inv.path2id("foo"), basestring)
612         self.assertIsInstance(inv.path2id("bar"), basestring)
613         self.assertIsInstance(inv.path2id("bar/foo"), basestring)
614
615     def test_generate_revision_id(self):
616         repos_url = self.make_client('d', 'dc')
617         self.build_tree({'dc/bla/bloe': None})
618         self.client_add("dc/bla")
619         self.client_commit("dc", "bla")
620         repository = Repository.open("svn+%s" % repos_url)
621         self.assertEqual(
622                u"svn-v%d-undefined:%s:bla%%2Fbloe:1" % (MAPPING_VERSION, repository.uuid), 
623             repository.generate_revision_id(1, "bla/bloe"))
624
625     def test_generate_revision_id_zero(self):
626         repos_url = self.make_client('d', 'dc')
627         repository = Repository.open("svn+%s" % repos_url)
628         self.assertEqual("svn-v%d-undefined:%s::0" % (MAPPING_VERSION, repository.uuid), 
629                 repository.generate_revision_id(0, ""))
630
631     def test_lookup_revision_id(self):
632         repos_url = self.make_client('d', 'dc')
633         self.build_tree({'dc/bloe': None})
634         self.client_add("dc/bloe")
635         self.client_commit("dc", "foobar")
636         repository = Repository.open("svn+%s" % repos_url)
637         self.assertRaises(NoSuchRevision, repository.lookup_revision_id, 
638             "nonexisting")
639         self.assertEqual(("bloe", 1), 
640             repository.lookup_revision_id(
641                 repository.generate_revision_id(1, "bloe")))
642
643     def test_lookup_revision_id_invalid_uuid(self):
644         repos_url = self.make_client('d', 'dc')
645         repository = Repository.open("svn+%s" % repos_url)
646         self.assertRaises(NoSuchRevision, 
647             repository.lookup_revision_id, 
648                 generate_svn_revision_id("invaliduuid", 0, ""))
649         
650     def test_check(self):
651         repos_url = self.make_client('d', 'dc')
652         self.build_tree({'dc/foo': "data"})
653         self.client_add("dc/foo")
654         self.client_commit("dc", "My Message")
655         repository = Repository.open("svn+%s" % repos_url)
656         repository.check([
657             repository.generate_revision_id(0, ""), 
658             repository.generate_revision_id(1, "")])
659
660     def test_copy_contents_into(self):
661         repos_url = self.make_client('d', 'dc')
662         self.build_tree({'dc/foo/bla': "data"})
663         self.client_add("dc/foo")
664         self.client_commit("dc", "My Message")
665         self.build_tree({'dc/foo/blo': "data2", "dc/bar/foo": "data3", 'dc/foo/bla': "data"})
666         self.client_add("dc/foo/blo")
667         self.client_add("dc/bar")
668         self.client_commit("dc", "Second Message")
669         repository = Repository.open("svn+%s" % repos_url)
670
671         to_repos = BzrDir.create_repository("e")
672
673         repository.copy_content_into(to_repos, 
674                 repository.generate_revision_id(2, ""))
675
676         self.assertTrue(repository.has_revision(
677             repository.generate_revision_id(2, "")))
678         self.assertTrue(repository.has_revision(
679             repository.generate_revision_id(1, "")))
680         self.assertFalse(repository.has_revision(
681             generate_svn_revision_id(repository.uuid, 4, "")))
682
683     def test_is_shared(self):
684         repos_url = self.make_client('d', 'dc')
685         self.build_tree({'dc/foo/bla': "data"})
686         self.client_add("dc/foo")
687         self.client_commit("dc", "My Message")
688         repository = Repository.open("svn+%s" % repos_url)
689         self.assertTrue(repository.is_shared())
690
691     def test_revision_fileid_renames(self):
692         repos_url = self.make_client('d', 'dc')
693         self.build_tree({'dc/test': "data"})
694         self.client_add("dc/test")
695         self.client_set_prop("dc", "bzr:file-ids", "test\tbla\n")
696         self.client_commit("dc", "Msg")
697
698         repos = Repository.open(repos_url)
699         renames = repos.revision_fileid_renames(repos.generate_revision_id(1, ""))
700         self.assertEqual({"test": "bla"}, renames)
701
702     def test_fetch_fileid_renames(self):
703         repos_url = self.make_client('d', 'dc')
704         self.build_tree({'dc/test': "data"})
705         self.client_add("dc/test")
706         self.client_set_prop("dc", "bzr:file-ids", "test\tbla\n")
707         self.client_commit("dc", "Msg")
708
709         oldrepos = Repository.open(repos_url)
710         dir = BzrDir.create("f")
711         newrepos = dir.create_repository()
712         oldrepos.copy_content_into(newrepos)
713         self.assertEqual("bla", newrepos.get_inventory(
714             oldrepos.generate_revision_id(1, "")).path2id("test"))
715
716     def test_fetch_trunk1(self):
717         repos_url = self.make_client('d', 'dc')
718         self.build_tree({'dc/proj1/trunk/file': "data"})
719         self.client_add("dc/proj1")
720         self.client_commit("dc", "My Message")
721         oldrepos = Repository.open(repos_url)
722         oldrepos.set_branching_scheme(TrunkBranchingScheme(1))
723         dir = BzrDir.create("f")
724         newrepos = dir.create_repository()
725         oldrepos.copy_content_into(newrepos)
726
727     def test_fetch_special_char(self):
728         repos_url = self.make_client('d', 'dc')
729         self.build_tree({u'dc/trunk/f\x2cle': "data"})
730         self.client_add("dc/trunk")
731         self.client_commit("dc", "My Message")
732         oldrepos = Repository.open(repos_url)
733         oldrepos.set_branching_scheme(TrunkBranchingScheme(1))
734         dir = BzrDir.create("f")
735         newrepos = dir.create_repository()
736         oldrepos.copy_content_into(newrepos)
737
738     def test_fetch_delete(self):
739         repos_url = self.make_client('d', 'dc')
740         self.build_tree({'dc/foo/bla': "data"})
741         self.client_add("dc/foo")
742         self.client_commit("dc", "My Message")
743         oldrepos = Repository.open(repos_url)
744         dir = BzrDir.create("f")
745         newrepos = dir.create_repository()
746         oldrepos.copy_content_into(newrepos)
747         self.client_delete("dc/foo/bla")
748         self.client_commit("dc", "Second Message")
749         newrepos = Repository.open("f")
750         oldrepos.copy_content_into(newrepos)
751         self.assertTrue(oldrepos.has_revision(oldrepos.generate_revision_id(2, "")))
752
753     def test_fetch_local(self):
754         repos_url = self.make_client('d', 'dc')
755         self.build_tree({'dc/foo/bla': "data"})
756         self.client_add("dc/foo")
757         self.client_commit("dc", "My Message")
758         self.build_tree({'dc/foo/blo': "data2", "dc/bar/foo": "data3", 'dc/foo/bla': "data"})
759         self.client_add("dc/foo/blo")
760         self.client_add("dc/bar")
761         self.client_commit("dc", "Second Message")
762         oldrepos = Repository.open(repos_url)
763         dir = BzrDir.create("f")
764         newrepos = dir.create_repository()
765         oldrepos.copy_content_into(newrepos)
766         self.assertTrue(newrepos.has_revision(
767             oldrepos.generate_revision_id(1, "")))
768         self.assertTrue(newrepos.has_revision(
769             oldrepos.generate_revision_id(2, "")))
770         tree = newrepos.revision_tree(
771                 oldrepos.generate_revision_id(2, ""))
772         self.assertTrue(tree.has_filename("foo/bla"))
773         self.assertTrue(tree.has_filename("foo"))
774         self.assertEqual("data", tree.get_file_by_path("foo/bla").read())
775
776     def test_control_code_msg(self):
777         repos_url = self.make_client('d', 'dc')
778
779         self.build_tree({'dc/trunk': None})
780         self.client_add("dc/trunk")
781         self.client_commit("dc", "\x24")
782
783         self.build_tree({'dc/trunk/hosts': 'hej2'})
784         self.client_add("dc/trunk/hosts")
785         self.client_commit("dc", "bla\xfcbla") #2
786
787         self.build_tree({'dc/trunk/hosts': 'hej3'})
788         self.client_commit("dc", "a\x0cb") #3
789
790         self.build_tree({'dc/branches/foobranch/file': 'foohosts'})
791         self.client_add("dc/branches")
792         self.client_commit("dc", "foohosts") #4
793
794         oldrepos = Repository.open("svn+"+repos_url)
795         oldrepos.set_branching_scheme(TrunkBranchingScheme())
796         dir = BzrDir.create("f")
797         newrepos = dir.create_repository()
798         oldrepos.copy_content_into(newrepos)
799
800         self.assertTrue(newrepos.has_revision(
801             oldrepos.generate_revision_id(1, "trunk")))
802         self.assertTrue(newrepos.has_revision(
803             oldrepos.generate_revision_id(2, "trunk")))
804         self.assertTrue(newrepos.has_revision(
805             oldrepos.generate_revision_id(3, "trunk")))
806         self.assertTrue(newrepos.has_revision(
807             oldrepos.generate_revision_id(4, "branches/foobranch")))
808         self.assertFalse(newrepos.has_revision(
809             oldrepos.generate_revision_id(4, "trunk")))
810         self.assertFalse(newrepos.has_revision(
811             oldrepos.generate_revision_id(2, "")))
812
813         rev = newrepos.get_revision(oldrepos.generate_revision_id(1, "trunk"))
814         self.assertEqual("$", rev.message)
815
816         rev = newrepos.get_revision(
817             oldrepos.generate_revision_id(2, "trunk"))
818         self.assertEqual(u'bla\xfcbla', rev.message)
819
820         rev = newrepos.get_revision(oldrepos.generate_revision_id(3, "trunk"))
821         self.assertEqual(u"a\\x0cb", rev.message)
822
823     def test_fetch_replace(self):
824         repos_url = self.make_client('d', 'dc')
825         self.build_tree({'dc/bla': "data"})
826         self.client_add("dc/bla")
827         self.client_commit("dc", "My Message")
828         self.client_delete("dc/bla")
829         self.build_tree({'dc/bla': "data2"})
830         self.client_add("dc/bla")
831         self.client_commit("dc", "Second Message")
832         oldrepos = Repository.open("svn+"+repos_url)
833         dir = BzrDir.create("f")
834         newrepos = dir.create_repository()
835         oldrepos.copy_content_into(newrepos)
836         self.assertTrue(newrepos.has_revision(
837             oldrepos.generate_revision_id(1, "")))
838         self.assertTrue(newrepos.has_revision(
839             oldrepos.generate_revision_id(2, "")))
840         inv1 = newrepos.get_inventory(
841                 oldrepos.generate_revision_id(1, ""))
842         inv2 = newrepos.get_inventory(
843                 oldrepos.generate_revision_id(2, ""))
844         self.assertNotEqual(inv1.path2id("bla"), inv2.path2id("bla"))
845
846     def test_fetch_copy_subdir(self):
847         repos_url = self.make_client('d', 'dc')
848         self.build_tree({'dc/trunk/mydir/a': "data"})
849         self.client_add("dc/trunk")
850         self.client_commit("dc", "My Message")
851         self.build_tree({'dc/branches/tmp': None})
852         self.client_add("dc/branches")
853         self.client_commit("dc", "Second Message")
854         self.client_copy("dc/trunk/mydir", "dc/branches/tmp/abranch")
855         self.client_commit("dc", "Third Message")
856         oldrepos = Repository.open("svn+"+repos_url)
857         oldrepos.set_branching_scheme(TrunkBranchingScheme())
858         dir = BzrDir.create("f")
859         newrepos = dir.create_repository()
860         oldrepos.copy_content_into(newrepos)
861
862     def test_fetch_replace_nordic(self):
863         filename = os.path.join(self.test_dir, "dumpfile")
864         open(filename, 'w').write("""SVN-fs-dump-format-version: 2
865
866 UUID: 606c7b1f-987c-4826-b37d-eb556ceb87e1
867
868 Revision-number: 0
869 Prop-content-length: 56
870 Content-length: 56
871
872 K 8
873 svn:date
874 V 27
875 2006-12-26T00:04:55.850520Z
876 PROPS-END
877
878 Revision-number: 1
879 Prop-content-length: 103
880 Content-length: 103
881
882 K 7
883 svn:log
884 V 3
885 add
886 K 10
887 svn:author
888 V 6
889 jelmer
890 K 8
891 svn:date
892 V 27
893 2006-12-26T00:05:15.504335Z
894 PROPS-END
895
896 Node-path: x\xc3\xa1
897 Node-kind: dir
898 Node-action: add
899 Prop-content-length: 10
900 Content-length: 10
901
902 PROPS-END
903
904 Node-path: u\xc3\xa1
905 Node-path: bla
906 Node-kind: file
907 Node-action: add
908 Prop-content-length: 10
909 Text-content-length: 5
910 Text-content-md5: 49803c8f7913948eb3e30bae749ae6bd
911 Content-length: 15
912
913 PROPS-END
914 bloe
915
916
917 Revision-number: 2
918 Prop-content-length: 105
919 Content-length: 105
920
921 K 7
922 svn:log
923 V 5
924 readd
925 K 10
926 svn:author
927 V 6
928 jelmer
929 K 8
930 svn:date
931 V 27
932 2006-12-26T00:05:43.584249Z
933 PROPS-END
934
935 Node-path: x\xc3\xa1
936 Node-action: delete
937
938 """)
939         os.mkdir("old")
940
941         load_dumpfile("dumpfile", "old")
942         oldrepos = Repository.open("old")
943         dir = BzrDir.create("f")
944         newrepos = dir.create_repository()
945         oldrepos.copy_content_into(newrepos)
946         self.assertTrue(newrepos.has_revision(
947             oldrepos.generate_revision_id(1, "")))
948         inv1 = newrepos.get_inventory(
949                 oldrepos.generate_revision_id(1, ""))
950         self.assertTrue(inv1.has_filename(u"x\xe1"))
951
952     def test_fetch_replace_with_subreplace(self):
953         filename = os.path.join(self.test_dir, "dumpfile")
954         open(filename, 'w').write("""SVN-fs-dump-format-version: 2
955
956 UUID: 606c7b1f-987c-4826-b37d-eb456ceb87e1
957
958 Revision-number: 0
959 Prop-content-length: 56
960 Content-length: 56
961
962 K 8
963 svn:date
964 V 27
965 2006-12-26T00:04:55.850520Z
966 PROPS-END
967
968 Revision-number: 1
969 Prop-content-length: 103
970 Content-length: 103
971
972 K 7
973 svn:log
974 V 3
975 add
976 K 10
977 svn:author
978 V 6
979 jelmer
980 K 8
981 svn:date
982 V 27
983 2006-12-26T00:05:15.504335Z
984 PROPS-END
985
986 Node-path: x
987 Node-kind: dir
988 Node-action: add
989 Prop-content-length: 10
990 Content-length: 10
991
992 PROPS-END
993
994 Node-path: x/t
995 Node-kind: dir
996 Node-action: add
997 Prop-content-length: 10
998 Content-length: 10
999
1000 PROPS-END
1001
1002 Node-path: u
1003 Node-kind: dir
1004 Node-action: add
1005 Prop-content-length: 10
1006 Content-length: 10
1007
1008 PROPS-END
1009
1010 Revision-number: 2
1011 Prop-content-length: 105
1012 Content-length: 105
1013
1014 K 7
1015 svn:log
1016 V 5
1017 readd
1018 K 10
1019 svn:author
1020 V 6
1021 jelmer
1022 K 8
1023 svn:date
1024 V 27
1025 2006-12-26T00:05:43.584249Z
1026 PROPS-END
1027
1028 Node-path: x
1029 Node-action: delete
1030
1031 Node-path: x
1032 Node-kind: dir
1033 Node-action: add
1034 Prop-content-length: 10
1035 Content-length: 10
1036
1037 PROPS-END
1038
1039
1040 Revision-number: 3
1041 Prop-content-length: 108
1042 Content-length: 108
1043
1044 K 7
1045 svn:log
1046 V 8
1047 Replace
1048
1049 K 10
1050 svn:author
1051 V 6
1052 jelmer
1053 K 8
1054 svn:date
1055 V 27
1056 2006-12-25T04:30:06.383777Z
1057 PROPS-END
1058
1059 Node-path: x
1060 Node-action: delete
1061
1062 Node-path: y
1063 Node-kind: dir
1064 Node-action: add
1065 Node-copyfrom-rev: 1
1066 Node-copyfrom-path: x
1067
1068 Node-path: y/t
1069 Node-action: delete
1070
1071 Node-path: y/t
1072 Node-kind: dir
1073 Node-action: add
1074 Node-copyfrom-rev: 1
1075 Node-copyfrom-path: u
1076
1077
1078 """)
1079         os.mkdir("old")
1080
1081         load_dumpfile("dumpfile", "old")
1082         oldrepos = Repository.open("old")
1083         dir = BzrDir.create("f")
1084         newrepos = dir.create_repository()
1085         oldrepos.copy_content_into(newrepos)
1086         self.assertTrue(newrepos.has_revision(
1087             oldrepos.generate_revision_id(1, "")))
1088         self.assertTrue(newrepos.has_revision(
1089             oldrepos.generate_revision_id(3, "")))
1090         inv1 = newrepos.get_inventory(
1091                 oldrepos.generate_revision_id(1, ""))
1092         inv2 = newrepos.get_inventory(
1093                 oldrepos.generate_revision_id(3, ""))
1094
1095     def test_fetch_replace_self(self):
1096         filename = os.path.join(self.test_dir, "dumpfile")
1097         open(filename, 'w').write("""SVN-fs-dump-format-version: 2
1098
1099 UUID: 6dcc86fc-ac21-4df7-a3a3-87616123c853
1100
1101 Revision-number: 0
1102 Prop-content-length: 56
1103 Content-length: 56
1104
1105 K 8
1106 svn:date
1107 V 27
1108 2006-12-25T04:27:54.633666Z
1109 PROPS-END
1110
1111 Revision-number: 1
1112 Prop-content-length: 108
1113 Content-length: 108
1114
1115 K 7
1116 svn:log
1117 V 8
1118 Add dir
1119
1120 K 10
1121 svn:author
1122 V 6
1123 jelmer
1124 K 8
1125 svn:date
1126 V 27
1127 2006-12-25T04:28:17.503039Z
1128 PROPS-END
1129
1130 Node-path: bla
1131 Node-kind: dir
1132 Node-action: add
1133 Prop-content-length: 10
1134 Content-length: 10
1135
1136 PROPS-END
1137
1138
1139 Revision-number: 2
1140 Prop-content-length: 117
1141 Content-length: 117
1142
1143 K 7
1144 svn:log
1145 V 16
1146 Add another dir
1147
1148 K 10
1149 svn:author
1150 V 6
1151 jelmer
1152 K 8
1153 svn:date
1154 V 27
1155 2006-12-25T04:28:30.160663Z
1156 PROPS-END
1157
1158 Node-path: blie
1159 Node-kind: dir
1160 Node-action: add
1161 Prop-content-length: 10
1162 Content-length: 10
1163
1164 PROPS-END
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 Copy
1175
1176 K 10
1177 svn:author
1178 V 6
1179 jelmer
1180 K 8
1181 svn:date
1182 V 27
1183 2006-12-25T04:28:44.996894Z
1184 PROPS-END
1185
1186 Node-path: bloe
1187 Node-kind: dir
1188 Node-action: add
1189 Node-copyfrom-rev: 1
1190 Node-copyfrom-path: bla
1191
1192
1193 Revision-number: 4
1194 Prop-content-length: 108
1195 Content-length: 108
1196
1197 K 7
1198 svn:log
1199 V 8
1200 Replace
1201
1202 K 10
1203 svn:author
1204 V 6
1205 jelmer
1206 K 8
1207 svn:date
1208 V 27
1209 2006-12-25T04:30:06.383777Z
1210 PROPS-END
1211
1212 Node-path: bla
1213 Node-action: delete
1214
1215
1216 Node-path: bla
1217 Node-kind: dir
1218 Node-action: add
1219 Node-copyfrom-rev: 2
1220 Node-copyfrom-path: bla
1221
1222
1223 """)
1224         os.mkdir("old")
1225
1226         load_dumpfile("dumpfile", "old")
1227         oldrepos = Repository.open("old")
1228         dir = BzrDir.create("f")
1229         newrepos = dir.create_repository()
1230         oldrepos.copy_content_into(newrepos)
1231         self.assertTrue(newrepos.has_revision(
1232             oldrepos.generate_revision_id(1, "")))
1233         self.assertTrue(newrepos.has_revision(
1234             oldrepos.generate_revision_id(3, "")))
1235         inv1 = newrepos.get_inventory(
1236                 oldrepos.generate_revision_id(1, ""))
1237         inv2 = newrepos.get_inventory(
1238                 oldrepos.generate_revision_id(3, ""))
1239         self.assertEqual(inv1.path2id("bla"), inv2.path2id("bla"))
1240
1241     def test_fetch_replace_backup(self):
1242         filename = os.path.join(self.test_dir, "dumpfile")
1243         open(filename, 'w').write("""SVN-fs-dump-format-version: 2
1244
1245 UUID: 6dcc86fc-ac21-4df7-a3a3-87616123c853
1246
1247 Revision-number: 0
1248 Prop-content-length: 56
1249 Content-length: 56
1250
1251 K 8
1252 svn:date
1253 V 27
1254 2006-12-25T04:27:54.633666Z
1255 PROPS-END
1256
1257 Revision-number: 1
1258 Prop-content-length: 108
1259 Content-length: 108
1260
1261 K 7
1262 svn:log
1263 V 8
1264 Add dir
1265
1266 K 10
1267 svn:author
1268 V 6
1269 jelmer
1270 K 8
1271 svn:date
1272 V 27
1273 2006-12-25T04:28:17.503039Z
1274 PROPS-END
1275
1276 Node-path: bla
1277 Node-kind: dir
1278 Node-action: add
1279 Prop-content-length: 10
1280 Content-length: 10
1281
1282 PROPS-END
1283
1284
1285 Revision-number: 2
1286 Prop-content-length: 117
1287 Content-length: 117
1288
1289 K 7
1290 svn:log
1291 V 16
1292 Add another dir
1293
1294 K 10
1295 svn:author
1296 V 6
1297 jelmer
1298 K 8
1299 svn:date
1300 V 27
1301 2006-12-25T04:28:30.160663Z
1302 PROPS-END
1303
1304 Node-path: blie
1305 Node-kind: dir
1306 Node-action: add
1307 Prop-content-length: 10
1308 Content-length: 10
1309
1310 PROPS-END
1311
1312
1313 Revision-number: 3
1314 Prop-content-length: 105
1315 Content-length: 105
1316
1317 K 7
1318 svn:log
1319 V 5
1320 Copy
1321
1322 K 10
1323 svn:author
1324 V 6
1325 jelmer
1326 K 8
1327 svn:date
1328 V 27
1329 2006-12-25T04:28:44.996894Z
1330 PROPS-END
1331
1332 Node-path: bloe
1333 Node-kind: dir
1334 Node-action: add
1335 Node-copyfrom-rev: 1
1336 Node-copyfrom-path: bla
1337
1338
1339 Revision-number: 4
1340 Prop-content-length: 112
1341 Content-length: 112
1342
1343 K 7
1344 svn:log
1345 V 11
1346 Change bla
1347
1348 K 10
1349 svn:author
1350 V 6
1351 jelmer
1352 K 8
1353 svn:date
1354 V 27
1355 2006-12-25T23:51:09.678679Z
1356 PROPS-END
1357
1358 Node-path: bla
1359 Node-kind: dir
1360 Node-action: change
1361 Prop-content-length: 28
1362 Content-length: 28
1363
1364 K 3
1365 foo
1366 V 5
1367 bloe
1368
1369 PROPS-END
1370
1371
1372 Revision-number: 5
1373 Prop-content-length: 108
1374 Content-length: 108
1375
1376 K 7
1377 svn:log
1378 V 8
1379 Replace
1380
1381 K 10
1382 svn:author
1383 V 6
1384 jelmer
1385 K 8
1386 svn:date
1387 V 27
1388 2006-12-25T04:30:06.383777Z
1389 PROPS-END
1390
1391 Node-path: bla
1392 Node-action: delete
1393
1394
1395 Node-path: bla
1396 Node-kind: dir
1397 Node-action: add
1398 Node-copyfrom-rev: 1
1399 Node-copyfrom-path: bla
1400
1401
1402 """)
1403         os.mkdir("old")
1404
1405         load_dumpfile("dumpfile", "old")
1406         oldrepos = Repository.open("old")
1407         dir = BzrDir.create("f")
1408         newrepos = dir.create_repository()
1409         oldrepos.copy_content_into(newrepos)
1410         self.assertTrue(newrepos.has_revision(
1411             oldrepos.generate_revision_id(1, "")))
1412         self.assertTrue(newrepos.has_revision(
1413             oldrepos.generate_revision_id(3, "")))
1414         inv1 = newrepos.get_inventory(
1415                 oldrepos.generate_revision_id(1, ""))
1416         inv2 = newrepos.get_inventory(
1417                 oldrepos.generate_revision_id(3, ""))
1418         self.assertEqual(inv1.path2id("bla"), inv2.path2id("bla"))
1419
1420     def test_fetch_replace_unrelated(self):
1421         filename = os.path.join(self.test_dir, "dumpfile")
1422         open(filename, 'w').write("""SVN-fs-dump-format-version: 2
1423
1424 UUID: 606c7b1f-987c-4826-b37d-eb456ceb87e1
1425
1426 Revision-number: 0
1427 Prop-content-length: 56
1428 Content-length: 56
1429
1430 K 8
1431 svn:date
1432 V 27
1433 2006-12-26T00:04:55.850520Z
1434 PROPS-END
1435
1436 Revision-number: 1
1437 Prop-content-length: 103
1438 Content-length: 103
1439
1440 K 7
1441 svn:log
1442 V 3
1443 add
1444 K 10
1445 svn:author
1446 V 6
1447 jelmer
1448 K 8
1449 svn:date
1450 V 27
1451 2006-12-26T00:05:15.504335Z
1452 PROPS-END
1453
1454 Node-path: x
1455 Node-kind: dir
1456 Node-action: add
1457 Prop-content-length: 10
1458 Content-length: 10
1459
1460 PROPS-END
1461
1462
1463 Revision-number: 2
1464 Prop-content-length: 102
1465 Content-length: 102
1466
1467 K 7
1468 svn:log
1469 V 2
1470 rm
1471 K 10
1472 svn:author
1473 V 6
1474 jelmer
1475 K 8
1476 svn:date
1477 V 27
1478 2006-12-26T00:05:30.775369Z
1479 PROPS-END
1480
1481 Node-path: x
1482 Node-action: delete
1483
1484
1485 Revision-number: 3
1486 Prop-content-length: 105
1487 Content-length: 105
1488
1489 K 7
1490 svn:log
1491 V 5
1492 readd
1493 K 10
1494 svn:author
1495 V 6
1496 jelmer
1497 K 8
1498 svn:date
1499 V 27
1500 2006-12-26T00:05:43.584249Z
1501 PROPS-END
1502
1503 Node-path: x
1504 Node-kind: dir
1505 Node-action: add
1506 Prop-content-length: 10
1507 Content-length: 10
1508
1509 PROPS-END
1510
1511
1512 Revision-number: 4
1513 Prop-content-length: 108
1514 Content-length: 108
1515
1516 K 7
1517 svn:log
1518 V 8
1519 Replace
1520
1521 K 10
1522 svn:author
1523 V 6
1524 jelmer
1525 K 8
1526 svn:date
1527 V 27
1528 2006-12-25T04:30:06.383777Z
1529 PROPS-END
1530
1531 Node-path: x
1532 Node-action: delete
1533
1534
1535 Node-path: x
1536 Node-kind: dir
1537 Node-action: add
1538 Node-copyfrom-rev: 1
1539 Node-copyfrom-path: x
1540
1541                 
1542 """)
1543         os.mkdir("old")
1544
1545         load_dumpfile("dumpfile", "old")
1546         oldrepos = Repository.open("old")
1547         dir = BzrDir.create("f")
1548         newrepos = dir.create_repository()
1549         oldrepos.copy_content_into(newrepos)
1550         self.assertTrue(newrepos.has_revision(
1551             oldrepos.generate_revision_id(1, "")))
1552         self.assertTrue(newrepos.has_revision(
1553             oldrepos.generate_revision_id(4, "")))
1554         inv1 = newrepos.get_inventory(
1555                 oldrepos.generate_revision_id(1, ""))
1556         inv2 = newrepos.get_inventory(
1557                 oldrepos.generate_revision_id(4, ""))
1558         self.assertNotEqual(inv1.path2id("x"), inv2.path2id("x"))
1559
1560     def test_fetch_replace_related(self):
1561         filename = os.path.join(self.test_dir, "dumpfile")
1562         open(filename, 'w').write("""SVN-fs-dump-format-version: 2
1563
1564 UUID: 606c7b1f-987c-4826-b37d-eb456ceb87e1
1565
1566 Revision-number: 0
1567 Prop-content-length: 56
1568 Content-length: 56
1569
1570 K 8
1571 svn:date
1572 V 27
1573 2006-12-26T00:04:55.850520Z
1574 PROPS-END
1575
1576 Revision-number: 1
1577 Prop-content-length: 103
1578 Content-length: 103
1579
1580 K 7
1581 svn:log
1582 V 3
1583 add
1584 K 10
1585 svn:author
1586 V 6
1587 jelmer
1588 K 8
1589 svn:date
1590 V 27
1591 2006-12-26T00:05:15.504335Z
1592 PROPS-END
1593
1594 Node-path: x
1595 Node-kind: dir
1596 Node-action: add
1597 Prop-content-length: 10
1598 Content-length: 10
1599
1600 PROPS-END
1601
1602
1603 Revision-number: 2
1604 Prop-content-length: 102
1605 Content-length: 102
1606
1607 K 7
1608 svn:log
1609 V 2
1610 rm
1611 K 10
1612 svn:author
1613 V 6
1614 jelmer
1615 K 8
1616 svn:date
1617 V 27
1618 2006-12-26T00:05:30.775369Z
1619 PROPS-END
1620
1621 Node-path: x
1622 Node-action: delete
1623
1624
1625 Revision-number: 3
1626 Prop-content-length: 105
1627 Content-length: 105
1628
1629 K 7
1630 svn:log
1631 V 5
1632 readd
1633 K 10
1634 svn:author
1635 V 6
1636 jelmer
1637 K 8
1638 svn:date
1639 V 27
1640 2006-12-26T00:05:43.584249Z
1641 PROPS-END
1642
1643 Node-path: y
1644 Node-kind: dir
1645 Node-action: add
1646 Node-copyfrom-rev: 1
1647 Node-copyfrom-path: x
1648 Prop-content-length: 10
1649 Content-length: 10
1650
1651 PROPS-END
1652
1653
1654 Revision-number: 4
1655 Prop-content-length: 108
1656 Content-length: 108
1657
1658 K 7
1659 svn:log
1660 V 8
1661 Replace
1662
1663 K 10
1664 svn:author
1665 V 6
1666 jelmer
1667 K 8
1668 svn:date
1669 V 27
1670 2006-12-25T04:30:06.383777Z
1671 PROPS-END
1672
1673 Node-path: y
1674 Node-action: delete
1675
1676
1677 Revision-number: 5
1678 Prop-content-length: 108
1679 Content-length: 108
1680
1681 K 7
1682 svn:log
1683 V 8
1684 Replace
1685
1686 K 10
1687 svn:author
1688 V 6
1689 jelmer
1690 K 8
1691 svn:date
1692 V 27
1693 2006-12-25T04:30:06.383777Z
1694 PROPS-END
1695
1696
1697 Node-path: y
1698 Node-kind: dir
1699 Node-action: add
1700 Node-copyfrom-rev: 1
1701 Node-copyfrom-path: x
1702
1703
1704 """)
1705         os.mkdir("old")
1706
1707         load_dumpfile("dumpfile", "old")
1708         oldrepos = Repository.open("old")
1709         dir = BzrDir.create("f")
1710         newrepos = dir.create_repository()
1711         oldrepos.copy_content_into(newrepos)
1712         self.assertTrue(newrepos.has_revision(
1713             oldrepos.generate_revision_id(1, "")))
1714         self.assertTrue(newrepos.has_revision(
1715             oldrepos.generate_revision_id(5, "")))
1716         inv1 = newrepos.get_inventory(
1717                 oldrepos.generate_revision_id(1, ""))
1718         inv2 = newrepos.get_inventory(
1719                 oldrepos.generate_revision_id(5, ""))
1720         self.assertNotEqual(inv1.path2id("y"), inv2.path2id("y"))
1721
1722     def test_fetch_dir_upgrade(self):
1723         repos_url = self.make_client('d', 'dc')
1724
1725         self.build_tree({'dc/trunk/lib/file': 'data'})
1726         self.client_add("dc/trunk")
1727         self.client_commit("dc", "trunk data")
1728
1729         self.build_tree({'dc/branches': None})
1730         self.client_add("dc/branches")
1731         self.client_copy("dc/trunk/lib", "dc/branches/mybranch")
1732         self.client_commit("dc", "split out lib")
1733
1734         oldrepos = Repository.open(repos_url)
1735         oldrepos.set_branching_scheme(TrunkBranchingScheme())
1736         dir = BzrDir.create("f")
1737         newrepos = dir.create_repository()
1738         oldrepos.copy_content_into(newrepos)
1739
1740         branch = Branch.open("%s/branches/mybranch" % repos_url)
1741         self.assertEqual([oldrepos.generate_revision_id(2, "branches/mybranch")], 
1742                          branch.revision_history())
1743
1744     def test_fetch_file_from_non_branch(self):
1745         repos_url = self.make_client('d', 'dc')
1746
1747         self.build_tree({'dc/old-trunk/lib/file': 'data'})
1748         self.client_add("dc/old-trunk")
1749         self.client_commit("dc", "trunk data")
1750
1751         self.build_tree({'dc/trunk/lib': None})
1752         self.client_add("dc/trunk")
1753         self.client_copy("dc/old-trunk/lib/file", "dc/trunk/lib/file")
1754         self.client_commit("dc", "revive old trunk")
1755
1756         oldrepos = Repository.open(repos_url)
1757         oldrepos.set_branching_scheme(TrunkBranchingScheme())
1758         dir = BzrDir.create("f")
1759         newrepos = dir.create_repository()
1760         oldrepos.copy_content_into(newrepos)
1761
1762         branch = Branch.open("%s/trunk" % repos_url)
1763         self.assertEqual([oldrepos.generate_revision_id(2, "trunk")], 
1764                          branch.revision_history())
1765
1766     def test_fetch_dir_from_non_branch(self):
1767         repos_url = self.make_client('d', 'dc')
1768
1769         self.build_tree({'dc/old-trunk/lib/file': 'data'})
1770         self.client_add("dc/old-trunk")
1771         self.client_commit("dc", "trunk data")
1772
1773         self.build_tree({'dc/trunk': None})
1774         self.client_add("dc/trunk")
1775         self.client_copy("dc/old-trunk/lib", "dc/trunk")
1776         self.client_commit("dc", "revive old trunk")
1777
1778         oldrepos = Repository.open(repos_url)
1779         oldrepos.set_branching_scheme(TrunkBranchingScheme())
1780         dir = BzrDir.create("f")
1781         newrepos = dir.create_repository()
1782         oldrepos.copy_content_into(newrepos)
1783
1784         branch = Branch.open("%s/trunk" % repos_url)
1785         self.assertEqual([oldrepos.generate_revision_id(2, "trunk")],
1786                          branch.revision_history())
1787
1788     def test_fetch_from_non_branch(self):
1789         repos_url = self.make_client('d', 'dc')
1790
1791         self.build_tree({'dc/old-trunk/lib/file': 'data'})
1792         self.client_add("dc/old-trunk")
1793         self.client_commit("dc", "trunk data")
1794
1795         self.client_copy("dc/old-trunk", "dc/trunk")
1796         self.client_commit("dc", "revive old trunk")
1797
1798         oldrepos = Repository.open(repos_url)
1799         oldrepos.set_branching_scheme(TrunkBranchingScheme())
1800         dir = BzrDir.create("f")
1801         newrepos = dir.create_repository()
1802         oldrepos.copy_content_into(newrepos)
1803
1804         branch = Branch.open("%s/trunk" % repos_url)
1805         self.assertEqual([oldrepos.generate_revision_id(2, "trunk")],
1806                          branch.revision_history())
1807
1808
1809
1810     def test_fetch_branch_downgrade(self):
1811         repos_url = self.make_client('d', 'dc')
1812
1813         self.build_tree({'dc/trunk/file': 'data'})
1814         self.client_add("dc/trunk")
1815         self.client_commit("dc", "trunk data")
1816
1817         self.build_tree({'dc/branches/mybranch': None})
1818         self.client_add("dc/branches")
1819         self.client_copy("dc/trunk", "dc/branches/mybranch/lib")
1820         self.client_commit("dc", "split out lib")
1821
1822         oldrepos = Repository.open(repos_url)
1823         oldrepos.set_branching_scheme(TrunkBranchingScheme())
1824         dir = BzrDir.create("f")
1825         newrepos = dir.create_repository()
1826         oldrepos.copy_content_into(newrepos)
1827
1828     def test_fetch_all(self):
1829         repos_url = self.make_client('d', 'dc')
1830
1831         self.build_tree({'dc/trunk': None, 
1832                          'dc/trunk/hosts': 'hej1'})
1833         self.client_add("dc/trunk")
1834         self.client_commit("dc", "created trunk and added hosts") #1
1835
1836         self.build_tree({'dc/trunk/hosts': 'hej2'})
1837         self.client_commit("dc", "rev 2") #2
1838
1839         self.build_tree({'dc/trunk/hosts': 'hej3'})
1840         self.client_commit("dc", "rev 3") #3
1841
1842         self.build_tree({'dc/branches/foobranch/file': 'foohosts'})
1843         self.client_add("dc/branches")
1844         self.client_commit("dc", "foohosts") #4
1845
1846         oldrepos = Repository.open(repos_url)
1847         oldrepos.set_branching_scheme(TrunkBranchingScheme())
1848         dir = BzrDir.create("f")
1849         newrepos = dir.create_repository()
1850         oldrepos.copy_content_into(newrepos)
1851
1852         self.assertTrue(newrepos.has_revision(
1853             oldrepos.generate_revision_id(1, "trunk")))
1854         self.assertTrue(newrepos.has_revision(
1855             oldrepos.generate_revision_id(2, "trunk")))
1856         self.assertTrue(newrepos.has_revision(
1857             oldrepos.generate_revision_id(3, "trunk")))
1858         self.assertTrue(newrepos.has_revision(
1859             oldrepos.generate_revision_id(4, "branches/foobranch")))
1860         self.assertFalse(newrepos.has_revision(
1861             oldrepos.generate_revision_id(4, "trunk")))
1862         self.assertFalse(newrepos.has_revision(
1863             oldrepos.generate_revision_id(2, "")))
1864
1865     def test_fetch_copy_root_id_kept(self):
1866         repos_url = self.make_client('d', 'dc')
1867
1868         self.build_tree({'dc/trunk': None, 
1869                          'dc/trunk/hosts': 'hej1'})
1870         self.client_add("dc/trunk")
1871         self.client_commit("dc", "created trunk and added hosts") #1
1872
1873         self.build_tree({'dc/branches': None})
1874         self.client_add("dc/branches")
1875         self.client_commit("dc", "added branches") #2
1876
1877         self.client_copy("dc/trunk", "dc/branches/foobranch")
1878         self.client_commit("dc", "added branch foobranch") #3
1879
1880         repos = format.SvnRemoteAccess(SvnRaTransport("svn+"+repos_url), format.SvnFormat(), 
1881                                    TrunkBranchingScheme()).find_repository()
1882
1883         tree = repos.revision_tree(
1884              repos.generate_revision_id(3, "branches/foobranch"))
1885
1886         self.assertEqual(generate_svn_file_id(repos.uuid, 1, "trunk", ""), tree.inventory.root.file_id)
1887
1888     def test_fetch_odd(self):
1889         repos_url = self.make_client('d', 'dc')
1890
1891         self.build_tree({'dc/trunk': None, 
1892                          'dc/trunk/hosts': 'hej1'})
1893         self.client_add("dc/trunk")
1894         self.client_commit("dc", "created trunk and added hosts") #1
1895
1896         self.build_tree({'dc/trunk/hosts': 'hej2'})
1897         self.client_commit("dc", "rev 2") #2
1898
1899         self.build_tree({'dc/trunk/hosts': 'hej3'})
1900         self.client_commit("dc", "rev 3") #3
1901
1902         self.build_tree({'dc/branches': None})
1903         self.client_add("dc/branches")
1904         self.client_commit("dc", "added branches") #4
1905
1906         self.client_copy("dc/trunk", "dc/branches/foobranch")
1907         self.client_commit("dc", "added branch foobranch") #5
1908
1909         self.build_tree({'dc/branches/foobranch/hosts': 'foohosts'})
1910         self.client_commit("dc", "foohosts") #6
1911
1912         repos = format.SvnRemoteAccess(SvnRaTransport("svn+"+repos_url), format.SvnFormat(), 
1913                                    TrunkBranchingScheme()).find_repository()
1914
1915         tree = repos.revision_tree(
1916              repos.generate_revision_id(6, "branches/foobranch"))
1917
1918     def test_fetch_consistent(self):
1919         repos_url = self.make_client('d', 'dc')
1920         self.build_tree({'dc/bla': "data"})
1921         self.client_add("dc/bla")
1922         self.client_set_prop("dc/bla", "svn:executable", "*")
1923         self.client_commit("dc", "My Message")
1924         oldrepos = Repository.open("svn+"+repos_url)
1925         dir1 = BzrDir.create("f")
1926         dir2 = BzrDir.create("g")
1927         newrepos1 = dir1.create_repository()
1928         newrepos2 = dir2.create_repository()
1929         oldrepos.copy_content_into(newrepos1)
1930         oldrepos.copy_content_into(newrepos2)
1931         inv1 = newrepos1.get_inventory(
1932                 oldrepos.generate_revision_id(1, ""))
1933         inv2 = newrepos2.get_inventory(
1934                 oldrepos.generate_revision_id(1, ""))
1935         self.assertEqual(inv1, inv2)
1936
1937     def test_fetch_executable(self):
1938         repos_url = self.make_client('d', 'dc')
1939         self.build_tree({'dc/bla': "data", 'dc/blie': "data2"})
1940         self.client_add("dc/bla")
1941         self.client_add("dc/blie")
1942         self.client_set_prop("dc/bla", "svn:executable", "*")
1943         self.client_set_prop("dc/blie", "svn:executable", "")
1944         self.client_commit("dc", "My Message")
1945         oldrepos = Repository.open("svn+"+repos_url)
1946         dir = BzrDir.create("f")
1947         newrepos = dir.create_repository()
1948         oldrepos.copy_content_into(newrepos)
1949         self.assertTrue(newrepos.has_revision(
1950             oldrepos.generate_revision_id(1, "")))
1951         inv1 = newrepos.get_inventory(
1952                 oldrepos.generate_revision_id(1, ""))
1953         self.assertTrue(inv1[inv1.path2id("bla")].executable)
1954         self.assertTrue(inv1[inv1.path2id("blie")].executable)
1955
1956     def test_fetch_symlink(self):
1957         repos_url = self.make_client('d', 'dc')
1958         self.build_tree({'dc/bla': "data"})
1959         os.symlink('bla', 'dc/mylink')
1960         self.client_add("dc/bla")
1961         self.client_add("dc/mylink")
1962         self.client_commit("dc", "My Message")
1963         oldrepos = Repository.open("svn+"+repos_url)
1964         dir = BzrDir.create("f")
1965         newrepos = dir.create_repository()
1966         oldrepos.copy_content_into(newrepos)
1967         self.assertTrue(newrepos.has_revision(
1968             oldrepos.generate_revision_id(1, "")))
1969         inv1 = newrepos.get_inventory(
1970                 oldrepos.generate_revision_id(1, ""))
1971         self.assertEqual('symlink', inv1[inv1.path2id("mylink")].kind)
1972         self.assertEqual('bla', inv1[inv1.path2id("mylink")].symlink_target)
1973
1974
1975     def test_fetch_executable_separate(self):
1976         repos_url = self.make_client('d', 'dc')
1977         self.build_tree({'dc/bla': "data"})
1978         self.client_add("dc/bla")
1979         self.client_commit("dc", "My Message")
1980         self.client_set_prop("dc/bla", "svn:executable", "*")
1981         self.client_commit("dc", "Make executable")
1982         oldrepos = Repository.open("svn+"+repos_url)
1983         dir = BzrDir.create("f")
1984         newrepos = dir.create_repository()
1985         oldrepos.copy_content_into(newrepos)
1986         self.assertTrue(newrepos.has_revision(
1987             oldrepos.generate_revision_id(1, "")))
1988         inv1 = newrepos.get_inventory(
1989                 oldrepos.generate_revision_id(1, ""))
1990         self.assertFalse(inv1[inv1.path2id("bla")].executable)
1991         inv2 = newrepos.get_inventory(
1992                 oldrepos.generate_revision_id(2, ""))
1993         self.assertTrue(inv2[inv2.path2id("bla")].executable)
1994         self.assertEqual(oldrepos.generate_revision_id(2, ""), 
1995                          inv2[inv2.path2id("bla")].revision)
1996
1997     def test_fetch_ghosts(self):
1998         repos_url = self.make_client('d', 'dc')
1999         self.build_tree({'dc/bla': "data"})
2000         self.client_add("dc/bla")
2001         self.client_set_prop("dc", "bzr:merge", "aghost\n")
2002         self.client_commit("dc", "My Message")
2003         oldrepos = Repository.open("svn+"+repos_url)
2004         dir = BzrDir.create("f")
2005         newrepos = dir.create_repository()
2006         oldrepos.copy_content_into(newrepos)
2007
2008         rev = newrepos.get_revision(oldrepos.generate_revision_id(1, ""))
2009         self.assertTrue("aghost" in rev.parent_ids)
2010
2011     def test_fetch_invalid_ghosts(self):
2012         repos_url = self.make_client('d', 'dc')
2013         self.build_tree({'dc/bla': "data"})
2014         self.client_add("dc/bla")
2015         self.client_set_prop("dc", "bzr:merge", "a ghost\n")
2016         self.client_commit("dc", "My Message")
2017         oldrepos = Repository.open("svn+"+repos_url)
2018         dir = BzrDir.create("f")
2019         newrepos = dir.create_repository()
2020         oldrepos.copy_content_into(newrepos)
2021
2022         rev = newrepos.get_revision(oldrepos.generate_revision_id(1, ""))
2023         self.assertEqual([oldrepos.generate_revision_id(0, "")], rev.parent_ids)
2024
2025     def test_set_branching_scheme(self):
2026         repos_url = self.make_client('d', 'dc')
2027         repos = Repository.open(repos_url)
2028         repos.set_branching_scheme(NoBranchingScheme())
2029
2030     def test_mainline_revision_parent_null(self):
2031         repos_url = self.make_client('d', 'dc')
2032         repos = Repository.open(repos_url)
2033         repos.set_branching_scheme(NoBranchingScheme())
2034         self.assertEquals(None, repos._mainline_revision_parent("", 0))
2035
2036     def test_mainline_revision_parent_first(self):
2037         repos_url = self.make_client('d', 'dc')
2038         repos = Repository.open(repos_url)
2039         repos.set_branching_scheme(NoBranchingScheme())
2040         self.build_tree({'dc/adir/afile': "data"})
2041         self.client_add("dc/adir")
2042         self.client_commit("dc", "Initial commit")
2043         self.assertEquals(repos.generate_revision_id(0, ""), \
2044                 repos._mainline_revision_parent("", 1))
2045
2046     def test_mainline_revision_parent_simple(self):
2047         repos_url = self.make_client('d', 'dc')
2048         self.build_tree({'dc/trunk/adir/afile': "data", 
2049                          'dc/trunk/adir/stationary': None,
2050                          'dc/branches/abranch': None})
2051         self.client_add("dc/trunk")
2052         self.client_add("dc/branches")
2053         self.client_commit("dc", "Initial commit")
2054         self.build_tree({'dc/trunk/adir/afile': "bla"})
2055         self.client_commit("dc", "Incremental commit")
2056         repos = Repository.open(repos_url)
2057         repos.set_branching_scheme(TrunkBranchingScheme())
2058         self.assertEquals(repos.generate_revision_id(1, "trunk"), \
2059                 repos._mainline_revision_parent("trunk", 2))
2060
2061     def test_mainline_revision_parent_copied(self):
2062         repos_url = self.make_client('d', 'dc')
2063         self.build_tree({'dc/py/trunk/adir/afile': "data", 
2064                          'dc/py/trunk/adir/stationary': None})
2065         self.client_add("dc/py")
2066         self.client_commit("dc", "Initial commit")
2067         self.client_copy("dc/py", "dc/de")
2068         self.client_commit("dc", "Incremental commit")
2069         self.build_tree({'dc/de/trunk/adir/afile': "bla"})
2070         self.client_commit("dc", "Change de")
2071         repos = Repository.open(repos_url)
2072         repos.set_branching_scheme(TrunkBranchingScheme(1))
2073         self.assertEquals(repos.generate_revision_id(1, "py/trunk"), \
2074                 repos._mainline_revision_parent("de/trunk", 3))
2075
2076     def test_mainline_revision_copied(self):
2077         repos_url = self.make_client('d', 'dc')
2078         self.build_tree({'dc/py/trunk/adir/afile': "data", 
2079                          'dc/py/trunk/adir/stationary': None})
2080         self.client_add("dc/py")
2081         self.client_commit("dc", "Initial commit")
2082         self.build_tree({'dc/de':None})
2083         self.client_add("dc/de")
2084         self.client_copy("dc/py/trunk", "dc/de/trunk")
2085         self.client_commit("dc", "Copy trunk")
2086         repos = Repository.open(repos_url)
2087         repos.set_branching_scheme(TrunkBranchingScheme(1))
2088         self.assertEquals(repos.generate_revision_id(1, "py/trunk"), \
2089                 repos._mainline_revision_parent("de/trunk", 2))
2090
2091     def test_mainline_revision_nested_deleted(self):
2092         repos_url = self.make_client('d', 'dc')
2093         self.build_tree({'dc/py/trunk/adir/afile': "data", 
2094                          'dc/py/trunk/adir/stationary': None})
2095         self.client_add("dc/py")
2096         self.client_commit("dc", "Initial commit")
2097         self.client_copy("dc/py", "dc/de")
2098         self.client_commit("dc", "Incremental commit")
2099         self.client_delete("dc/de/trunk/adir")
2100         self.client_commit("dc", "Another incremental commit")
2101         repos = Repository.open(repos_url)
2102         repos.set_branching_scheme(TrunkBranchingScheme(1))
2103         self.assertEquals(repos.generate_revision_id(1, "py/trunk"), \
2104                 repos._mainline_revision_parent("de/trunk", 3))
2105
2106     def test_mainline_revision_missing(self):
2107         repos_url = self.make_client('d', 'dc')
2108         repos = Repository.open(repos_url)
2109         self.build_tree({'dc/py/trunk/adir/afile': "data", 
2110                          'dc/py/trunk/adir/stationary': None})
2111         self.client_add("dc/py")
2112         self.client_commit("dc", "Initial commit")
2113         self.assertRaises(NoSuchRevision, 
2114                 lambda: repos._mainline_revision_parent("trunk", 1))
2115
2116     def test_fetch_crosscopy(self):
2117         repos_url = self.make_client('d', 'dc')
2118         self.build_tree({'dc/trunk/adir/afile': "data", 
2119                          'dc/trunk/adir/stationary': None,
2120                          'dc/branches/abranch': None})
2121         self.client_add("dc/trunk")
2122         self.client_add("dc/branches")
2123         self.client_commit("dc", "Initial commit")
2124
2125         # copyrev
2126         self.client_copy("dc/trunk/adir", "dc/branches/abranch/bdir")
2127         self.client_commit("dc", "Cross copy commit")
2128
2129         # prevrev
2130         self.build_tree({"dc/branches/abranch/bdir/afile": "otherdata"})
2131         self.client_commit("dc", "Change data")
2132
2133         # lastrev
2134         self.build_tree({"dc/branches/abranch/bdir/bfile": "camel",
2135                       "dc/branches/abranch/bdir/stationary/traveller": "data"})
2136         self.client_add("dc/branches/abranch/bdir/bfile")
2137         self.client_add("dc/branches/abranch/bdir/stationary/traveller")
2138         self.client_commit("dc", "Change dir")
2139
2140         oldrepos = Repository.open("svn+"+repos_url)
2141         oldrepos.set_branching_scheme(TrunkBranchingScheme())
2142         dir = BzrDir.create("f")
2143         newrepos = dir.create_repository()
2144         copyrev = oldrepos.generate_revision_id(2, "branches/abranch")
2145         prevrev = oldrepos.generate_revision_id(3, "branches/abranch")
2146         lastrev = oldrepos.generate_revision_id(4, "branches/abranch")
2147         oldrepos.copy_content_into(newrepos, lastrev)
2148
2149         inventory = newrepos.get_inventory(lastrev)
2150         self.assertEqual(prevrev, 
2151                          inventory[inventory.path2id("bdir/afile")].revision)
2152
2153         inventory = newrepos.get_inventory(prevrev)
2154         self.assertEqual(copyrev, 
2155                          inventory[inventory.path2id("bdir/stationary")].revision)
2156
2157 class TestSvnRevisionTree(TestCaseWithSubversionRepository):
2158     def setUp(self):
2159         super(TestSvnRevisionTree, self).setUp()
2160         repos_url = self.make_client('d', 'dc')
2161         self.build_tree({'dc/foo/bla': "data"})
2162         self.client_add("dc/foo")
2163         self.client_commit("dc", "My Message")
2164         self.repos = Repository.open(repos_url)
2165         self.inventory = self.repos.get_inventory(
2166                 self.repos.generate_revision_id(1, ""))
2167         self.tree = self.repos.revision_tree(
2168                 self.repos.generate_revision_id(1, ""))
2169
2170     def test_inventory(self):
2171         self.assertIsInstance(self.tree.inventory, Inventory)
2172         self.assertEqual(self.inventory, self.tree.inventory)
2173
2174     def test_get_parent_ids(self):
2175         self.assertEqual([self.repos.generate_revision_id(0, "")], self.tree.get_parent_ids())
2176
2177     def test_get_parent_ids_zero(self):
2178         tree = self.repos.revision_tree(
2179                 self.repos.generate_revision_id(0, ""))
2180         self.assertEqual([], tree.get_parent_ids())
2181
2182     def test_get_revision_id(self):
2183         self.assertEqual(self.repos.generate_revision_id(1, ""),
2184                          self.tree.get_revision_id())
2185
2186     def test_get_file_lines(self):
2187         self.assertEqual(["data"], 
2188                 self.tree.get_file_lines(self.inventory.path2id("foo/bla")))
2189
2190     def test_executable(self):
2191         self.client_set_prop("dc/foo/bla", "svn:executable", "*")
2192         self.client_commit("dc", "My Message")
2193         
2194         inventory = self.repos.get_inventory(
2195                 self.repos.generate_revision_id(2, ""))
2196
2197         self.assertTrue(inventory[inventory.path2id("foo/bla")].executable)
2198
2199     def test_symlink(self):
2200         os.symlink('foo/bla', 'dc/bar')
2201         self.client_add('dc/bar')
2202         self.client_commit("dc", "My Message")
2203         
2204         inventory = self.repos.get_inventory(
2205                 self.repos.generate_revision_id(2, ""))
2206
2207         self.assertEqual('symlink', inventory[inventory.path2id("bar")].kind)
2208         self.assertEqual('foo/bla', inventory[inventory.path2id("bar")].symlink_target)
2209
2210     def test_not_executable(self):
2211         self.assertFalse(self.inventory[
2212             self.inventory.path2id("foo/bla")].executable)
2213
2214 class RevisionIdMappingTest(TestCase):
2215     def test_generate_revid(self):
2216         self.assertEqual("svn-v%d-undefined:myuuid:branch:5" % MAPPING_VERSION, 
2217                          generate_svn_revision_id("myuuid", 5, "branch"))
2218
2219     def test_generate_revid_nested(self):
2220         self.assertEqual("svn-v%d-undefined:myuuid:branch%%2Fpath:5" % MAPPING_VERSION, 
2221                          generate_svn_revision_id("myuuid", 5, "branch/path"))
2222
2223     def test_generate_revid_special_char(self):
2224         self.assertEqual(u"svn-v%d-undefined:myuuid:branch%%2C:5" % MAPPING_VERSION, 
2225                          generate_svn_revision_id("myuuid", 5, u"branch\x2c"))
2226
2227     def test_generate_revid_special_char_ascii(self):
2228         self.assertEqual("svn-v%d-undefined:myuuid:branch%%2C:5" % MAPPING_VERSION, 
2229                          generate_svn_revision_id("myuuid", 5, "branch\x2c"))
2230
2231     def test_generate_revid_nordic(self):
2232         self.assertEqual("svn-v%d-undefined:myuuid:branch%%C3%%A6:5" % MAPPING_VERSION, 
2233                          generate_svn_revision_id("myuuid", 5, u"branch\xe6"))
2234
2235     def test_parse_revid_simple(self):
2236         self.assertEqual(("uuid", "", 4),
2237                          parse_svn_revision_id(
2238                              "svn-v%d-undefined:uuid::4" % MAPPING_VERSION))
2239
2240     def test_parse_revid_nested(self):
2241         self.assertEqual(("uuid", "bp/data", 4),
2242                          parse_svn_revision_id(
2243                              "svn-v%d-undefined:uuid:bp%%2Fdata:4" % MAPPING_VERSION))
2244
2245     def test_svk_revid_map_root(self):
2246         self.assertEqual("svn-v%d-undefined:auuid::6" % MAPPING_VERSION,
2247                          svk_feature_to_revision_id("auuid:/:6"))
2248
2249     def test_svk_revid_map_nested(self):
2250         self.assertEqual("svn-v%d-undefined:auuid:bp:6" % MAPPING_VERSION,
2251                          svk_feature_to_revision_id("auuid:/bp:6"))
2252
2253     def test_revid_svk_map(self):
2254         self.assertEqual("auuid:/:6", 
2255               revision_id_to_svk_feature("svn-v%d-undefined:auuid::6" % MAPPING_VERSION))
2256
2257
2258 class EscapeTest(TestCase):
2259     def test_escape_svn_path_none(self):      
2260         self.assertEqual("", escape_svn_path(""))
2261
2262     def test_escape_svn_path_simple(self):
2263         self.assertEqual("ab", escape_svn_path("ab"))
2264
2265     def test_escape_svn_path_percent(self):
2266         self.assertEqual("a%25b", escape_svn_path("a%b"))
2267
2268     def test_escape_svn_path_whitespace(self):
2269         self.assertEqual("foobar%20", escape_svn_path("foobar "))
2270
2271     def test_escape_svn_path_slash(self):
2272         self.assertEqual("foobar%2F", escape_svn_path("foobar/"))
2273
2274     def test_escape_svn_path_special_char(self):
2275         self.assertEqual("foobar%8A", escape_svn_path("foobar\x8a"))
2276
2277     def test_unescape_svn_path_slash(self):
2278         self.assertEqual("foobar/", unescape_svn_path("foobar%2F"))
2279
2280     def test_unescape_svn_path_none(self):
2281         self.assertEqual("foobar", unescape_svn_path("foobar"))
2282
2283     def test_unescape_svn_path_percent(self):
2284         self.assertEqual("foobar%b", unescape_svn_path("foobar%25b"))
2285
2286     def test_escape_svn_path_nordic(self):
2287         self.assertEqual("foobar%C3%A6", escape_svn_path(u"foobar\xe6"))
2288
2289
2290 class SvnRepositoryFormatTests(TestCase):
2291     def setUp(self):
2292         self.format = SvnRepositoryFormat()
2293
2294     def test_initialize(self):
2295         self.assertRaises(UninitializableFormat, self.format.initialize, None)
2296
2297     def test_get_format_description(self):
2298         self.assertEqual("Subversion Repository", 
2299                          self.format.get_format_description())