##// END OF EJS Templates
convert: follow svn tags history (issue953)
Patrick Mezard -
r6399:5efd447a default
parent child Browse files
Show More
@@ -369,18 +369,58 b' class svn_source(converter_source):'
369 369 if self.tags is None:
370 370 return tags
371 371
372 start = self.revnum(self.head)
372 # svn tags are just a convention, project branches left in a
373 # 'tags' directory. There is no other relationship than
374 # ancestry, which is expensive to discover and makes them hard
375 # to update incrementally. Worse, past revisions may be
376 # referenced by tags far away in the future, requiring a deep
377 # history traversal on every calculation. Current code
378 # performs a single backward traversal, tracking moves within
379 # the tags directory (tag renaming) and recording a new tag
380 # everytime a project is copied from outside the tags
381 # directory. It also lists deleted tags, this behaviour may
382 # change in the future.
383 pendings = []
384 tagspath = self.tags
385 start = svn.ra.get_latest_revnum(self.ra)
373 386 try:
374 for entry in get_log(self.url, [self.tags], self.startrev, start):
375 orig_paths, revnum, author, date, message = entry
376 for path in orig_paths:
377 if not path.startswith(self.tags+'/'):
387 for entry in get_log(self.url, [self.tags], start, self.startrev):
388 origpaths, revnum, author, date, message = entry
389 copies = [(e.copyfrom_path, e.copyfrom_rev, p) for p,e
390 in origpaths.iteritems() if e.copyfrom_path]
391 copies.sort()
392 # Apply moves/copies from more specific to general
393 copies.reverse()
394
395 srctagspath = tagspath
396 if copies and copies[-1][2] == tagspath:
397 # Track tags directory moves
398 srctagspath = copies.pop()[0]
399
400 for source, sourcerev, dest in copies:
401 if not dest.startswith(tagspath + '/'):
378 402 continue
379 ent = orig_paths[path]
380 source = ent.copyfrom_path
381 rev = ent.copyfrom_rev
382 tag = path.split('/')[-1]
383 tags[tag] = self.revid(rev, module=source)
403 for tag in pendings:
404 if tag[0].startswith(dest):
405 tagpath = source + tag[0][len(dest):]
406 tag[:2] = [tagpath, sourcerev]
407 break
408 else:
409 pendings.append([source, sourcerev, dest.split('/')[-1]])
410
411 # Tell tag renamings from tag creations
412 remainings = []
413 for source, sourcerev, tagname in pendings:
414 if source.startswith(srctagspath):
415 remainings.append([source, sourcerev, tagname])
416 continue
417 # From revision may be fake, get one with changes
418 tagid = self.latest(source, sourcerev)
419 if tagid:
420 tags[tagname] = tagid
421 pendings = remainings
422 tagspath = srctagspath
423
384 424 except SubversionException, (inst, num):
385 425 self.ui.note('no tags found at revision %d\n' % start)
386 426 return tags
@@ -27,6 +27,7 b' cd projA'
27 27 mkdir trunk
28 28 mkdir branches
29 29 mkdir tags
30 mkdir unrelated
30 31 cd ..
31 32
32 33 svnurl=file://$svnpath/svn-repo/projA
@@ -42,12 +43,23 b' echo a >> trunk/a'
42 43 svn ci -m changea
43 44 echo a >> trunk/a
44 45 svn ci -m changea2
46 # Add an unrelated commit to test that tags are bound to the
47 # correct "from" revision and not a dummy one
48 echo a >> unrelated/dummy
49 svn add unrelated/dummy
50 svn ci -m unrelatedchange
45 51 echo % tag current revision
46 52 svn up
47 53 svn copy trunk tags/trunk.v1
48 svn ci -m "tagging trunk.v1"
54 svn copy trunk tags/trunk.badtag
55 svn ci -m "tagging trunk.v1 trunk.badtag"
49 56 echo a >> trunk/a
50 57 svn ci -m changea3
58 echo % fix the bad tag
59 # trunk.badtag should not show in converted tags
60 svn up
61 svn mv tags/trunk.badtag tags/trunk.goodtag
62 svn ci -m "fix trunk.badtag"
51 63 cd ..
52 64
53 65 echo % convert
@@ -1,11 +1,13 b''
1 1 % initial svn import
2 2 Adding projA/trunk
3 Adding projA/unrelated
3 4 Adding projA/branches
4 5 Adding projA/tags
5 6
6 7 Committed revision 1.
7 8 % update svn repository
8 9 A A/trunk
10 A A/unrelated
9 11 A A/branches
10 12 A A/tags
11 13 Checked out revision 1.
@@ -19,15 +21,30 b' Committed revision 3.'
19 21 Sending trunk/a
20 22 Transmitting file data .
21 23 Committed revision 4.
24 A unrelated/dummy
25 Adding unrelated/dummy
26 Transmitting file data .
27 Committed revision 5.
22 28 % tag current revision
23 At revision 4.
29 At revision 5.
24 30 A tags/trunk.v1
31 A tags/trunk.badtag
32 Adding tags/trunk.badtag
25 33 Adding tags/trunk.v1
26 34
27 Committed revision 5.
35 Committed revision 6.
28 36 Sending trunk/a
29 37 Transmitting file data .
30 Committed revision 6.
38 Committed revision 7.
39 % fix the bad tag
40 At revision 7.
41 A tags/trunk.goodtag
42 D tags/trunk.badtag/a
43 D tags/trunk.badtag
44 Deleting tags/trunk.badtag
45 Adding tags/trunk.goodtag
46
47 Committed revision 8.
31 48 % convert
32 49 initializing destination A-hg repository
33 50 scanning source...
@@ -43,7 +60,7 b' o 5 update tags tags: tip'
43 60 |
44 61 o 4 changea3 tags:
45 62 |
46 o 3 changea2 tags: trunk.v1
63 o 3 changea2 tags: trunk.v1 trunk.goodtag
47 64 |
48 65 o 2 changea tags:
49 66 |
@@ -53,3 +70,4 b' o 0 init projA tags:'
53 70
54 71 tip
55 72 trunk.v1
73 trunk.goodtag
General Comments 0
You need to be logged in to leave comments. Login now