Merge upstream fixes.
[jelmer/subvertpy.git] / tests / test_branch.py
1 # Copyright (C) 2006 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, BzrDirTestProviderAdapter, BzrDirFormat
19 from bzrlib.errors import NoSuchFile
20 from bzrlib.repository import Repository
21 from bzrlib.trace import mutter
22
23 import os
24 from unittest import TestCase
25
26 import svn.core, svn.client
27
28 from branch import FakeControlFiles
29 from convert import load_dumpfile
30 import format
31 from repository import MAPPING_VERSION
32 from tests import TestCaseWithSubversionRepository
33
34 class WorkingSubversionBranch(TestCaseWithSubversionRepository):
35     def test_num_revnums(self):
36         repos_url = self.make_client('a', 'dc')
37         bzrdir = BzrDir.open("svn+"+repos_url)
38         branch = bzrdir.open_branch()
39         self.assertEqual(None, branch.last_revision())
40
41         self.build_tree({'dc/foo': "data"})
42         self.client_add("dc/foo")
43         self.client_commit("dc", "My Message")
44         
45         bzrdir = BzrDir.open("svn+"+repos_url)
46         branch = bzrdir.open_branch()
47         repos = bzrdir.open_repository()
48
49         self.assertEqual("svn-v%d:1@%s-" % (MAPPING_VERSION, repos.uuid), 
50                 branch.last_revision())
51
52         self.build_tree({'dc/foo': "data2"})
53         self.client_commit("dc", "My Message")
54
55         branch = Branch.open("svn+"+repos_url)
56         repos = Repository.open("svn+"+repos_url)
57
58         self.assertEqual("svn-v%d:2@%s-" % (MAPPING_VERSION, repos.uuid), 
59                 branch.last_revision())
60
61     def test_set_revision_history(self):
62         repos_url = self.make_client('a', 'dc')
63         branch = Branch.open("svn+"+repos_url)
64         self.assertRaises(NotImplementedError, branch.set_revision_history, [])
65
66     def test_set_push_location(self):
67         repos_url = self.make_client('a', 'dc')
68         branch = Branch.open("svn+"+repos_url)
69         self.assertRaises(NotImplementedError, branch.set_push_location, [])
70
71     def test_get_parent(self):
72         repos_url = self.make_client('a', 'dc')
73         branch = Branch.open("svn+"+repos_url)
74         self.assertEqual("svn+"+repos_url, branch.get_parent())
75
76     def test_append_revision(self):
77         repos_url = self.make_client('a', 'dc')
78         branch = Branch.open("svn+"+repos_url)
79         branch.append_revision([])
80
81     def test_get_push_location(self):
82         repos_url = self.make_client('a', 'dc')
83         branch = Branch.open("svn+"+repos_url)
84         self.assertIs(None, branch.get_push_location())
85
86     def test_revision_history(self):
87         repos_url = self.make_client('a', 'dc')
88
89         branch = Branch.open("svn+"+repos_url)
90         self.assertEqual([], branch.revision_history())
91
92         self.build_tree({'dc/foo': "data"})
93         self.client_add("dc/foo")
94         self.client_commit("dc", "My Message")
95         
96         branch = Branch.open("svn+"+repos_url)
97         repos = Repository.open("svn+"+repos_url)
98
99         self.assertEqual(["svn-v%d:1@%s-" % (MAPPING_VERSION, repos.uuid)], 
100                 branch.revision_history())
101
102         self.build_tree({'dc/foo': "data34"})
103         self.client_commit("dc", "My Message")
104
105         branch = Branch.open("svn+"+repos_url)
106         repos = Repository.open("svn+"+repos_url)
107
108         self.assertEqual([
109             "svn-v%d:1@%s-" % (MAPPING_VERSION, repos.uuid), 
110             "svn-v%d:2@%s-" % (MAPPING_VERSION, repos.uuid)],
111             branch.revision_history())
112
113     def test_get_nick_none(self):
114         repos_url = self.make_client('a', 'dc')
115
116         self.build_tree({'dc/foo': "data"})
117         self.client_add("dc/foo")
118         self.client_commit("dc", "My Message")
119
120         branch = Branch.open("svn+"+repos_url)
121
122         self.assertIs(None, branch.nick)
123
124     def test_get_revprops(self):
125         repos_url = self.make_client('a', 'dc')
126
127         self.build_tree({'dc/foo': "data"})
128         self.client_add("dc/foo")
129         self.client_set_prop("dc", "bzr:revprop:branch-nick", "mybranch")
130         self.client_commit("dc", "My Message")
131
132         branch = Branch.open("svn+"+repos_url)
133
134         rev = branch.repository.get_revision(branch.last_revision())
135
136         self.assertEqual("mybranch", rev.properties["branch-nick"])
137
138     def test_fetch_replace(self):
139         filename = os.path.join(self.test_dir, "dumpfile")
140         open(filename, 'w').write("""SVN-fs-dump-format-version: 2
141
142 UUID: 6f95bc5c-e18d-4021-aca8-49ed51dbcb75
143
144 Revision-number: 0
145 Prop-content-length: 56
146 Content-length: 56
147
148 K 8
149 svn:date
150 V 27
151 2006-07-30T12:41:25.270824Z
152 PROPS-END
153
154 Revision-number: 1
155 Prop-content-length: 94
156 Content-length: 94
157
158 K 7
159 svn:log
160 V 0
161
162 K 10
163 svn:author
164 V 0
165
166 K 8
167 svn:date
168 V 27
169 2006-07-30T12:41:26.117512Z
170 PROPS-END
171
172 Node-path: trunk
173 Node-kind: dir
174 Node-action: add
175 Prop-content-length: 10
176 Content-length: 10
177
178 PROPS-END
179
180
181 Node-path: trunk/hosts
182 Node-kind: file
183 Node-action: add
184 Prop-content-length: 10
185 Text-content-length: 4
186 Text-content-md5: 771ec3328c29d17af5aacf7f895dd885
187 Content-length: 14
188
189 PROPS-END
190 hej1
191
192 Revision-number: 2
193 Prop-content-length: 94
194 Content-length: 94
195
196 K 7
197 svn:log
198 V 0
199
200 K 10
201 svn:author
202 V 0
203
204 K 8
205 svn:date
206 V 27
207 2006-07-30T12:41:27.130044Z
208 PROPS-END
209
210 Node-path: trunk/hosts
211 Node-kind: file
212 Node-action: change
213 Text-content-length: 4
214 Text-content-md5: 6c2479dbb342b8df96d84db7ab92c412
215 Content-length: 4
216
217 hej2
218
219 Revision-number: 3
220 Prop-content-length: 94
221 Content-length: 94
222
223 K 7
224 svn:log
225 V 0
226
227 K 10
228 svn:author
229 V 0
230
231 K 8
232 svn:date
233 V 27
234 2006-07-30T12:41:28.114350Z
235 PROPS-END
236
237 Node-path: trunk/hosts
238 Node-kind: file
239 Node-action: change
240 Text-content-length: 4
241 Text-content-md5: 368cb8d3db6186e2e83d9434f165c525
242 Content-length: 4
243
244 hej3
245
246 Revision-number: 4
247 Prop-content-length: 94
248 Content-length: 94
249
250 K 7
251 svn:log
252 V 0
253
254 K 10
255 svn:author
256 V 0
257
258 K 8
259 svn:date
260 V 27
261 2006-07-30T12:41:29.129563Z
262 PROPS-END
263
264 Node-path: branches
265 Node-kind: dir
266 Node-action: add
267 Prop-content-length: 10
268 Content-length: 10
269
270 PROPS-END
271
272
273 Revision-number: 5
274 Prop-content-length: 94
275 Content-length: 94
276
277 K 7
278 svn:log
279 V 0
280
281 K 10
282 svn:author
283 V 0
284
285 K 8
286 svn:date
287 V 27
288 2006-07-30T12:41:31.130508Z
289 PROPS-END
290
291 Node-path: branches/foobranch
292 Node-kind: dir
293 Node-action: add
294 Node-copyfrom-rev: 4
295 Node-copyfrom-path: trunk
296
297
298 Revision-number: 6
299 Prop-content-length: 94
300 Content-length: 94
301
302 K 7
303 svn:log
304 V 0
305
306 K 10
307 svn:author
308 V 0
309
310 K 8
311 svn:date
312 V 27
313 2006-07-30T12:41:33.129149Z
314 PROPS-END
315
316 Node-path: branches/foobranch/hosts
317 Node-kind: file
318 Node-action: delete
319
320 Node-path: branches/foobranch/hosts
321 Node-kind: file
322 Node-action: add
323 Node-copyfrom-rev: 2
324 Node-copyfrom-path: trunk/hosts
325
326
327
328
329 Revision-number: 7
330 Prop-content-length: 94
331 Content-length: 94
332
333 K 7
334 svn:log
335 V 0
336
337 K 10
338 svn:author
339 V 0
340
341 K 8
342 svn:date
343 V 27
344 2006-07-30T12:41:34.136423Z
345 PROPS-END
346
347 Node-path: branches/foobranch/hosts
348 Node-kind: file
349 Node-action: change
350 Text-content-length: 8
351 Text-content-md5: 0e328d3517a333a4879ebf3d88fd82bb
352 Content-length: 8
353
354 foohosts""")
355         os.mkdir("new")
356         os.mkdir("old")
357
358         load_dumpfile("dumpfile", "old")
359
360         url = "old/branches/foobranch"
361         mutter('open %r' % url)
362         olddir = BzrDir.open(url)
363
364         newdir = olddir.sprout("new")
365
366         newbranch = newdir.open_branch()
367
368         uuid = "6f95bc5c-e18d-4021-aca8-49ed51dbcb75"
369         tree = newbranch.repository.revision_tree(
370                 "svn-v%d:7@%s-branches%%2ffoobranch" % (MAPPING_VERSION, uuid))
371
372         weave = tree.get_weave(tree.inventory.path2id("hosts"))
373         self.assertEqual([
374             'svn-v%d:6@%s-branches%%2ffoobranch' % (MAPPING_VERSION, uuid), 
375             'svn-v%d:7@%s-branches%%2ffoobranch' % (MAPPING_VERSION, uuid)],
376                           weave.versions())
377  
378
379     def test_fetch_odd(self):
380         repos_url = self.make_client('d', 'dc')
381
382         self.build_tree({'dc/trunk': None, 
383                          'dc/trunk/hosts': 'hej1'})
384         self.client_add("dc/trunk")
385         self.client_commit("dc", "created trunk and added hosts") #1
386
387         self.build_tree({'dc/trunk/hosts': 'hej2'})
388         self.client_commit("dc", "rev 2") #2
389
390         self.build_tree({'dc/trunk/hosts': 'hej3'})
391         self.client_commit("dc", "rev 3") #3
392
393         self.build_tree({'dc/branches': None})
394         self.client_add("dc/branches")
395         self.client_commit("dc", "added branches") #4
396
397         self.client_copy("dc/trunk", "dc/branches/foobranch")
398         self.client_commit("dc", "added branch foobranch") #5
399
400         self.build_tree({'dc/branches/foobranch/hosts': 'foohosts'})
401         self.client_commit("dc", "foohosts") #6
402
403         os.mkdir("new")
404
405         url = "svn+"+repos_url+"/branches/foobranch"
406         mutter('open %r' % url)
407         olddir = BzrDir.open(url)
408
409         newdir = olddir.sprout("new")
410
411         newbranch = newdir.open_branch()
412
413         uuid = olddir.open_repository().uuid
414         tree = newbranch.repository.revision_tree(
415                 "svn-v%d:6@%s-branches%%2ffoobranch" % (MAPPING_VERSION, uuid))
416
417         weave = tree.get_weave(tree.inventory.path2id("hosts"))
418         self.assertEqual([
419             'svn-v%d:1@%s-trunk' % (MAPPING_VERSION, uuid), 
420             'svn-v%d:2@%s-trunk' % (MAPPING_VERSION, uuid), 
421             'svn-v%d:3@%s-trunk' % (MAPPING_VERSION, uuid), 
422             'svn-v%d:6@%s-branches%%2ffoobranch' % (MAPPING_VERSION, uuid)],
423                           weave.versions())
424
425     def test_check(self):
426         repos_url = self.make_client('d', 'dc')
427         branch = Branch.open('d')
428         result = branch.check()
429         self.assertEqual(branch, result.branch) 
430  
431     def test_create_checkout(self):
432         repos_url = self.make_client('d', 'dc')
433
434         self.build_tree({'dc/trunk': None, 
435                          'dc/trunk/hosts': 'hej1'})
436         self.client_add("dc/trunk")
437         self.client_commit("dc", "created trunk and added hosts") #1
438
439         url = "svn+"+repos_url+"/trunk"
440         oldbranch = Branch.open(url)
441
442         newtree = oldbranch.create_checkout("e")
443         self.assertTrue(
444             newtree.branch.repository.has_revision(
445            'svn-v%d:1@%s-trunk' % (MAPPING_VERSION, oldbranch.repository.uuid)))
446
447         self.assertTrue(os.path.exists("e/.bzr"))
448         self.assertFalse(os.path.exists("e/.svn"))
449
450     def test_create_checkout_lightweight(self):
451         repos_url = self.make_client('d', 'dc')
452
453         self.build_tree({'dc/trunk': None, 
454                          'dc/trunk/hosts': 'hej1'})
455         self.client_add("dc/trunk")
456         self.client_commit("dc", "created trunk and added hosts") #1
457
458         url = "svn+"+repos_url+"/trunk"
459         oldbranch = Branch.open(url)
460
461         newtree = oldbranch.create_checkout("e", lightweight=True)
462         self.assertTrue(
463             newtree.branch.repository.has_revision(
464            'svn-v%d:1@%s-trunk' % (MAPPING_VERSION, oldbranch.repository.uuid)))
465         self.assertTrue(os.path.exists("e/.svn"))
466         self.assertFalse(os.path.exists("e/.bzr"))
467
468     def test_fetch_branch(self):
469         repos_url = self.make_client('d', 'sc')
470
471         self.build_tree({'sc/foo/bla': "data"})
472         self.client_add("sc/foo")
473         self.client_commit("sc", "foo")
474
475         olddir = BzrDir.open("sc")
476
477         os.mkdir("dc")
478         
479         newdir = olddir.sprout('dc')
480
481         self.assertEqual(
482                 olddir.open_branch().last_revision(),
483                 newdir.open_branch().last_revision())
484
485     def test_ghost_workingtree(self):
486         # Looks like bazaar has trouble creating a working tree of a 
487         # revision that has ghost parents
488         repos_url = self.make_client('d', 'sc')
489
490         self.build_tree({'sc/foo/bla': "data"})
491         self.client_add("sc/foo")
492         self.client_set_prop("sc", "bzr:merge", "some-ghost\n")
493         self.client_commit("sc", "foo")
494
495         olddir = BzrDir.open("sc")
496
497         os.mkdir("dc")
498         
499         newdir = olddir.sprout('dc')
500         newdir.open_repository().get_revision(
501                 newdir.open_branch().last_revision())
502         newdir.open_repository().get_revision_inventory(
503                 newdir.open_branch().last_revision())
504
505 class TestFakeControlFiles(TestCase):
506     def test_get_utf8(self):
507         f = FakeControlFiles()
508         self.assertRaises(NoSuchFile, f.get_utf8, "foo")
509
510
511     def test_get(self):
512         f = FakeControlFiles()
513         self.assertRaises(NoSuchFile, f.get, "foobla")
514