annotate hgext/convert/subversion.py @ 7381:b965605dfb2e

convert: be even more tolerant when detecting svn tags Former code failed when tracking child directories we assumed were renamed with their parents but were really created in the tags directory. This happens in jQuery repository with /tags/ui/1.5b4/release@5455.
author Patrick Mezard <pmezard@gmail.com>
date Sat, 15 Nov 2008 15:51:26 +0100
parents 380fda3eed13
children f5f6b7dcd217
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
1 # Subversion 1.4/1.5 Python API backend
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
2 #
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
3 # Copyright(C) 2007 Daniel Holth et al
4925
2642726b61b6 convert/subversion.py: fix bad assumptions about SVN path naming
Bryan O'Sullivan <bos@serpentine.com>
parents: 4873
diff changeset
4 #
2642726b61b6 convert/subversion.py: fix bad assumptions about SVN path naming
Bryan O'Sullivan <bos@serpentine.com>
parents: 4873
diff changeset
5 # Configuration options:
2642726b61b6 convert/subversion.py: fix bad assumptions about SVN path naming
Bryan O'Sullivan <bos@serpentine.com>
parents: 4873
diff changeset
6 #
2642726b61b6 convert/subversion.py: fix bad assumptions about SVN path naming
Bryan O'Sullivan <bos@serpentine.com>
parents: 4873
diff changeset
7 # convert.svn.trunk
2642726b61b6 convert/subversion.py: fix bad assumptions about SVN path naming
Bryan O'Sullivan <bos@serpentine.com>
parents: 4873
diff changeset
8 # Relative path to the trunk (default: "trunk")
2642726b61b6 convert/subversion.py: fix bad assumptions about SVN path naming
Bryan O'Sullivan <bos@serpentine.com>
parents: 4873
diff changeset
9 # convert.svn.branches
2642726b61b6 convert/subversion.py: fix bad assumptions about SVN path naming
Bryan O'Sullivan <bos@serpentine.com>
parents: 4873
diff changeset
10 # Relative path to tree of branches (default: "branches")
5462
91a522a69c13 convert: svn -- fix tags handling
Kirill Smelkov <kirr@landau.phys.spbu.ru>
parents: 5461
diff changeset
11 # convert.svn.tags
91a522a69c13 convert: svn -- fix tags handling
Kirill Smelkov <kirr@landau.phys.spbu.ru>
parents: 5461
diff changeset
12 # Relative path to tree of tags (default: "tags")
4925
2642726b61b6 convert/subversion.py: fix bad assumptions about SVN path naming
Bryan O'Sullivan <bos@serpentine.com>
parents: 4873
diff changeset
13 #
2642726b61b6 convert/subversion.py: fix bad assumptions about SVN path naming
Bryan O'Sullivan <bos@serpentine.com>
parents: 4873
diff changeset
14 # Set these in a hgrc, or on the command line as follows:
2642726b61b6 convert/subversion.py: fix bad assumptions about SVN path naming
Bryan O'Sullivan <bos@serpentine.com>
parents: 4873
diff changeset
15 #
2642726b61b6 convert/subversion.py: fix bad assumptions about SVN path naming
Bryan O'Sullivan <bos@serpentine.com>
parents: 4873
diff changeset
16 # hg convert --config convert.svn.trunk=wackoname [...]
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
17
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
18 import locale
4946
e8f4e40f285a convert/subversion: work around memory leak in svn's python bindings
Bryan O'Sullivan <bos@serpentine.com>
parents: 4944
diff changeset
19 import os
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
20 import re
5139
18abf13064cb Move debugsvnlog to subversion module.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5138
diff changeset
21 import sys
4946
e8f4e40f285a convert/subversion: work around memory leak in svn's python bindings
Bryan O'Sullivan <bos@serpentine.com>
parents: 4944
diff changeset
22 import cPickle as pickle
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
23 import tempfile
7074
b1a4f67b98d0 convert: properly encode subversion URLs (issue 1224)
Patrick Mezard <pmezard@gmail.com>
parents: 6877
diff changeset
24 import urllib
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
25
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
26 from mercurial import strutil, util
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
27 from mercurial.i18n import _
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
28
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
29 # Subversion stuff. Works best with very recent Python SVN bindings
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
30 # e.g. SVN 1.5 or backports. Thanks to the bzr folks for enhancing
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
31 # these bindings.
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
32
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
33 from cStringIO import StringIO
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
34
5139
18abf13064cb Move debugsvnlog to subversion module.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5138
diff changeset
35 from common import NoRepo, commit, converter_source, encodeargs, decodeargs
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
36 from common import commandline, converter_sink, mapfile
4766
95cbb6b74790 convert: activate subversion engine
Brendan Cully <brendan@kublai.com>
parents: 4765
diff changeset
37
95cbb6b74790 convert: activate subversion engine
Brendan Cully <brendan@kublai.com>
parents: 4765
diff changeset
38 try:
95cbb6b74790 convert: activate subversion engine
Brendan Cully <brendan@kublai.com>
parents: 4765
diff changeset
39 from svn.core import SubversionException, Pool
5010
6b2d8caf87b2 convert svn: try to extract URL from source if it is a working directory
Brendan Cully <brendan@kublai.com>
parents: 5008
diff changeset
40 import svn
6b2d8caf87b2 convert svn: try to extract URL from source if it is a working directory
Brendan Cully <brendan@kublai.com>
parents: 5008
diff changeset
41 import svn.client
4766
95cbb6b74790 convert: activate subversion engine
Brendan Cully <brendan@kublai.com>
parents: 4765
diff changeset
42 import svn.core
95cbb6b74790 convert: activate subversion engine
Brendan Cully <brendan@kublai.com>
parents: 4765
diff changeset
43 import svn.ra
95cbb6b74790 convert: activate subversion engine
Brendan Cully <brendan@kublai.com>
parents: 4765
diff changeset
44 import svn.delta
95cbb6b74790 convert: activate subversion engine
Brendan Cully <brendan@kublai.com>
parents: 4765
diff changeset
45 import transport
95cbb6b74790 convert: activate subversion engine
Brendan Cully <brendan@kublai.com>
parents: 4765
diff changeset
46 except ImportError:
95cbb6b74790 convert: activate subversion engine
Brendan Cully <brendan@kublai.com>
parents: 4765
diff changeset
47 pass
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
48
7381
b965605dfb2e convert: be even more tolerant when detecting svn tags
Patrick Mezard <pmezard@gmail.com>
parents: 7184
diff changeset
49 class SvnPathNotFound(Exception):
b965605dfb2e convert: be even more tolerant when detecting svn tags
Patrick Mezard <pmezard@gmail.com>
parents: 7184
diff changeset
50 pass
b965605dfb2e convert: be even more tolerant when detecting svn tags
Patrick Mezard <pmezard@gmail.com>
parents: 7184
diff changeset
51
5008
b6c3abdbe0eb convert: urlify svn repos if necessary.
Brendan Cully <brendan@kublai.com>
parents: 4960
diff changeset
52 def geturl(path):
5010
6b2d8caf87b2 convert svn: try to extract URL from source if it is a working directory
Brendan Cully <brendan@kublai.com>
parents: 5008
diff changeset
53 try:
5020
780051cca03c convert svn: canonicalize path before calling url_from_path.
Brendan Cully <brendan@kublai.com>
parents: 5010
diff changeset
54 return svn.client.url_from_path(svn.core.svn_path_canonicalize(path))
5010
6b2d8caf87b2 convert svn: try to extract URL from source if it is a working directory
Brendan Cully <brendan@kublai.com>
parents: 5008
diff changeset
55 except SubversionException:
6b2d8caf87b2 convert svn: try to extract URL from source if it is a working directory
Brendan Cully <brendan@kublai.com>
parents: 5008
diff changeset
56 pass
5008
b6c3abdbe0eb convert: urlify svn repos if necessary.
Brendan Cully <brendan@kublai.com>
parents: 4960
diff changeset
57 if os.path.isdir(path):
5793
68f5bf9aa582 convert: Accept local path on win32.
Shun-ichi GOTO <shunichi.goto@gmail.com>
parents: 5790
diff changeset
58 path = os.path.normpath(os.path.abspath(path))
68f5bf9aa582 convert: Accept local path on win32.
Shun-ichi GOTO <shunichi.goto@gmail.com>
parents: 5790
diff changeset
59 if os.name == 'nt':
5842
111ed8c871bf Use util.normpath() instead of direct path string operation.
Shun-ichi GOTO <shunichi.goto@gmail.com>
parents: 5841
diff changeset
60 path = '/' + util.normpath(path)
7074
b1a4f67b98d0 convert: properly encode subversion URLs (issue 1224)
Patrick Mezard <pmezard@gmail.com>
parents: 6877
diff changeset
61 return 'file://%s' % urllib.quote(path)
5008
b6c3abdbe0eb convert: urlify svn repos if necessary.
Brendan Cully <brendan@kublai.com>
parents: 4960
diff changeset
62 return path
b6c3abdbe0eb convert: urlify svn repos if necessary.
Brendan Cully <brendan@kublai.com>
parents: 4960
diff changeset
63
5117
c89ed1f27e78 convert: svn: add helper function for optrevs
Brendan Cully <brendan@kublai.com>
parents: 5114
diff changeset
64 def optrev(number):
c89ed1f27e78 convert: svn: add helper function for optrevs
Brendan Cully <brendan@kublai.com>
parents: 5114
diff changeset
65 optrev = svn.core.svn_opt_revision_t()
c89ed1f27e78 convert: svn: add helper function for optrevs
Brendan Cully <brendan@kublai.com>
parents: 5114
diff changeset
66 optrev.kind = svn.core.svn_opt_revision_number
c89ed1f27e78 convert: svn: add helper function for optrevs
Brendan Cully <brendan@kublai.com>
parents: 5114
diff changeset
67 optrev.value.number = number
c89ed1f27e78 convert: svn: add helper function for optrevs
Brendan Cully <brendan@kublai.com>
parents: 5114
diff changeset
68 return optrev
c89ed1f27e78 convert: svn: add helper function for optrevs
Brendan Cully <brendan@kublai.com>
parents: 5114
diff changeset
69
4946
e8f4e40f285a convert/subversion: work around memory leak in svn's python bindings
Bryan O'Sullivan <bos@serpentine.com>
parents: 4944
diff changeset
70 class changedpath(object):
e8f4e40f285a convert/subversion: work around memory leak in svn's python bindings
Bryan O'Sullivan <bos@serpentine.com>
parents: 4944
diff changeset
71 def __init__(self, p):
e8f4e40f285a convert/subversion: work around memory leak in svn's python bindings
Bryan O'Sullivan <bos@serpentine.com>
parents: 4944
diff changeset
72 self.copyfrom_path = p.copyfrom_path
e8f4e40f285a convert/subversion: work around memory leak in svn's python bindings
Bryan O'Sullivan <bos@serpentine.com>
parents: 4944
diff changeset
73 self.copyfrom_rev = p.copyfrom_rev
e8f4e40f285a convert/subversion: work around memory leak in svn's python bindings
Bryan O'Sullivan <bos@serpentine.com>
parents: 4944
diff changeset
74 self.action = p.action
e8f4e40f285a convert/subversion: work around memory leak in svn's python bindings
Bryan O'Sullivan <bos@serpentine.com>
parents: 4944
diff changeset
75
5127
39b6eaee6fd7 convert: replace fork with subprocess call.
Patrick Mezard <pmezard@gmail.com>
parents: 5122
diff changeset
76 def get_log_child(fp, url, paths, start, end, limit=0, discover_changed_paths=True,
39b6eaee6fd7 convert: replace fork with subprocess call.
Patrick Mezard <pmezard@gmail.com>
parents: 5122
diff changeset
77 strict_node_history=False):
39b6eaee6fd7 convert: replace fork with subprocess call.
Patrick Mezard <pmezard@gmail.com>
parents: 5122
diff changeset
78 protocol = -1
39b6eaee6fd7 convert: replace fork with subprocess call.
Patrick Mezard <pmezard@gmail.com>
parents: 5122
diff changeset
79 def receiver(orig_paths, revnum, author, date, message, pool):
39b6eaee6fd7 convert: replace fork with subprocess call.
Patrick Mezard <pmezard@gmail.com>
parents: 5122
diff changeset
80 if orig_paths is not None:
39b6eaee6fd7 convert: replace fork with subprocess call.
Patrick Mezard <pmezard@gmail.com>
parents: 5122
diff changeset
81 for k, v in orig_paths.iteritems():
39b6eaee6fd7 convert: replace fork with subprocess call.
Patrick Mezard <pmezard@gmail.com>
parents: 5122
diff changeset
82 orig_paths[k] = changedpath(v)
39b6eaee6fd7 convert: replace fork with subprocess call.
Patrick Mezard <pmezard@gmail.com>
parents: 5122
diff changeset
83 pickle.dump((orig_paths, revnum, author, date, message),
5143
d4fa6bafc43a Remove trailing spaces, fix indentation
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5141
diff changeset
84 fp, protocol)
d4fa6bafc43a Remove trailing spaces, fix indentation
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5141
diff changeset
85
5127
39b6eaee6fd7 convert: replace fork with subprocess call.
Patrick Mezard <pmezard@gmail.com>
parents: 5122
diff changeset
86 try:
39b6eaee6fd7 convert: replace fork with subprocess call.
Patrick Mezard <pmezard@gmail.com>
parents: 5122
diff changeset
87 # Use an ra of our own so that our parent can consume
39b6eaee6fd7 convert: replace fork with subprocess call.
Patrick Mezard <pmezard@gmail.com>
parents: 5122
diff changeset
88 # our results without confusing the server.
39b6eaee6fd7 convert: replace fork with subprocess call.
Patrick Mezard <pmezard@gmail.com>
parents: 5122
diff changeset
89 t = transport.SvnRaTransport(url=url)
39b6eaee6fd7 convert: replace fork with subprocess call.
Patrick Mezard <pmezard@gmail.com>
parents: 5122
diff changeset
90 svn.ra.get_log(t.ra, paths, start, end, limit,
39b6eaee6fd7 convert: replace fork with subprocess call.
Patrick Mezard <pmezard@gmail.com>
parents: 5122
diff changeset
91 discover_changed_paths,
39b6eaee6fd7 convert: replace fork with subprocess call.
Patrick Mezard <pmezard@gmail.com>
parents: 5122
diff changeset
92 strict_node_history,
39b6eaee6fd7 convert: replace fork with subprocess call.
Patrick Mezard <pmezard@gmail.com>
parents: 5122
diff changeset
93 receiver)
5140
792c1d979097 Replace _ with inst for catching exceptions to not shadow gettext.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5139
diff changeset
94 except SubversionException, (inst, num):
5127
39b6eaee6fd7 convert: replace fork with subprocess call.
Patrick Mezard <pmezard@gmail.com>
parents: 5122
diff changeset
95 pickle.dump(num, fp, protocol)
5873
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
96 except IOError:
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
97 # Caller may interrupt the iteration
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
98 pickle.dump(None, fp, protocol)
5127
39b6eaee6fd7 convert: replace fork with subprocess call.
Patrick Mezard <pmezard@gmail.com>
parents: 5122
diff changeset
99 else:
39b6eaee6fd7 convert: replace fork with subprocess call.
Patrick Mezard <pmezard@gmail.com>
parents: 5122
diff changeset
100 pickle.dump(None, fp, protocol)
39b6eaee6fd7 convert: replace fork with subprocess call.
Patrick Mezard <pmezard@gmail.com>
parents: 5122
diff changeset
101 fp.close()
6397
e1402cf5e08a convert: avoid svn log retrieval process cleanup
Patrick Mezard <pmezard@gmail.com>
parents: 6281
diff changeset
102 # With large history, cleanup process goes crazy and suddenly
e1402cf5e08a convert: avoid svn log retrieval process cleanup
Patrick Mezard <pmezard@gmail.com>
parents: 6281
diff changeset
103 # consumes *huge* amount of memory. The output file being closed,
e1402cf5e08a convert: avoid svn log retrieval process cleanup
Patrick Mezard <pmezard@gmail.com>
parents: 6281
diff changeset
104 # there is no need for clean termination.
e1402cf5e08a convert: avoid svn log retrieval process cleanup
Patrick Mezard <pmezard@gmail.com>
parents: 6281
diff changeset
105 os._exit(0)
5127
39b6eaee6fd7 convert: replace fork with subprocess call.
Patrick Mezard <pmezard@gmail.com>
parents: 5122
diff changeset
106
5139
18abf13064cb Move debugsvnlog to subversion module.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5138
diff changeset
107 def debugsvnlog(ui, **opts):
18abf13064cb Move debugsvnlog to subversion module.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5138
diff changeset
108 """Fetch SVN log in a subprocess and channel them back to parent to
18abf13064cb Move debugsvnlog to subversion module.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5138
diff changeset
109 avoid memory collection issues.
18abf13064cb Move debugsvnlog to subversion module.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5138
diff changeset
110 """
18abf13064cb Move debugsvnlog to subversion module.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5138
diff changeset
111 util.set_binary(sys.stdin)
18abf13064cb Move debugsvnlog to subversion module.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5138
diff changeset
112 util.set_binary(sys.stdout)
18abf13064cb Move debugsvnlog to subversion module.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5138
diff changeset
113 args = decodeargs(sys.stdin.read())
18abf13064cb Move debugsvnlog to subversion module.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5138
diff changeset
114 get_log_child(sys.stdout, *args)
18abf13064cb Move debugsvnlog to subversion module.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5138
diff changeset
115
5873
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
116 class logstream:
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
117 """Interruptible revision log iterator."""
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
118 def __init__(self, stdout):
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
119 self._stdout = stdout
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
120
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
121 def __iter__(self):
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
122 while True:
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
123 entry = pickle.load(self._stdout)
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
124 try:
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
125 orig_paths, revnum, author, date, message = entry
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
126 except:
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
127 if entry is None:
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
128 break
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
129 raise SubversionException("child raised exception", entry)
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
130 yield entry
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
131
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
132 def close(self):
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
133 if self._stdout:
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
134 self._stdout.close()
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
135 self._stdout = None
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
136
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
137 # SVN conversion code stolen from bzr-svn and tailor
5876
fb93c774dfff convert: document the subversion conversion model
Patrick Mezard <pmezard@gmail.com>
parents: 5875
diff changeset
138 #
fb93c774dfff convert: document the subversion conversion model
Patrick Mezard <pmezard@gmail.com>
parents: 5875
diff changeset
139 # Subversion looks like a versioned filesystem, branches structures
fb93c774dfff convert: document the subversion conversion model
Patrick Mezard <pmezard@gmail.com>
parents: 5875
diff changeset
140 # are defined by conventions and not enforced by the tool. First,
fb93c774dfff convert: document the subversion conversion model
Patrick Mezard <pmezard@gmail.com>
parents: 5875
diff changeset
141 # we define the potential branches (modules) as "trunk" and "branches"
fb93c774dfff convert: document the subversion conversion model
Patrick Mezard <pmezard@gmail.com>
parents: 5875
diff changeset
142 # children directories. Revisions are then identified by their
fb93c774dfff convert: document the subversion conversion model
Patrick Mezard <pmezard@gmail.com>
parents: 5875
diff changeset
143 # module and revision number (and a repository identifier).
fb93c774dfff convert: document the subversion conversion model
Patrick Mezard <pmezard@gmail.com>
parents: 5875
diff changeset
144 #
fb93c774dfff convert: document the subversion conversion model
Patrick Mezard <pmezard@gmail.com>
parents: 5875
diff changeset
145 # The revision graph is really a tree (or a forest). By default, a
fb93c774dfff convert: document the subversion conversion model
Patrick Mezard <pmezard@gmail.com>
parents: 5875
diff changeset
146 # revision parent is the previous revision in the same module. If the
fb93c774dfff convert: document the subversion conversion model
Patrick Mezard <pmezard@gmail.com>
parents: 5875
diff changeset
147 # module directory is copied/moved from another module then the
fb93c774dfff convert: document the subversion conversion model
Patrick Mezard <pmezard@gmail.com>
parents: 5875
diff changeset
148 # revision is the module root and its parent the source revision in
fb93c774dfff convert: document the subversion conversion model
Patrick Mezard <pmezard@gmail.com>
parents: 5875
diff changeset
149 # the parent module. A revision has at most one parent.
fb93c774dfff convert: document the subversion conversion model
Patrick Mezard <pmezard@gmail.com>
parents: 5875
diff changeset
150 #
5438
6fa5258be3d4 convert: rename convert_svn to svn_source
Bryan O'Sullivan <bos@serpentine.com>
parents: 5437
diff changeset
151 class svn_source(converter_source):
4766
95cbb6b74790 convert: activate subversion engine
Brendan Cully <brendan@kublai.com>
parents: 4765
diff changeset
152 def __init__(self, ui, url, rev=None):
5438
6fa5258be3d4 convert: rename convert_svn to svn_source
Bryan O'Sullivan <bos@serpentine.com>
parents: 5437
diff changeset
153 super(svn_source, self).__init__(ui, url, rev=rev)
4807
15a3cbfc6568 convert: call superclass init from engine init functions
Brendan Cully <brendan@kublai.com>
parents: 4799
diff changeset
154
4766
95cbb6b74790 convert: activate subversion engine
Brendan Cully <brendan@kublai.com>
parents: 4765
diff changeset
155 try:
95cbb6b74790 convert: activate subversion engine
Brendan Cully <brendan@kublai.com>
parents: 4765
diff changeset
156 SubversionException
95cbb6b74790 convert: activate subversion engine
Brendan Cully <brendan@kublai.com>
parents: 4765
diff changeset
157 except NameError:
5521
03496d4fa509 convert: display all errors if we couldn't open the source repo
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5462
diff changeset
158 raise NoRepo('Subversion python bindings could not be loaded')
4766
95cbb6b74790 convert: activate subversion engine
Brendan Cully <brendan@kublai.com>
parents: 4765
diff changeset
159
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
160 self.encoding = locale.getpreferredencoding()
4813
1fcdf2fe3d7c convert: svn: use revmap to parse only new revisions in incremental conversions
Brendan Cully <brendan@kublai.com>
parents: 4811
diff changeset
161 self.lastrevs = {}
1fcdf2fe3d7c convert: svn: use revmap to parse only new revisions in incremental conversions
Brendan Cully <brendan@kublai.com>
parents: 4811
diff changeset
162
4766
95cbb6b74790 convert: activate subversion engine
Brendan Cully <brendan@kublai.com>
parents: 4765
diff changeset
163 latest = None
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
164 try:
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
165 # Support file://path@rev syntax. Useful e.g. to convert
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
166 # deleted branches.
4927
5e89b0dafce5 convert/subversion.py: str.rsplit is not available in Python 2.3
Bryan O'Sullivan <bos@serpentine.com>
parents: 4925
diff changeset
167 at = url.rfind('@')
5e89b0dafce5 convert/subversion.py: str.rsplit is not available in Python 2.3
Bryan O'Sullivan <bos@serpentine.com>
parents: 4925
diff changeset
168 if at >= 0:
5e89b0dafce5 convert/subversion.py: str.rsplit is not available in Python 2.3
Bryan O'Sullivan <bos@serpentine.com>
parents: 4925
diff changeset
169 latest = int(url[at+1:])
5e89b0dafce5 convert/subversion.py: str.rsplit is not available in Python 2.3
Bryan O'Sullivan <bos@serpentine.com>
parents: 4925
diff changeset
170 url = url[:at]
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
171 except ValueError, e:
4766
95cbb6b74790 convert: activate subversion engine
Brendan Cully <brendan@kublai.com>
parents: 4765
diff changeset
172 pass
5008
b6c3abdbe0eb convert: urlify svn repos if necessary.
Brendan Cully <brendan@kublai.com>
parents: 4960
diff changeset
173 self.url = geturl(url)
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
174 self.encoding = 'UTF-8' # Subversion is always nominal UTF-8
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
175 try:
5008
b6c3abdbe0eb convert: urlify svn repos if necessary.
Brendan Cully <brendan@kublai.com>
parents: 4960
diff changeset
176 self.transport = transport.SvnRaTransport(url=self.url)
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
177 self.ra = self.transport.ra
4946
e8f4e40f285a convert/subversion: work around memory leak in svn's python bindings
Bryan O'Sullivan <bos@serpentine.com>
parents: 4944
diff changeset
178 self.ctx = self.transport.client
7074
b1a4f67b98d0 convert: properly encode subversion URLs (issue 1224)
Patrick Mezard <pmezard@gmail.com>
parents: 6877
diff changeset
179 self.baseurl = svn.ra.get_repos_root(self.ra)
6538
05dff77bfbd9 convert: fix subpaths detection in svn source
Patrick Mezard <pmezard@gmail.com>
parents: 6493
diff changeset
180 # Module is either empty or a repository path starting with
05dff77bfbd9 convert: fix subpaths detection in svn source
Patrick Mezard <pmezard@gmail.com>
parents: 6493
diff changeset
181 # a slash and not ending with a slash.
7074
b1a4f67b98d0 convert: properly encode subversion URLs (issue 1224)
Patrick Mezard <pmezard@gmail.com>
parents: 6877
diff changeset
182 self.module = urllib.unquote(self.url[len(self.baseurl):])
6847
9d6d1fdb7d72 convert: restore previous svn transport parent correctly
Patrick Mezard <pmezard@gmail.com>
parents: 6553
diff changeset
183 self.prevmodule = None
5957
971a17af5982 convert: prevent svn branches to leave the root module tree
Patrick Mezard <pmezard@gmail.com>
parents: 5956
diff changeset
184 self.rootmodule = self.module
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
185 self.commits = {}
5121
ef338e34a906 convert: look up copies in getchanges instead of getcommit
Brendan Cully <brendan@kublai.com>
parents: 5120
diff changeset
186 self.paths = {}
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
187 self.uuid = svn.ra.get_uuid(self.ra).decode(self.encoding)
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
188 except SubversionException, e:
5437
4d34f8b12a9e convert: report errors more meaningfully if run with --traceback
Bryan O'Sullivan <bos@serpentine.com>
parents: 5415
diff changeset
189 ui.print_exc()
5521
03496d4fa509 convert: display all errors if we couldn't open the source repo
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5462
diff changeset
190 raise NoRepo("%s does not look like a Subversion repo" % self.url)
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
191
5145
0751c25ea0c0 raise util.Abort again if specified revision is not an integer.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5144
diff changeset
192 if rev:
0751c25ea0c0 raise util.Abort again if specified revision is not an integer.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5144
diff changeset
193 try:
0751c25ea0c0 raise util.Abort again if specified revision is not an integer.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5144
diff changeset
194 latest = int(rev)
0751c25ea0c0 raise util.Abort again if specified revision is not an integer.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5144
diff changeset
195 except ValueError:
0751c25ea0c0 raise util.Abort again if specified revision is not an integer.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5144
diff changeset
196 raise util.Abort('svn: revision %s is not an integer' % rev)
0751c25ea0c0 raise util.Abort again if specified revision is not an integer.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5144
diff changeset
197
6173
963000ed8cac convert: add shallow, single branch svn conversions via svn.startrev
Patrick Mezard <pmezard@gmail.com>
parents: 6172
diff changeset
198 self.startrev = self.ui.config('convert', 'svn.startrev', default=0)
963000ed8cac convert: add shallow, single branch svn conversions via svn.startrev
Patrick Mezard <pmezard@gmail.com>
parents: 6172
diff changeset
199 try:
963000ed8cac convert: add shallow, single branch svn conversions via svn.startrev
Patrick Mezard <pmezard@gmail.com>
parents: 6172
diff changeset
200 self.startrev = int(self.startrev)
963000ed8cac convert: add shallow, single branch svn conversions via svn.startrev
Patrick Mezard <pmezard@gmail.com>
parents: 6172
diff changeset
201 if self.startrev < 0:
963000ed8cac convert: add shallow, single branch svn conversions via svn.startrev
Patrick Mezard <pmezard@gmail.com>
parents: 6172
diff changeset
202 self.startrev = 0
963000ed8cac convert: add shallow, single branch svn conversions via svn.startrev
Patrick Mezard <pmezard@gmail.com>
parents: 6172
diff changeset
203 except ValueError:
6210
942287cb1f57 Removed trailing spaces from everything except test output
Thomas Arendsen Hein <thomas@intevation.de>
parents: 6173
diff changeset
204 raise util.Abort(_('svn: start revision %s is not an integer')
6173
963000ed8cac convert: add shallow, single branch svn conversions via svn.startrev
Patrick Mezard <pmezard@gmail.com>
parents: 6172
diff changeset
205 % self.startrev)
963000ed8cac convert: add shallow, single branch svn conversions via svn.startrev
Patrick Mezard <pmezard@gmail.com>
parents: 6172
diff changeset
206
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
207 try:
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
208 self.get_blacklist()
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
209 except IOError, e:
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
210 pass
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
211
5955
c4496b7c10ce convert: fix svn_source.latest()
Patrick Mezard <pmezard@gmail.com>
parents: 5921
diff changeset
212 self.head = self.latest(self.module, latest)
5957
971a17af5982 convert: prevent svn branches to leave the root module tree
Patrick Mezard <pmezard@gmail.com>
parents: 5956
diff changeset
213 if not self.head:
971a17af5982 convert: prevent svn branches to leave the root module tree
Patrick Mezard <pmezard@gmail.com>
parents: 5956
diff changeset
214 raise util.Abort(_('no revision found in module %s') %
971a17af5982 convert: prevent svn branches to leave the root module tree
Patrick Mezard <pmezard@gmail.com>
parents: 5956
diff changeset
215 self.module.encode(self.encoding))
5955
c4496b7c10ce convert: fix svn_source.latest()
Patrick Mezard <pmezard@gmail.com>
parents: 5921
diff changeset
216 self.last_changed = self.revnum(self.head)
6210
942287cb1f57 Removed trailing spaces from everything except test output
Thomas Arendsen Hein <thomas@intevation.de>
parents: 6173
diff changeset
217
5382
d7d395fb7cd5 convert_svn: add --filemap support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5373
diff changeset
218 self._changescache = None
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
219
5554
2147a734dcf9 convert: tell the source repository when a rev has been converted
Bryan O'Sullivan <bos@serpentine.com>
parents: 5537
diff changeset
220 if os.path.exists(os.path.join(url, '.svn/entries')):
2147a734dcf9 convert: tell the source repository when a rev has been converted
Bryan O'Sullivan <bos@serpentine.com>
parents: 5537
diff changeset
221 self.wc = url
2147a734dcf9 convert: tell the source repository when a rev has been converted
Bryan O'Sullivan <bos@serpentine.com>
parents: 5537
diff changeset
222 else:
2147a734dcf9 convert: tell the source repository when a rev has been converted
Bryan O'Sullivan <bos@serpentine.com>
parents: 5537
diff changeset
223 self.wc = None
2147a734dcf9 convert: tell the source repository when a rev has been converted
Bryan O'Sullivan <bos@serpentine.com>
parents: 5537
diff changeset
224 self.convertfp = None
2147a734dcf9 convert: tell the source repository when a rev has been converted
Bryan O'Sullivan <bos@serpentine.com>
parents: 5537
diff changeset
225
5510
11d7908a3ea8 convert: abstract map files into a class
Bryan O'Sullivan <bos@serpentine.com>
parents: 5462
diff changeset
226 def setrevmap(self, revmap):
4840
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
227 lastrevs = {}
5511
03bb1296a1c3 convert: iterate
Bryan O'Sullivan <bos@serpentine.com>
parents: 5510
diff changeset
228 for revid in revmap.iterkeys():
4840
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
229 uuid, module, revnum = self.revsplit(revid)
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
230 lastrevnum = lastrevs.setdefault(module, revnum)
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
231 if revnum > lastrevnum:
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
232 lastrevs[module] = revnum
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
233 self.lastrevs = lastrevs
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
234
4925
2642726b61b6 convert/subversion.py: fix bad assumptions about SVN path naming
Bryan O'Sullivan <bos@serpentine.com>
parents: 4873
diff changeset
235 def exists(self, path, optrev):
2642726b61b6 convert/subversion.py: fix bad assumptions about SVN path naming
Bryan O'Sullivan <bos@serpentine.com>
parents: 4873
diff changeset
236 try:
7074
b1a4f67b98d0 convert: properly encode subversion URLs (issue 1224)
Patrick Mezard <pmezard@gmail.com>
parents: 6877
diff changeset
237 svn.client.ls(self.url.rstrip('/') + '/' + urllib.quote(path),
4925
2642726b61b6 convert/subversion.py: fix bad assumptions about SVN path naming
Bryan O'Sullivan <bos@serpentine.com>
parents: 4873
diff changeset
238 optrev, False, self.ctx)
5461
ab4d2e9f3b97 convert: svn -- fix 'exists'
Kirill Smelkov <kirr@landau.phys.spbu.ru>
parents: 5438
diff changeset
239 return True
4925
2642726b61b6 convert/subversion.py: fix bad assumptions about SVN path naming
Bryan O'Sullivan <bos@serpentine.com>
parents: 4873
diff changeset
240 except SubversionException, err:
5461
ab4d2e9f3b97 convert: svn -- fix 'exists'
Kirill Smelkov <kirr@landau.phys.spbu.ru>
parents: 5438
diff changeset
241 return False
4925
2642726b61b6 convert/subversion.py: fix bad assumptions about SVN path naming
Bryan O'Sullivan <bos@serpentine.com>
parents: 4873
diff changeset
242
4840
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
243 def getheads(self):
5854
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
244
6491
2bdd43246c95 convert: check svn branches are directories
Patrick Mezard <pmezard@gmail.com>
parents: 6400
diff changeset
245 def isdir(path, revnum):
6848
59c40c60d8d8 convert: remove leading slash from ra.check_path inputs (issue 1236)
Patrick Mezard <pmezard@gmail.com>
parents: 6847
diff changeset
246 kind = self._checkpath(path, revnum)
6491
2bdd43246c95 convert: check svn branches are directories
Patrick Mezard <pmezard@gmail.com>
parents: 6400
diff changeset
247 return kind == svn.core.svn_node_dir
2bdd43246c95 convert: check svn branches are directories
Patrick Mezard <pmezard@gmail.com>
parents: 6400
diff changeset
248
5854
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
249 def getcfgpath(name, rev):
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
250 cfgpath = self.ui.config('convert', 'svn.' + name)
6172
0cd6846e5200 convert: allow svn trunk/branches/tags detection to be skipped
Patrick Mezard <pmezard@gmail.com>
parents: 6053
diff changeset
251 if cfgpath is not None and cfgpath.strip() == '':
0cd6846e5200 convert: allow svn trunk/branches/tags detection to be skipped
Patrick Mezard <pmezard@gmail.com>
parents: 6053
diff changeset
252 return None
5854
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
253 path = (cfgpath or name).strip('/')
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
254 if not self.exists(path, rev):
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
255 if cfgpath:
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
256 raise util.Abort(_('expected %s to be at %r, but not found')
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
257 % (name, path))
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
258 return None
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
259 self.ui.note(_('found %s at %r\n') % (name, path))
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
260 return path
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
261
5117
c89ed1f27e78 convert: svn: add helper function for optrevs
Brendan Cully <brendan@kublai.com>
parents: 5114
diff changeset
262 rev = optrev(self.last_changed)
5854
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
263 oldmodule = ''
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
264 trunk = getcfgpath('trunk', rev)
6400
c237b27e1350 convert: allow tags detection to be disabled
Patrick Mezard <pmezard@gmail.com>
parents: 6399
diff changeset
265 self.tags = getcfgpath('tags', rev)
5854
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
266 branches = getcfgpath('branches', rev)
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
267
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
268 # If the project has a trunk or branches, we will extract heads
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
269 # from them. We keep the project root otherwise.
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
270 if trunk:
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
271 oldmodule = self.module or ''
4925
2642726b61b6 convert/subversion.py: fix bad assumptions about SVN path naming
Bryan O'Sullivan <bos@serpentine.com>
parents: 4873
diff changeset
272 self.module += '/' + trunk
5955
c4496b7c10ce convert: fix svn_source.latest()
Patrick Mezard <pmezard@gmail.com>
parents: 5921
diff changeset
273 self.head = self.latest(self.module, self.last_changed)
5957
971a17af5982 convert: prevent svn branches to leave the root module tree
Patrick Mezard <pmezard@gmail.com>
parents: 5956
diff changeset
274 if not self.head:
971a17af5982 convert: prevent svn branches to leave the root module tree
Patrick Mezard <pmezard@gmail.com>
parents: 5956
diff changeset
275 raise util.Abort(_('no revision found in module %s') %
971a17af5982 convert: prevent svn branches to leave the root module tree
Patrick Mezard <pmezard@gmail.com>
parents: 5956
diff changeset
276 self.module.encode(self.encoding))
5854
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
277
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
278 # First head in the list is the module's head
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
279 self.heads = [self.head]
6400
c237b27e1350 convert: allow tags detection to be disabled
Patrick Mezard <pmezard@gmail.com>
parents: 6399
diff changeset
280 if self.tags is not None:
c237b27e1350 convert: allow tags detection to be disabled
Patrick Mezard <pmezard@gmail.com>
parents: 6399
diff changeset
281 self.tags = '%s/%s' % (oldmodule , (self.tags or 'tags'))
5854
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
282
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
283 # Check if branches bring a few more heads to the list
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
284 if branches:
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
285 rpath = self.url.strip('/')
7184
380fda3eed13 clean up trailing spaces
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7074
diff changeset
286 branchnames = svn.client.ls(rpath + '/' + urllib.quote(branches),
7074
b1a4f67b98d0 convert: properly encode subversion URLs (issue 1224)
Patrick Mezard <pmezard@gmail.com>
parents: 6877
diff changeset
287 rev, False, self.ctx)
4925
2642726b61b6 convert/subversion.py: fix bad assumptions about SVN path naming
Bryan O'Sullivan <bos@serpentine.com>
parents: 4873
diff changeset
288 for branch in branchnames.keys():
5854
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
289 module = '%s/%s/%s' % (oldmodule, branches, branch)
6491
2bdd43246c95 convert: check svn branches are directories
Patrick Mezard <pmezard@gmail.com>
parents: 6400
diff changeset
290 if not isdir(module, self.last_changed):
2bdd43246c95 convert: check svn branches are directories
Patrick Mezard <pmezard@gmail.com>
parents: 6400
diff changeset
291 continue
5955
c4496b7c10ce convert: fix svn_source.latest()
Patrick Mezard <pmezard@gmail.com>
parents: 5921
diff changeset
292 brevid = self.latest(module, self.last_changed)
5957
971a17af5982 convert: prevent svn branches to leave the root module tree
Patrick Mezard <pmezard@gmail.com>
parents: 5956
diff changeset
293 if not brevid:
971a17af5982 convert: prevent svn branches to leave the root module tree
Patrick Mezard <pmezard@gmail.com>
parents: 5956
diff changeset
294 self.ui.note(_('ignoring empty branch %s\n') %
971a17af5982 convert: prevent svn branches to leave the root module tree
Patrick Mezard <pmezard@gmail.com>
parents: 5956
diff changeset
295 branch.encode(self.encoding))
971a17af5982 convert: prevent svn branches to leave the root module tree
Patrick Mezard <pmezard@gmail.com>
parents: 5956
diff changeset
296 continue
6210
942287cb1f57 Removed trailing spaces from everything except test output
Thomas Arendsen Hein <thomas@intevation.de>
parents: 6173
diff changeset
297 self.ui.note('found branch %s at %d\n' %
5955
c4496b7c10ce convert: fix svn_source.latest()
Patrick Mezard <pmezard@gmail.com>
parents: 5921
diff changeset
298 (branch, self.revnum(brevid)))
c4496b7c10ce convert: fix svn_source.latest()
Patrick Mezard <pmezard@gmail.com>
parents: 5921
diff changeset
299 self.heads.append(brevid)
5462
91a522a69c13 convert: svn -- fix tags handling
Kirill Smelkov <kirr@landau.phys.spbu.ru>
parents: 5461
diff changeset
300
6173
963000ed8cac convert: add shallow, single branch svn conversions via svn.startrev
Patrick Mezard <pmezard@gmail.com>
parents: 6172
diff changeset
301 if self.startrev and self.heads:
963000ed8cac convert: add shallow, single branch svn conversions via svn.startrev
Patrick Mezard <pmezard@gmail.com>
parents: 6172
diff changeset
302 if len(self.heads) > 1:
963000ed8cac convert: add shallow, single branch svn conversions via svn.startrev
Patrick Mezard <pmezard@gmail.com>
parents: 6172
diff changeset
303 raise util.Abort(_('svn: start revision is not supported with '
963000ed8cac convert: add shallow, single branch svn conversions via svn.startrev
Patrick Mezard <pmezard@gmail.com>
parents: 6172
diff changeset
304 'with more than one branch'))
963000ed8cac convert: add shallow, single branch svn conversions via svn.startrev
Patrick Mezard <pmezard@gmail.com>
parents: 6172
diff changeset
305 revnum = self.revnum(self.heads[0])
963000ed8cac convert: add shallow, single branch svn conversions via svn.startrev
Patrick Mezard <pmezard@gmail.com>
parents: 6172
diff changeset
306 if revnum < self.startrev:
6210
942287cb1f57 Removed trailing spaces from everything except test output
Thomas Arendsen Hein <thomas@intevation.de>
parents: 6173
diff changeset
307 raise util.Abort(_('svn: no revision found after start revision %d')
6173
963000ed8cac convert: add shallow, single branch svn conversions via svn.startrev
Patrick Mezard <pmezard@gmail.com>
parents: 6172
diff changeset
308 % self.startrev)
963000ed8cac convert: add shallow, single branch svn conversions via svn.startrev
Patrick Mezard <pmezard@gmail.com>
parents: 6172
diff changeset
309
4840
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
310 return self.heads
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
311
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
312 def getfile(self, file, rev):
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
313 data, mode = self._getfile(file, rev)
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
314 self.modecache[(file, rev)] = mode
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
315 return data
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
316
4957
cdd33a048289 removed trailing whitespace
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4949
diff changeset
317 def getmode(self, file, rev):
4840
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
318 return self.modecache[(file, rev)]
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
319
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
320 def getchanges(self, rev):
5382
d7d395fb7cd5 convert_svn: add --filemap support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5373
diff changeset
321 if self._changescache and self._changescache[0] == rev:
d7d395fb7cd5 convert_svn: add --filemap support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5373
diff changeset
322 return self._changescache[1]
d7d395fb7cd5 convert_svn: add --filemap support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5373
diff changeset
323 self._changescache = None
4840
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
324 self.modecache = {}
5121
ef338e34a906 convert: look up copies in getchanges instead of getcommit
Brendan Cully <brendan@kublai.com>
parents: 5120
diff changeset
325 (paths, parents) = self.paths[rev]
5956
094638b3cbed convert: checkout svn root revisions
Patrick Mezard <pmezard@gmail.com>
parents: 5955
diff changeset
326 if parents:
094638b3cbed convert: checkout svn root revisions
Patrick Mezard <pmezard@gmail.com>
parents: 5955
diff changeset
327 files, copies = self.expandpaths(rev, paths, parents)
094638b3cbed convert: checkout svn root revisions
Patrick Mezard <pmezard@gmail.com>
parents: 5955
diff changeset
328 else:
094638b3cbed convert: checkout svn root revisions
Patrick Mezard <pmezard@gmail.com>
parents: 5955
diff changeset
329 # Perform a full checkout on roots
094638b3cbed convert: checkout svn root revisions
Patrick Mezard <pmezard@gmail.com>
parents: 5955
diff changeset
330 uuid, module, revnum = self.revsplit(rev)
7184
380fda3eed13 clean up trailing spaces
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7074
diff changeset
331 entries = svn.client.ls(self.baseurl + urllib.quote(module),
7074
b1a4f67b98d0 convert: properly encode subversion URLs (issue 1224)
Patrick Mezard <pmezard@gmail.com>
parents: 6877
diff changeset
332 optrev(revnum), True, self.ctx)
6210
942287cb1f57 Removed trailing spaces from everything except test output
Thomas Arendsen Hein <thomas@intevation.de>
parents: 6173
diff changeset
333 files = [n for n,e in entries.iteritems()
5956
094638b3cbed convert: checkout svn root revisions
Patrick Mezard <pmezard@gmail.com>
parents: 5955
diff changeset
334 if e.kind == svn.core.svn_node_file]
094638b3cbed convert: checkout svn root revisions
Patrick Mezard <pmezard@gmail.com>
parents: 5955
diff changeset
335 copies = {}
094638b3cbed convert: checkout svn root revisions
Patrick Mezard <pmezard@gmail.com>
parents: 5955
diff changeset
336
5121
ef338e34a906 convert: look up copies in getchanges instead of getcommit
Brendan Cully <brendan@kublai.com>
parents: 5120
diff changeset
337 files.sort()
ef338e34a906 convert: look up copies in getchanges instead of getcommit
Brendan Cully <brendan@kublai.com>
parents: 5120
diff changeset
338 files = zip(files, [rev] * len(files))
ef338e34a906 convert: look up copies in getchanges instead of getcommit
Brendan Cully <brendan@kublai.com>
parents: 5120
diff changeset
339
4840
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
340 # caller caches the result, so free it here to release memory
5121
ef338e34a906 convert: look up copies in getchanges instead of getcommit
Brendan Cully <brendan@kublai.com>
parents: 5120
diff changeset
341 del self.paths[rev]
ef338e34a906 convert: look up copies in getchanges instead of getcommit
Brendan Cully <brendan@kublai.com>
parents: 5120
diff changeset
342 return (files, copies)
4840
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
343
5382
d7d395fb7cd5 convert_svn: add --filemap support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5373
diff changeset
344 def getchangedfiles(self, rev, i):
d7d395fb7cd5 convert_svn: add --filemap support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5373
diff changeset
345 changes = self.getchanges(rev)
d7d395fb7cd5 convert_svn: add --filemap support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5373
diff changeset
346 self._changescache = (rev, changes)
d7d395fb7cd5 convert_svn: add --filemap support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5373
diff changeset
347 return [f[0] for f in changes[0]]
d7d395fb7cd5 convert_svn: add --filemap support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5373
diff changeset
348
4840
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
349 def getcommit(self, rev):
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
350 if rev not in self.commits:
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
351 uuid, module, revnum = self.revsplit(rev)
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
352 self.module = module
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
353 self.reparent(module)
5875
f1504d3355bb convert: fetch less revisions when looking for a branch parent
Patrick Mezard <pmezard@gmail.com>
parents: 5873
diff changeset
354 # We assume that:
f1504d3355bb convert: fetch less revisions when looking for a branch parent
Patrick Mezard <pmezard@gmail.com>
parents: 5873
diff changeset
355 # - requests for revisions after "stop" come from the
f1504d3355bb convert: fetch less revisions when looking for a branch parent
Patrick Mezard <pmezard@gmail.com>
parents: 5873
diff changeset
356 # revision graph backward traversal. Cache all of them
f1504d3355bb convert: fetch less revisions when looking for a branch parent
Patrick Mezard <pmezard@gmail.com>
parents: 5873
diff changeset
357 # down to stop, they will be used eventually.
f1504d3355bb convert: fetch less revisions when looking for a branch parent
Patrick Mezard <pmezard@gmail.com>
parents: 5873
diff changeset
358 # - requests for revisions before "stop" come to get
f1504d3355bb convert: fetch less revisions when looking for a branch parent
Patrick Mezard <pmezard@gmail.com>
parents: 5873
diff changeset
359 # isolated branches parents. Just fetch what is needed.
4840
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
360 stop = self.lastrevs.get(module, 0)
5875
f1504d3355bb convert: fetch less revisions when looking for a branch parent
Patrick Mezard <pmezard@gmail.com>
parents: 5873
diff changeset
361 if revnum < stop:
f1504d3355bb convert: fetch less revisions when looking for a branch parent
Patrick Mezard <pmezard@gmail.com>
parents: 5873
diff changeset
362 stop = revnum + 1
5871
c1244685425a convert: fix parents of last fetched svn revision
Patrick Mezard <pmezard@gmail.com>
parents: 5870
diff changeset
363 self._fetch_revisions(revnum, stop)
4840
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
364 commit = self.commits[rev]
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
365 # caller caches the result, so free it here to release memory
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
366 del self.commits[rev]
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
367 return commit
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
368
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
369 def gettags(self):
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
370 tags = {}
6172
0cd6846e5200 convert: allow svn trunk/branches/tags detection to be skipped
Patrick Mezard <pmezard@gmail.com>
parents: 6053
diff changeset
371 if self.tags is None:
0cd6846e5200 convert: allow svn trunk/branches/tags detection to be skipped
Patrick Mezard <pmezard@gmail.com>
parents: 6053
diff changeset
372 return tags
6210
942287cb1f57 Removed trailing spaces from everything except test output
Thomas Arendsen Hein <thomas@intevation.de>
parents: 6173
diff changeset
373
6399
5efd447a9b8d convert: follow svn tags history (issue953)
Patrick Mezard <pmezard@gmail.com>
parents: 6397
diff changeset
374 # svn tags are just a convention, project branches left in a
5efd447a9b8d convert: follow svn tags history (issue953)
Patrick Mezard <pmezard@gmail.com>
parents: 6397
diff changeset
375 # 'tags' directory. There is no other relationship than
5efd447a9b8d convert: follow svn tags history (issue953)
Patrick Mezard <pmezard@gmail.com>
parents: 6397
diff changeset
376 # ancestry, which is expensive to discover and makes them hard
5efd447a9b8d convert: follow svn tags history (issue953)
Patrick Mezard <pmezard@gmail.com>
parents: 6397
diff changeset
377 # to update incrementally. Worse, past revisions may be
5efd447a9b8d convert: follow svn tags history (issue953)
Patrick Mezard <pmezard@gmail.com>
parents: 6397
diff changeset
378 # referenced by tags far away in the future, requiring a deep
5efd447a9b8d convert: follow svn tags history (issue953)
Patrick Mezard <pmezard@gmail.com>
parents: 6397
diff changeset
379 # history traversal on every calculation. Current code
5efd447a9b8d convert: follow svn tags history (issue953)
Patrick Mezard <pmezard@gmail.com>
parents: 6397
diff changeset
380 # performs a single backward traversal, tracking moves within
5efd447a9b8d convert: follow svn tags history (issue953)
Patrick Mezard <pmezard@gmail.com>
parents: 6397
diff changeset
381 # the tags directory (tag renaming) and recording a new tag
5efd447a9b8d convert: follow svn tags history (issue953)
Patrick Mezard <pmezard@gmail.com>
parents: 6397
diff changeset
382 # everytime a project is copied from outside the tags
5efd447a9b8d convert: follow svn tags history (issue953)
Patrick Mezard <pmezard@gmail.com>
parents: 6397
diff changeset
383 # directory. It also lists deleted tags, this behaviour may
5efd447a9b8d convert: follow svn tags history (issue953)
Patrick Mezard <pmezard@gmail.com>
parents: 6397
diff changeset
384 # change in the future.
5efd447a9b8d convert: follow svn tags history (issue953)
Patrick Mezard <pmezard@gmail.com>
parents: 6397
diff changeset
385 pendings = []
5efd447a9b8d convert: follow svn tags history (issue953)
Patrick Mezard <pmezard@gmail.com>
parents: 6397
diff changeset
386 tagspath = self.tags
5efd447a9b8d convert: follow svn tags history (issue953)
Patrick Mezard <pmezard@gmail.com>
parents: 6397
diff changeset
387 start = svn.ra.get_latest_revnum(self.ra)
4949
2f0f9528e77b convert/subversion: rehandle the no-tags case
Bryan O'Sullivan <bos@serpentine.com>
parents: 4946
diff changeset
388 try:
6850
c6bb8fae3bd2 convert: normalize paths sent to svn get_log (issue 1219)
Patrick Mezard <pmezard@gmail.com>
parents: 6848
diff changeset
389 for entry in self._getlog([self.tags], start, self.startrev):
6399
5efd447a9b8d convert: follow svn tags history (issue953)
Patrick Mezard <pmezard@gmail.com>
parents: 6397
diff changeset
390 origpaths, revnum, author, date, message = entry
6493
c19c26718d22 Fix spacing error introduced in 5efd447a9b8d
Thomas Arendsen Hein <thomas@intevation.de>
parents: 6491
diff changeset
391 copies = [(e.copyfrom_path, e.copyfrom_rev, p) for p, e
6399
5efd447a9b8d convert: follow svn tags history (issue953)
Patrick Mezard <pmezard@gmail.com>
parents: 6397
diff changeset
392 in origpaths.iteritems() if e.copyfrom_path]
5efd447a9b8d convert: follow svn tags history (issue953)
Patrick Mezard <pmezard@gmail.com>
parents: 6397
diff changeset
393 copies.sort()
5efd447a9b8d convert: follow svn tags history (issue953)
Patrick Mezard <pmezard@gmail.com>
parents: 6397
diff changeset
394 # Apply moves/copies from more specific to general
5efd447a9b8d convert: follow svn tags history (issue953)
Patrick Mezard <pmezard@gmail.com>
parents: 6397
diff changeset
395 copies.reverse()
5efd447a9b8d convert: follow svn tags history (issue953)
Patrick Mezard <pmezard@gmail.com>
parents: 6397
diff changeset
396
5efd447a9b8d convert: follow svn tags history (issue953)
Patrick Mezard <pmezard@gmail.com>
parents: 6397
diff changeset
397 srctagspath = tagspath
5efd447a9b8d convert: follow svn tags history (issue953)
Patrick Mezard <pmezard@gmail.com>
parents: 6397
diff changeset
398 if copies and copies[-1][2] == tagspath:
5efd447a9b8d convert: follow svn tags history (issue953)
Patrick Mezard <pmezard@gmail.com>
parents: 6397
diff changeset
399 # Track tags directory moves
5efd447a9b8d convert: follow svn tags history (issue953)
Patrick Mezard <pmezard@gmail.com>
parents: 6397
diff changeset
400 srctagspath = copies.pop()[0]
5efd447a9b8d convert: follow svn tags history (issue953)
Patrick Mezard <pmezard@gmail.com>
parents: 6397
diff changeset
401
5efd447a9b8d convert: follow svn tags history (issue953)
Patrick Mezard <pmezard@gmail.com>
parents: 6397
diff changeset
402 for source, sourcerev, dest in copies:
5efd447a9b8d convert: follow svn tags history (issue953)
Patrick Mezard <pmezard@gmail.com>
parents: 6397
diff changeset
403 if not dest.startswith(tagspath + '/'):
4949
2f0f9528e77b convert/subversion: rehandle the no-tags case
Bryan O'Sullivan <bos@serpentine.com>
parents: 4946
diff changeset
404 continue
6399
5efd447a9b8d convert: follow svn tags history (issue953)
Patrick Mezard <pmezard@gmail.com>
parents: 6397
diff changeset
405 for tag in pendings:
5efd447a9b8d convert: follow svn tags history (issue953)
Patrick Mezard <pmezard@gmail.com>
parents: 6397
diff changeset
406 if tag[0].startswith(dest):
5efd447a9b8d convert: follow svn tags history (issue953)
Patrick Mezard <pmezard@gmail.com>
parents: 6397
diff changeset
407 tagpath = source + tag[0][len(dest):]
5efd447a9b8d convert: follow svn tags history (issue953)
Patrick Mezard <pmezard@gmail.com>
parents: 6397
diff changeset
408 tag[:2] = [tagpath, sourcerev]
5efd447a9b8d convert: follow svn tags history (issue953)
Patrick Mezard <pmezard@gmail.com>
parents: 6397
diff changeset
409 break
5efd447a9b8d convert: follow svn tags history (issue953)
Patrick Mezard <pmezard@gmail.com>
parents: 6397
diff changeset
410 else:
5efd447a9b8d convert: follow svn tags history (issue953)
Patrick Mezard <pmezard@gmail.com>
parents: 6397
diff changeset
411 pendings.append([source, sourcerev, dest.split('/')[-1]])
5efd447a9b8d convert: follow svn tags history (issue953)
Patrick Mezard <pmezard@gmail.com>
parents: 6397
diff changeset
412
5efd447a9b8d convert: follow svn tags history (issue953)
Patrick Mezard <pmezard@gmail.com>
parents: 6397
diff changeset
413 # Tell tag renamings from tag creations
5efd447a9b8d convert: follow svn tags history (issue953)
Patrick Mezard <pmezard@gmail.com>
parents: 6397
diff changeset
414 remainings = []
5efd447a9b8d convert: follow svn tags history (issue953)
Patrick Mezard <pmezard@gmail.com>
parents: 6397
diff changeset
415 for source, sourcerev, tagname in pendings:
5efd447a9b8d convert: follow svn tags history (issue953)
Patrick Mezard <pmezard@gmail.com>
parents: 6397
diff changeset
416 if source.startswith(srctagspath):
5efd447a9b8d convert: follow svn tags history (issue953)
Patrick Mezard <pmezard@gmail.com>
parents: 6397
diff changeset
417 remainings.append([source, sourcerev, tagname])
5efd447a9b8d convert: follow svn tags history (issue953)
Patrick Mezard <pmezard@gmail.com>
parents: 6397
diff changeset
418 continue
5efd447a9b8d convert: follow svn tags history (issue953)
Patrick Mezard <pmezard@gmail.com>
parents: 6397
diff changeset
419 # From revision may be fake, get one with changes
7381
b965605dfb2e convert: be even more tolerant when detecting svn tags
Patrick Mezard <pmezard@gmail.com>
parents: 7184
diff changeset
420 try:
b965605dfb2e convert: be even more tolerant when detecting svn tags
Patrick Mezard <pmezard@gmail.com>
parents: 7184
diff changeset
421 tagid = self.latest(source, sourcerev)
b965605dfb2e convert: be even more tolerant when detecting svn tags
Patrick Mezard <pmezard@gmail.com>
parents: 7184
diff changeset
422 if tagid:
b965605dfb2e convert: be even more tolerant when detecting svn tags
Patrick Mezard <pmezard@gmail.com>
parents: 7184
diff changeset
423 tags[tagname] = tagid
b965605dfb2e convert: be even more tolerant when detecting svn tags
Patrick Mezard <pmezard@gmail.com>
parents: 7184
diff changeset
424 except SvnPathNotFound:
b965605dfb2e convert: be even more tolerant when detecting svn tags
Patrick Mezard <pmezard@gmail.com>
parents: 7184
diff changeset
425 # It happens when we are following directories we assumed
b965605dfb2e convert: be even more tolerant when detecting svn tags
Patrick Mezard <pmezard@gmail.com>
parents: 7184
diff changeset
426 # were copied with their parents but were really created
b965605dfb2e convert: be even more tolerant when detecting svn tags
Patrick Mezard <pmezard@gmail.com>
parents: 7184
diff changeset
427 # in the tag directory.
b965605dfb2e convert: be even more tolerant when detecting svn tags
Patrick Mezard <pmezard@gmail.com>
parents: 7184
diff changeset
428 pass
6399
5efd447a9b8d convert: follow svn tags history (issue953)
Patrick Mezard <pmezard@gmail.com>
parents: 6397
diff changeset
429 pendings = remainings
5efd447a9b8d convert: follow svn tags history (issue953)
Patrick Mezard <pmezard@gmail.com>
parents: 6397
diff changeset
430 tagspath = srctagspath
5efd447a9b8d convert: follow svn tags history (issue953)
Patrick Mezard <pmezard@gmail.com>
parents: 6397
diff changeset
431
5140
792c1d979097 Replace _ with inst for catching exceptions to not shadow gettext.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5139
diff changeset
432 except SubversionException, (inst, num):
4949
2f0f9528e77b convert/subversion: rehandle the no-tags case
Bryan O'Sullivan <bos@serpentine.com>
parents: 4946
diff changeset
433 self.ui.note('no tags found at revision %d\n' % start)
4946
e8f4e40f285a convert/subversion: work around memory leak in svn's python bindings
Bryan O'Sullivan <bos@serpentine.com>
parents: 4944
diff changeset
434 return tags
4840
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
435
5554
2147a734dcf9 convert: tell the source repository when a rev has been converted
Bryan O'Sullivan <bos@serpentine.com>
parents: 5537
diff changeset
436 def converted(self, rev, destrev):
2147a734dcf9 convert: tell the source repository when a rev has been converted
Bryan O'Sullivan <bos@serpentine.com>
parents: 5537
diff changeset
437 if not self.wc:
2147a734dcf9 convert: tell the source repository when a rev has been converted
Bryan O'Sullivan <bos@serpentine.com>
parents: 5537
diff changeset
438 return
2147a734dcf9 convert: tell the source repository when a rev has been converted
Bryan O'Sullivan <bos@serpentine.com>
parents: 5537
diff changeset
439 if self.convertfp is None:
2147a734dcf9 convert: tell the source repository when a rev has been converted
Bryan O'Sullivan <bos@serpentine.com>
parents: 5537
diff changeset
440 self.convertfp = open(os.path.join(self.wc, '.svn', 'hg-shamap'),
2147a734dcf9 convert: tell the source repository when a rev has been converted
Bryan O'Sullivan <bos@serpentine.com>
parents: 5537
diff changeset
441 'a')
2147a734dcf9 convert: tell the source repository when a rev has been converted
Bryan O'Sullivan <bos@serpentine.com>
parents: 5537
diff changeset
442 self.convertfp.write('%s %d\n' % (destrev, self.revnum(rev)))
2147a734dcf9 convert: tell the source repository when a rev has been converted
Bryan O'Sullivan <bos@serpentine.com>
parents: 5537
diff changeset
443 self.convertfp.flush()
2147a734dcf9 convert: tell the source repository when a rev has been converted
Bryan O'Sullivan <bos@serpentine.com>
parents: 5537
diff changeset
444
4840
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
445 # -- helper functions --
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
446
4810
c2d529f288a1 convert: move some code into common init function
Brendan Cully <brendan@kublai.com>
parents: 4807
diff changeset
447 def revid(self, revnum, module=None):
4795
ea618c5934f3 convert: svn: get parent for branch creation events
Brendan Cully <brendan@kublai.com>
parents: 4794
diff changeset
448 if not module:
ea618c5934f3 convert: svn: get parent for branch creation events
Brendan Cully <brendan@kublai.com>
parents: 4794
diff changeset
449 module = self.module
5287
c6f932d3e0f6 Don't decode unicode strings.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5276
diff changeset
450 return u"svn:%s%s@%s" % (self.uuid, module.decode(self.encoding),
c6f932d3e0f6 Don't decode unicode strings.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5276
diff changeset
451 revnum)
4774
d305852a5ec8 convert: svn: add revnum() to convert rev to revnum
Brendan Cully <brendan@kublai.com>
parents: 4773
diff changeset
452
d305852a5ec8 convert: svn: add revnum() to convert rev to revnum
Brendan Cully <brendan@kublai.com>
parents: 4773
diff changeset
453 def revnum(self, rev):
d305852a5ec8 convert: svn: add revnum() to convert rev to revnum
Brendan Cully <brendan@kublai.com>
parents: 4773
diff changeset
454 return int(rev.split('@')[-1])
4789
c5dd8e184279 convert: svn: add function to get the latest revision touching a path
Brendan Cully <brendan@kublai.com>
parents: 4788
diff changeset
455
4794
1f10a6cccdb5 convert: add optional module argument to svn._fetch_revisions
Brendan Cully <brendan@kublai.com>
parents: 4793
diff changeset
456 def revsplit(self, rev):
1f10a6cccdb5 convert: add optional module argument to svn._fetch_revisions
Brendan Cully <brendan@kublai.com>
parents: 4793
diff changeset
457 url, revnum = rev.encode(self.encoding).split('@', 1)
1f10a6cccdb5 convert: add optional module argument to svn._fetch_revisions
Brendan Cully <brendan@kublai.com>
parents: 4793
diff changeset
458 revnum = int(revnum)
1f10a6cccdb5 convert: add optional module argument to svn._fetch_revisions
Brendan Cully <brendan@kublai.com>
parents: 4793
diff changeset
459 parts = url.split('/', 1)
1f10a6cccdb5 convert: add optional module argument to svn._fetch_revisions
Brendan Cully <brendan@kublai.com>
parents: 4793
diff changeset
460 uuid = parts.pop(0)[4:]
4797
09dae950919f convert: svn: autodetect /branches, /tags, /trunk.
Brendan Cully <brendan@kublai.com>
parents: 4796
diff changeset
461 mod = ''
4794
1f10a6cccdb5 convert: add optional module argument to svn._fetch_revisions
Brendan Cully <brendan@kublai.com>
parents: 4793
diff changeset
462 if parts:
4797
09dae950919f convert: svn: autodetect /branches, /tags, /trunk.
Brendan Cully <brendan@kublai.com>
parents: 4796
diff changeset
463 mod = '/' + parts[0]
4794
1f10a6cccdb5 convert: add optional module argument to svn._fetch_revisions
Brendan Cully <brendan@kublai.com>
parents: 4793
diff changeset
464 return uuid, mod, revnum
1f10a6cccdb5 convert: add optional module argument to svn._fetch_revisions
Brendan Cully <brendan@kublai.com>
parents: 4793
diff changeset
465
4790
c2ef09a35c53 convert: typo in svn.latest
Brendan Cully <brendan@kublai.com>
parents: 4789
diff changeset
466 def latest(self, path, stop=0):
5955
c4496b7c10ce convert: fix svn_source.latest()
Patrick Mezard <pmezard@gmail.com>
parents: 5921
diff changeset
467 """Find the latest revid affecting path, up to stop. It may return
c4496b7c10ce convert: fix svn_source.latest()
Patrick Mezard <pmezard@gmail.com>
parents: 5921
diff changeset
468 a revision in a different module, since a branch may be moved without
5957
971a17af5982 convert: prevent svn branches to leave the root module tree
Patrick Mezard <pmezard@gmail.com>
parents: 5956
diff changeset
469 a change being reported. Return None if computed module does not
971a17af5982 convert: prevent svn branches to leave the root module tree
Patrick Mezard <pmezard@gmail.com>
parents: 5956
diff changeset
470 belong to rootmodule subtree.
5955
c4496b7c10ce convert: fix svn_source.latest()
Patrick Mezard <pmezard@gmail.com>
parents: 5921
diff changeset
471 """
6281
3e5f99b13998 convert: avoid querying log of foreign svn branches
Patrick Mezard <pmezard@gmail.com>
parents: 6214
diff changeset
472 if not path.startswith(self.rootmodule):
3e5f99b13998 convert: avoid querying log of foreign svn branches
Patrick Mezard <pmezard@gmail.com>
parents: 6214
diff changeset
473 # Requests on foreign branches may be forbidden at server level
3e5f99b13998 convert: avoid querying log of foreign svn branches
Patrick Mezard <pmezard@gmail.com>
parents: 6214
diff changeset
474 self.ui.debug(_('ignoring foreign branch %r\n') % path)
3e5f99b13998 convert: avoid querying log of foreign svn branches
Patrick Mezard <pmezard@gmail.com>
parents: 6214
diff changeset
475 return None
3e5f99b13998 convert: avoid querying log of foreign svn branches
Patrick Mezard <pmezard@gmail.com>
parents: 6214
diff changeset
476
4789
c5dd8e184279 convert: svn: add function to get the latest revision touching a path
Brendan Cully <brendan@kublai.com>
parents: 4788
diff changeset
477 if not stop:
c5dd8e184279 convert: svn: add function to get the latest revision touching a path
Brendan Cully <brendan@kublai.com>
parents: 4788
diff changeset
478 stop = svn.ra.get_latest_revnum(self.ra)
c5dd8e184279 convert: svn: add function to get the latest revision touching a path
Brendan Cully <brendan@kublai.com>
parents: 4788
diff changeset
479 try:
6847
9d6d1fdb7d72 convert: restore previous svn transport parent correctly
Patrick Mezard <pmezard@gmail.com>
parents: 6553
diff changeset
480 prevmodule = self.reparent('')
4789
c5dd8e184279 convert: svn: add function to get the latest revision touching a path
Brendan Cully <brendan@kublai.com>
parents: 4788
diff changeset
481 dirent = svn.ra.stat(self.ra, path.strip('/'), stop)
6847
9d6d1fdb7d72 convert: restore previous svn transport parent correctly
Patrick Mezard <pmezard@gmail.com>
parents: 6553
diff changeset
482 self.reparent(prevmodule)
4789
c5dd8e184279 convert: svn: add function to get the latest revision touching a path
Brendan Cully <brendan@kublai.com>
parents: 4788
diff changeset
483 except SubversionException:
c5dd8e184279 convert: svn: add function to get the latest revision touching a path
Brendan Cully <brendan@kublai.com>
parents: 4788
diff changeset
484 dirent = None
c5dd8e184279 convert: svn: add function to get the latest revision touching a path
Brendan Cully <brendan@kublai.com>
parents: 4788
diff changeset
485 if not dirent:
7381
b965605dfb2e convert: be even more tolerant when detecting svn tags
Patrick Mezard <pmezard@gmail.com>
parents: 7184
diff changeset
486 raise SvnPathNotFound(_('%s not found up to revision %d') % (path, stop))
4789
c5dd8e184279 convert: svn: add function to get the latest revision touching a path
Brendan Cully <brendan@kublai.com>
parents: 4788
diff changeset
487
5955
c4496b7c10ce convert: fix svn_source.latest()
Patrick Mezard <pmezard@gmail.com>
parents: 5921
diff changeset
488 # stat() gives us the previous revision on this line of development, but
c4496b7c10ce convert: fix svn_source.latest()
Patrick Mezard <pmezard@gmail.com>
parents: 5921
diff changeset
489 # it might be in *another module*. Fetch the log and detect renames down
c4496b7c10ce convert: fix svn_source.latest()
Patrick Mezard <pmezard@gmail.com>
parents: 5921
diff changeset
490 # to the latest revision.
6850
c6bb8fae3bd2 convert: normalize paths sent to svn get_log (issue 1219)
Patrick Mezard <pmezard@gmail.com>
parents: 6848
diff changeset
491 stream = self._getlog([path], stop, dirent.created_rev)
5955
c4496b7c10ce convert: fix svn_source.latest()
Patrick Mezard <pmezard@gmail.com>
parents: 5921
diff changeset
492 try:
c4496b7c10ce convert: fix svn_source.latest()
Patrick Mezard <pmezard@gmail.com>
parents: 5921
diff changeset
493 for entry in stream:
c4496b7c10ce convert: fix svn_source.latest()
Patrick Mezard <pmezard@gmail.com>
parents: 5921
diff changeset
494 paths, revnum, author, date, message = entry
c4496b7c10ce convert: fix svn_source.latest()
Patrick Mezard <pmezard@gmail.com>
parents: 5921
diff changeset
495 if revnum <= dirent.created_rev:
c4496b7c10ce convert: fix svn_source.latest()
Patrick Mezard <pmezard@gmail.com>
parents: 5921
diff changeset
496 break
c4496b7c10ce convert: fix svn_source.latest()
Patrick Mezard <pmezard@gmail.com>
parents: 5921
diff changeset
497
c4496b7c10ce convert: fix svn_source.latest()
Patrick Mezard <pmezard@gmail.com>
parents: 5921
diff changeset
498 for p in paths:
c4496b7c10ce convert: fix svn_source.latest()
Patrick Mezard <pmezard@gmail.com>
parents: 5921
diff changeset
499 if not path.startswith(p) or not paths[p].copyfrom_path:
c4496b7c10ce convert: fix svn_source.latest()
Patrick Mezard <pmezard@gmail.com>
parents: 5921
diff changeset
500 continue
c4496b7c10ce convert: fix svn_source.latest()
Patrick Mezard <pmezard@gmail.com>
parents: 5921
diff changeset
501 newpath = paths[p].copyfrom_path + path[len(p):]
6210
942287cb1f57 Removed trailing spaces from everything except test output
Thomas Arendsen Hein <thomas@intevation.de>
parents: 6173
diff changeset
502 self.ui.debug("branch renamed from %s to %s at %d\n" %
5955
c4496b7c10ce convert: fix svn_source.latest()
Patrick Mezard <pmezard@gmail.com>
parents: 5921
diff changeset
503 (path, newpath, revnum))
c4496b7c10ce convert: fix svn_source.latest()
Patrick Mezard <pmezard@gmail.com>
parents: 5921
diff changeset
504 path = newpath
c4496b7c10ce convert: fix svn_source.latest()
Patrick Mezard <pmezard@gmail.com>
parents: 5921
diff changeset
505 break
c4496b7c10ce convert: fix svn_source.latest()
Patrick Mezard <pmezard@gmail.com>
parents: 5921
diff changeset
506 finally:
c4496b7c10ce convert: fix svn_source.latest()
Patrick Mezard <pmezard@gmail.com>
parents: 5921
diff changeset
507 stream.close()
c4496b7c10ce convert: fix svn_source.latest()
Patrick Mezard <pmezard@gmail.com>
parents: 5921
diff changeset
508
5957
971a17af5982 convert: prevent svn branches to leave the root module tree
Patrick Mezard <pmezard@gmail.com>
parents: 5956
diff changeset
509 if not path.startswith(self.rootmodule):
971a17af5982 convert: prevent svn branches to leave the root module tree
Patrick Mezard <pmezard@gmail.com>
parents: 5956
diff changeset
510 self.ui.debug(_('ignoring foreign branch %r\n') % path)
971a17af5982 convert: prevent svn branches to leave the root module tree
Patrick Mezard <pmezard@gmail.com>
parents: 5956
diff changeset
511 return None
5955
c4496b7c10ce convert: fix svn_source.latest()
Patrick Mezard <pmezard@gmail.com>
parents: 5921
diff changeset
512 return self.revid(dirent.created_rev, path)
4789
c5dd8e184279 convert: svn: add function to get the latest revision touching a path
Brendan Cully <brendan@kublai.com>
parents: 4788
diff changeset
513
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
514 def get_blacklist(self):
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
515 """Avoid certain revision numbers.
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
516 It is not uncommon for two nearby revisions to cancel each other
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
517 out, e.g. 'I copied trunk into a subdirectory of itself instead
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
518 of making a branch'. The converted repository is significantly
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
519 smaller if we ignore such revisions."""
5276
694eb9ccb54d convert/subversion: Use util.set() instead of set() for python2.3 compatibility
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5250
diff changeset
520 self.blacklist = util.set()
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
521 blacklist = self.blacklist
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
522 for line in file("blacklist.txt", "r"):
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
523 if not line.startswith("#"):
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
524 try:
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
525 svn_rev = int(line.strip())
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
526 blacklist.add(svn_rev)
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
527 except ValueError, e:
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
528 pass # not an integer or a comment
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
529
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
530 def is_blacklisted(self, svn_rev):
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
531 return svn_rev in self.blacklist
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
532
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
533 def reparent(self, module):
6847
9d6d1fdb7d72 convert: restore previous svn transport parent correctly
Patrick Mezard <pmezard@gmail.com>
parents: 6553
diff changeset
534 """Reparent the svn transport and return the previous parent."""
9d6d1fdb7d72 convert: restore previous svn transport parent correctly
Patrick Mezard <pmezard@gmail.com>
parents: 6553
diff changeset
535 if self.prevmodule == module:
9d6d1fdb7d72 convert: restore previous svn transport parent correctly
Patrick Mezard <pmezard@gmail.com>
parents: 6553
diff changeset
536 return module
7074
b1a4f67b98d0 convert: properly encode subversion URLs (issue 1224)
Patrick Mezard <pmezard@gmail.com>
parents: 6877
diff changeset
537 svnurl = self.baseurl + urllib.quote(module)
6847
9d6d1fdb7d72 convert: restore previous svn transport parent correctly
Patrick Mezard <pmezard@gmail.com>
parents: 6553
diff changeset
538 prevmodule = self.prevmodule
9d6d1fdb7d72 convert: restore previous svn transport parent correctly
Patrick Mezard <pmezard@gmail.com>
parents: 6553
diff changeset
539 if prevmodule is None:
9d6d1fdb7d72 convert: restore previous svn transport parent correctly
Patrick Mezard <pmezard@gmail.com>
parents: 6553
diff changeset
540 prevmodule = ''
7074
b1a4f67b98d0 convert: properly encode subversion URLs (issue 1224)
Patrick Mezard <pmezard@gmail.com>
parents: 6877
diff changeset
541 self.ui.debug("reparent to %s\n" % svnurl)
b1a4f67b98d0 convert: properly encode subversion URLs (issue 1224)
Patrick Mezard <pmezard@gmail.com>
parents: 6877
diff changeset
542 svn.ra.reparent(self.ra, svnurl)
6847
9d6d1fdb7d72 convert: restore previous svn transport parent correctly
Patrick Mezard <pmezard@gmail.com>
parents: 6553
diff changeset
543 self.prevmodule = module
9d6d1fdb7d72 convert: restore previous svn transport parent correctly
Patrick Mezard <pmezard@gmail.com>
parents: 6553
diff changeset
544 return prevmodule
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
545
5120
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
546 def expandpaths(self, rev, paths, parents):
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
547 entries = []
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
548 copyfrom = {} # Map of entrypath, revision for finding source of deleted revisions.
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
549 copies = {}
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
550
5872
7d4149cccc5d convert: fix cross-branches subversion revisions handling
Patrick Mezard <pmezard@gmail.com>
parents: 5871
diff changeset
551 new_module, revnum = self.revsplit(rev)[1:]
7d4149cccc5d convert: fix cross-branches subversion revisions handling
Patrick Mezard <pmezard@gmail.com>
parents: 5871
diff changeset
552 if new_module != self.module:
7d4149cccc5d convert: fix cross-branches subversion revisions handling
Patrick Mezard <pmezard@gmail.com>
parents: 5871
diff changeset
553 self.module = new_module
7d4149cccc5d convert: fix cross-branches subversion revisions handling
Patrick Mezard <pmezard@gmail.com>
parents: 5871
diff changeset
554 self.reparent(self.module)
5121
ef338e34a906 convert: look up copies in getchanges instead of getcommit
Brendan Cully <brendan@kublai.com>
parents: 5120
diff changeset
555
5120
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
556 for path, ent in paths:
6539
7814d7bb77bc convert: rename get_entry_from_path() into an svn_source method
Patrick Mezard <pmezard@gmail.com>
parents: 6538
diff changeset
557 entrypath = self.getrelpath(path)
5120
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
558 entry = entrypath.decode(self.encoding)
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
559
6848
59c40c60d8d8 convert: remove leading slash from ra.check_path inputs (issue 1236)
Patrick Mezard <pmezard@gmail.com>
parents: 6847
diff changeset
560 kind = self._checkpath(entrypath, revnum)
5120
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
561 if kind == svn.core.svn_node_file:
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
562 entries.append(self.recode(entry))
6546
075b2c9aed37 convert: fix svn file copy detection code
Patrick Mezard <pmezard@gmail.com>
parents: 6545
diff changeset
563 if not ent.copyfrom_path or not parents:
6544
3447c088a516 convert: cleanup svn file copy handling
Patrick Mezard <pmezard@gmail.com>
parents: 6543
diff changeset
564 continue
6546
075b2c9aed37 convert: fix svn file copy detection code
Patrick Mezard <pmezard@gmail.com>
parents: 6545
diff changeset
565 # Copy sources not in parent revisions cannot be represented,
075b2c9aed37 convert: fix svn file copy detection code
Patrick Mezard <pmezard@gmail.com>
parents: 6545
diff changeset
566 # ignore their origin for now
075b2c9aed37 convert: fix svn file copy detection code
Patrick Mezard <pmezard@gmail.com>
parents: 6545
diff changeset
567 pmodule, prevnum = self.revsplit(parents[0])[1:]
075b2c9aed37 convert: fix svn file copy detection code
Patrick Mezard <pmezard@gmail.com>
parents: 6545
diff changeset
568 if ent.copyfrom_rev < prevnum:
075b2c9aed37 convert: fix svn file copy detection code
Patrick Mezard <pmezard@gmail.com>
parents: 6545
diff changeset
569 continue
075b2c9aed37 convert: fix svn file copy detection code
Patrick Mezard <pmezard@gmail.com>
parents: 6545
diff changeset
570 copyfrom_path = self.getrelpath(ent.copyfrom_path, pmodule)
6544
3447c088a516 convert: cleanup svn file copy handling
Patrick Mezard <pmezard@gmail.com>
parents: 6543
diff changeset
571 if not copyfrom_path:
3447c088a516 convert: cleanup svn file copy handling
Patrick Mezard <pmezard@gmail.com>
parents: 6543
diff changeset
572 continue
3447c088a516 convert: cleanup svn file copy handling
Patrick Mezard <pmezard@gmail.com>
parents: 6543
diff changeset
573 self.ui.debug("copied to %s from %s@%s\n" %
3447c088a516 convert: cleanup svn file copy handling
Patrick Mezard <pmezard@gmail.com>
parents: 6543
diff changeset
574 (entrypath, copyfrom_path, ent.copyfrom_rev))
6546
075b2c9aed37 convert: fix svn file copy detection code
Patrick Mezard <pmezard@gmail.com>
parents: 6545
diff changeset
575 copies[self.recode(entry)] = self.recode(copyfrom_path)
5120
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
576 elif kind == 0: # gone, but had better be a deleted *file*
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
577 self.ui.debug("gone from %s\n" % ent.copyfrom_rev)
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
578
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
579 # if a branch is created but entries are removed in the same
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
580 # changeset, get the right fromrev
5872
7d4149cccc5d convert: fix cross-branches subversion revisions handling
Patrick Mezard <pmezard@gmail.com>
parents: 5871
diff changeset
581 # parents cannot be empty here, you cannot remove things from
7d4149cccc5d convert: fix cross-branches subversion revisions handling
Patrick Mezard <pmezard@gmail.com>
parents: 5871
diff changeset
582 # a root revision.
7d4149cccc5d convert: fix cross-branches subversion revisions handling
Patrick Mezard <pmezard@gmail.com>
parents: 5871
diff changeset
583 uuid, old_module, fromrev = self.revsplit(parents[0])
5120
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
584
6539
7814d7bb77bc convert: rename get_entry_from_path() into an svn_source method
Patrick Mezard <pmezard@gmail.com>
parents: 6538
diff changeset
585 basepath = old_module + "/" + self.getrelpath(path)
7814d7bb77bc convert: rename get_entry_from_path() into an svn_source method
Patrick Mezard <pmezard@gmail.com>
parents: 6538
diff changeset
586 entrypath = basepath
5120
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
587
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
588 def lookup_parts(p):
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
589 rc = None
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
590 parts = p.split("/")
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
591 for i in range(len(parts)):
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
592 part = "/".join(parts[:i])
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
593 info = part, copyfrom.get(part, None)
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
594 if info[1] is not None:
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
595 self.ui.debug("Found parent directory %s\n" % info[1])
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
596 rc = info
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
597 return rc
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
598
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
599 self.ui.debug("base, entry %s %s\n" % (basepath, entrypath))
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
600
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
601 frompath, froment = lookup_parts(entrypath) or (None, revnum - 1)
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
602
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
603 # need to remove fragment from lookup_parts and replace with copyfrom_path
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
604 if frompath is not None:
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
605 self.ui.debug("munge-o-matic\n")
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
606 self.ui.debug(entrypath + '\n')
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
607 self.ui.debug(entrypath[len(frompath):] + '\n')
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
608 entrypath = froment.copyfrom_path + entrypath[len(frompath):]
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
609 fromrev = froment.copyfrom_rev
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
610 self.ui.debug("Info: %s %s %s %s\n" % (frompath, froment, ent, entrypath))
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
611
5880
b32a0596b2d7 convert: fix invalid svn.ra.check_path() call (issue 771)
Patrick Mezard <pmezard@gmail.com>
parents: 5617
diff changeset
612 # We can avoid the reparent calls if the module has not changed
b32a0596b2d7 convert: fix invalid svn.ra.check_path() call (issue 771)
Patrick Mezard <pmezard@gmail.com>
parents: 5617
diff changeset
613 # but it probably does not worth the pain.
6847
9d6d1fdb7d72 convert: restore previous svn transport parent correctly
Patrick Mezard <pmezard@gmail.com>
parents: 6553
diff changeset
614 prevmodule = self.reparent('')
5880
b32a0596b2d7 convert: fix invalid svn.ra.check_path() call (issue 771)
Patrick Mezard <pmezard@gmail.com>
parents: 5617
diff changeset
615 fromkind = svn.ra.check_path(self.ra, entrypath.strip('/'), fromrev)
6847
9d6d1fdb7d72 convert: restore previous svn transport parent correctly
Patrick Mezard <pmezard@gmail.com>
parents: 6553
diff changeset
616 self.reparent(prevmodule)
6210
942287cb1f57 Removed trailing spaces from everything except test output
Thomas Arendsen Hein <thomas@intevation.de>
parents: 6173
diff changeset
617
5120
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
618 if fromkind == svn.core.svn_node_file: # a deleted file
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
619 entries.append(self.recode(entry))
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
620 elif fromkind == svn.core.svn_node_dir:
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
621 # print "Deleted/moved non-file:", revnum, path, ent
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
622 # children = self._find_children(path, revnum - 1)
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
623 # print "find children %s@%d from %d action %s" % (path, revnum, ent.copyfrom_rev, ent.action)
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
624 # Sometimes this is tricky. For example: in
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
625 # The Subversion Repository revision 6940 a dir
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
626 # was copied and one of its files was deleted
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
627 # from the new location in the same commit. This
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
628 # code can't deal with that yet.
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
629 if ent.action == 'C':
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
630 children = self._find_children(path, fromrev)
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
631 else:
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
632 oroot = entrypath.strip('/')
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
633 nroot = path.strip('/')
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
634 children = self._find_children(oroot, fromrev)
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
635 children = [s.replace(oroot,nroot) for s in children]
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
636 # Mark all [files, not directories] as deleted.
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
637 for child in children:
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
638 # Can we move a child directory and its
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
639 # parent in the same commit? (probably can). Could
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
640 # cause problems if instead of revnum -1,
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
641 # we have to look in (copyfrom_path, revnum - 1)
6539
7814d7bb77bc convert: rename get_entry_from_path() into an svn_source method
Patrick Mezard <pmezard@gmail.com>
parents: 6538
diff changeset
642 entrypath = self.getrelpath("/" + child, module=old_module)
5120
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
643 if entrypath:
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
644 entry = self.recode(entrypath.decode(self.encoding))
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
645 if entry in copies:
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
646 # deleted file within a copy
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
647 del copies[entry]
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
648 else:
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
649 entries.append(entry)
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
650 else:
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
651 self.ui.debug('unknown path in revision %d: %s\n' % \
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
652 (revnum, path))
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
653 elif kind == svn.core.svn_node_dir:
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
654 # Should probably synthesize normal file entries
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
655 # and handle as above to clean up copy/rename handling.
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
656
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
657 # If the directory just had a prop change,
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
658 # then we shouldn't need to look for its children.
5870
0d583ade5817 convert: don't scan directories on property changes
Patrick Mezard <pmezard@gmail.com>
parents: 5854
diff changeset
659 if ent.action == 'M':
0d583ade5817 convert: don't scan directories on property changes
Patrick Mezard <pmezard@gmail.com>
parents: 5854
diff changeset
660 continue
0d583ade5817 convert: don't scan directories on property changes
Patrick Mezard <pmezard@gmail.com>
parents: 5854
diff changeset
661
5120
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
662 # Also this could create duplicate entries. Not sure
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
663 # whether this will matter. Maybe should make entries a set.
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
664 # print "Changed directory", revnum, path, ent.action, ent.copyfrom_path, ent.copyfrom_rev
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
665 # This will fail if a directory was copied
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
666 # from another branch and then some of its files
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
667 # were deleted in the same transaction.
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
668 children = self._find_children(path, revnum)
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
669 children.sort()
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
670 for child in children:
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
671 # Can we move a child directory and its
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
672 # parent in the same commit? (probably can). Could
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
673 # cause problems if instead of revnum -1,
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
674 # we have to look in (copyfrom_path, revnum - 1)
6539
7814d7bb77bc convert: rename get_entry_from_path() into an svn_source method
Patrick Mezard <pmezard@gmail.com>
parents: 6538
diff changeset
675 entrypath = self.getrelpath("/" + child)
5120
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
676 # print child, self.module, entrypath
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
677 if entrypath:
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
678 # Need to filter out directories here...
6848
59c40c60d8d8 convert: remove leading slash from ra.check_path inputs (issue 1236)
Patrick Mezard <pmezard@gmail.com>
parents: 6847
diff changeset
679 kind = self._checkpath(entrypath, revnum)
5120
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
680 if kind != svn.core.svn_node_dir:
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
681 entries.append(self.recode(entrypath))
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
682
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
683 # Copies here (must copy all from source)
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
684 # Probably not a real problem for us if
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
685 # source does not exist
6543
a6e2e60b34d0 convert: handle past or foreign partial svn copies
Patrick Mezard <pmezard@gmail.com>
parents: 6542
diff changeset
686 if not ent.copyfrom_path or not parents:
6542
e7810e61f7c1 convert: more cleanup in svn directory copy handling
Patrick Mezard <pmezard@gmail.com>
parents: 6541
diff changeset
687 continue
6543
a6e2e60b34d0 convert: handle past or foreign partial svn copies
Patrick Mezard <pmezard@gmail.com>
parents: 6542
diff changeset
688 # Copy sources not in parent revisions cannot be represented,
a6e2e60b34d0 convert: handle past or foreign partial svn copies
Patrick Mezard <pmezard@gmail.com>
parents: 6542
diff changeset
689 # ignore their origin for now
a6e2e60b34d0 convert: handle past or foreign partial svn copies
Patrick Mezard <pmezard@gmail.com>
parents: 6542
diff changeset
690 pmodule, prevnum = self.revsplit(parents[0])[1:]
a6e2e60b34d0 convert: handle past or foreign partial svn copies
Patrick Mezard <pmezard@gmail.com>
parents: 6542
diff changeset
691 if ent.copyfrom_rev < prevnum:
a6e2e60b34d0 convert: handle past or foreign partial svn copies
Patrick Mezard <pmezard@gmail.com>
parents: 6542
diff changeset
692 continue
a6e2e60b34d0 convert: handle past or foreign partial svn copies
Patrick Mezard <pmezard@gmail.com>
parents: 6542
diff changeset
693 copyfrompath = ent.copyfrom_path.decode(self.encoding)
a6e2e60b34d0 convert: handle past or foreign partial svn copies
Patrick Mezard <pmezard@gmail.com>
parents: 6542
diff changeset
694 copyfrompath = self.getrelpath(copyfrompath, pmodule)
6542
e7810e61f7c1 convert: more cleanup in svn directory copy handling
Patrick Mezard <pmezard@gmail.com>
parents: 6541
diff changeset
695 if not copyfrompath:
e7810e61f7c1 convert: more cleanup in svn directory copy handling
Patrick Mezard <pmezard@gmail.com>
parents: 6541
diff changeset
696 continue
e7810e61f7c1 convert: more cleanup in svn directory copy handling
Patrick Mezard <pmezard@gmail.com>
parents: 6541
diff changeset
697 copyfrom[path] = ent
6553
0bb76d168437 remove trailing spaces
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6546
diff changeset
698 self.ui.debug("mark %s came from %s:%d\n"
6542
e7810e61f7c1 convert: more cleanup in svn directory copy handling
Patrick Mezard <pmezard@gmail.com>
parents: 6541
diff changeset
699 % (path, copyfrompath, ent.copyfrom_rev))
e7810e61f7c1 convert: more cleanup in svn directory copy handling
Patrick Mezard <pmezard@gmail.com>
parents: 6541
diff changeset
700 children = self._find_children(ent.copyfrom_path, ent.copyfrom_rev)
e7810e61f7c1 convert: more cleanup in svn directory copy handling
Patrick Mezard <pmezard@gmail.com>
parents: 6541
diff changeset
701 children.sort()
e7810e61f7c1 convert: more cleanup in svn directory copy handling
Patrick Mezard <pmezard@gmail.com>
parents: 6541
diff changeset
702 for child in children:
6543
a6e2e60b34d0 convert: handle past or foreign partial svn copies
Patrick Mezard <pmezard@gmail.com>
parents: 6542
diff changeset
703 entrypath = self.getrelpath("/" + child, pmodule)
6542
e7810e61f7c1 convert: more cleanup in svn directory copy handling
Patrick Mezard <pmezard@gmail.com>
parents: 6541
diff changeset
704 if not entrypath:
e7810e61f7c1 convert: more cleanup in svn directory copy handling
Patrick Mezard <pmezard@gmail.com>
parents: 6541
diff changeset
705 continue
e7810e61f7c1 convert: more cleanup in svn directory copy handling
Patrick Mezard <pmezard@gmail.com>
parents: 6541
diff changeset
706 entry = entrypath.decode(self.encoding)
e7810e61f7c1 convert: more cleanup in svn directory copy handling
Patrick Mezard <pmezard@gmail.com>
parents: 6541
diff changeset
707 copytopath = path + entry[len(copyfrompath):]
e7810e61f7c1 convert: more cleanup in svn directory copy handling
Patrick Mezard <pmezard@gmail.com>
parents: 6541
diff changeset
708 copytopath = self.getrelpath(copytopath)
6543
a6e2e60b34d0 convert: handle past or foreign partial svn copies
Patrick Mezard <pmezard@gmail.com>
parents: 6542
diff changeset
709 copies[self.recode(copytopath)] = self.recode(entry, pmodule)
5120
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
710
5883
a893610f6f0c convert: enforce svn_source.getchanges() files unicity
Patrick Mezard <pmezard@gmail.com>
parents: 5880
diff changeset
711 return (util.unique(entries), copies)
5120
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
712
5871
c1244685425a convert: fix parents of last fetched svn revision
Patrick Mezard <pmezard@gmail.com>
parents: 5870
diff changeset
713 def _fetch_revisions(self, from_revnum, to_revnum):
c1244685425a convert: fix parents of last fetched svn revision
Patrick Mezard <pmezard@gmail.com>
parents: 5870
diff changeset
714 if from_revnum < to_revnum:
c1244685425a convert: fix parents of last fetched svn revision
Patrick Mezard <pmezard@gmail.com>
parents: 5870
diff changeset
715 from_revnum, to_revnum = to_revnum, from_revnum
c1244685425a convert: fix parents of last fetched svn revision
Patrick Mezard <pmezard@gmail.com>
parents: 5870
diff changeset
716
4940
961379b2c586 convert/subversion: reduce memory usage by filtering early
Bryan O'Sullivan <bos@serpentine.com>
parents: 4927
diff changeset
717 self.child_cset = None
6545
a7492fb2107b convert: fix svn branch source detection corner case
Patrick Mezard <pmezard@gmail.com>
parents: 6544
diff changeset
718
a7492fb2107b convert: fix svn branch source detection corner case
Patrick Mezard <pmezard@gmail.com>
parents: 6544
diff changeset
719 def isdescendantof(parent, child):
a7492fb2107b convert: fix svn branch source detection corner case
Patrick Mezard <pmezard@gmail.com>
parents: 6544
diff changeset
720 if not child or not parent or not child.startswith(parent):
a7492fb2107b convert: fix svn branch source detection corner case
Patrick Mezard <pmezard@gmail.com>
parents: 6544
diff changeset
721 return False
a7492fb2107b convert: fix svn branch source detection corner case
Patrick Mezard <pmezard@gmail.com>
parents: 6544
diff changeset
722 subpath = child[len(parent):]
a7492fb2107b convert: fix svn branch source detection corner case
Patrick Mezard <pmezard@gmail.com>
parents: 6544
diff changeset
723 return len(subpath) > 1 and subpath[0] == '/'
a7492fb2107b convert: fix svn branch source detection corner case
Patrick Mezard <pmezard@gmail.com>
parents: 6544
diff changeset
724
4946
e8f4e40f285a convert/subversion: work around memory leak in svn's python bindings
Bryan O'Sullivan <bos@serpentine.com>
parents: 4944
diff changeset
725 def parselogentry(orig_paths, revnum, author, date, message):
6210
942287cb1f57 Removed trailing spaces from everything except test output
Thomas Arendsen Hein <thomas@intevation.de>
parents: 6173
diff changeset
726 """Return the parsed commit object or None, and True if
5872
7d4149cccc5d convert: fix cross-branches subversion revisions handling
Patrick Mezard <pmezard@gmail.com>
parents: 5871
diff changeset
727 the revision is a branch root.
7d4149cccc5d convert: fix cross-branches subversion revisions handling
Patrick Mezard <pmezard@gmail.com>
parents: 5871
diff changeset
728 """
4946
e8f4e40f285a convert/subversion: work around memory leak in svn's python bindings
Bryan O'Sullivan <bos@serpentine.com>
parents: 4944
diff changeset
729 self.ui.debug("parsing revision %d (%d changes)\n" %
e8f4e40f285a convert/subversion: work around memory leak in svn's python bindings
Bryan O'Sullivan <bos@serpentine.com>
parents: 4944
diff changeset
730 (revnum, len(orig_paths)))
4940
961379b2c586 convert/subversion: reduce memory usage by filtering early
Bryan O'Sullivan <bos@serpentine.com>
parents: 4927
diff changeset
731
5957
971a17af5982 convert: prevent svn branches to leave the root module tree
Patrick Mezard <pmezard@gmail.com>
parents: 5956
diff changeset
732 branched = False
4810
c2d529f288a1 convert: move some code into common init function
Brendan Cully <brendan@kublai.com>
parents: 4807
diff changeset
733 rev = self.revid(revnum)
4837
4cdbaa885d8a convert: svn: some improvements in memory usage
Brendan Cully <brendan@kublai.com>
parents: 4814
diff changeset
734 # branch log might return entries for a parent we already have
5871
c1244685425a convert: fix parents of last fetched svn revision
Patrick Mezard <pmezard@gmail.com>
parents: 5870
diff changeset
735
c1244685425a convert: fix parents of last fetched svn revision
Patrick Mezard <pmezard@gmail.com>
parents: 5870
diff changeset
736 if (rev in self.commits or revnum < to_revnum):
5957
971a17af5982 convert: prevent svn branches to leave the root module tree
Patrick Mezard <pmezard@gmail.com>
parents: 5956
diff changeset
737 return None, branched
4837
4cdbaa885d8a convert: svn: some improvements in memory usage
Brendan Cully <brendan@kublai.com>
parents: 4814
diff changeset
738
5120
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
739 parents = []
5958
59dce24933ad convert: follow svn module parent moves
Patrick Mezard <pmezard@gmail.com>
parents: 5957
diff changeset
740 # check whether this revision is the start of a branch or part
59dce24933ad convert: follow svn module parent moves
Patrick Mezard <pmezard@gmail.com>
parents: 5957
diff changeset
741 # of a branch renaming
59dce24933ad convert: follow svn module parent moves
Patrick Mezard <pmezard@gmail.com>
parents: 5957
diff changeset
742 orig_paths = orig_paths.items()
59dce24933ad convert: follow svn module parent moves
Patrick Mezard <pmezard@gmail.com>
parents: 5957
diff changeset
743 orig_paths.sort()
59dce24933ad convert: follow svn module parent moves
Patrick Mezard <pmezard@gmail.com>
parents: 5957
diff changeset
744 root_paths = [(p,e) for p,e in orig_paths if self.module.startswith(p)]
59dce24933ad convert: follow svn module parent moves
Patrick Mezard <pmezard@gmail.com>
parents: 5957
diff changeset
745 if root_paths:
59dce24933ad convert: follow svn module parent moves
Patrick Mezard <pmezard@gmail.com>
parents: 5957
diff changeset
746 path, ent = root_paths[-1]
5119
4cef0b93969d convert: svn: hoist up branch creation check
Brendan Cully <brendan@kublai.com>
parents: 5118
diff changeset
747 if ent.copyfrom_path:
6553
0bb76d168437 remove trailing spaces
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6546
diff changeset
748 # If dir was moved while one of its file was removed
6545
a7492fb2107b convert: fix svn branch source detection corner case
Patrick Mezard <pmezard@gmail.com>
parents: 6544
diff changeset
749 # the log may look like:
a7492fb2107b convert: fix svn branch source detection corner case
Patrick Mezard <pmezard@gmail.com>
parents: 6544
diff changeset
750 # A /dir (from /dir:x)
a7492fb2107b convert: fix svn branch source detection corner case
Patrick Mezard <pmezard@gmail.com>
parents: 6544
diff changeset
751 # A /dir/a (from /dir/a:y)
a7492fb2107b convert: fix svn branch source detection corner case
Patrick Mezard <pmezard@gmail.com>
parents: 6544
diff changeset
752 # A /dir/b (from /dir/b:z)
a7492fb2107b convert: fix svn branch source detection corner case
Patrick Mezard <pmezard@gmail.com>
parents: 6544
diff changeset
753 # ...
a7492fb2107b convert: fix svn branch source detection corner case
Patrick Mezard <pmezard@gmail.com>
parents: 6544
diff changeset
754 # for all remaining children.
a7492fb2107b convert: fix svn branch source detection corner case
Patrick Mezard <pmezard@gmail.com>
parents: 6544
diff changeset
755 # Let's take the highest child element from rev as source.
6553
0bb76d168437 remove trailing spaces
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6546
diff changeset
756 copies = [(p,e) for p,e in orig_paths[:-1]
6545
a7492fb2107b convert: fix svn branch source detection corner case
Patrick Mezard <pmezard@gmail.com>
parents: 6544
diff changeset
757 if isdescendantof(ent.copyfrom_path, e.copyfrom_path)]
a7492fb2107b convert: fix svn branch source detection corner case
Patrick Mezard <pmezard@gmail.com>
parents: 6544
diff changeset
758 fromrev = max([e.copyfrom_rev for p,e in copies] + [ent.copyfrom_rev])
5957
971a17af5982 convert: prevent svn branches to leave the root module tree
Patrick Mezard <pmezard@gmail.com>
parents: 5956
diff changeset
759 branched = True
5958
59dce24933ad convert: follow svn module parent moves
Patrick Mezard <pmezard@gmail.com>
parents: 5957
diff changeset
760 newpath = ent.copyfrom_path + self.module[len(path):]
5119
4cef0b93969d convert: svn: hoist up branch creation check
Brendan Cully <brendan@kublai.com>
parents: 5118
diff changeset
761 # ent.copyfrom_rev may not be the actual last revision
6545
a7492fb2107b convert: fix svn branch source detection corner case
Patrick Mezard <pmezard@gmail.com>
parents: 6544
diff changeset
762 previd = self.latest(newpath, fromrev)
5957
971a17af5982 convert: prevent svn branches to leave the root module tree
Patrick Mezard <pmezard@gmail.com>
parents: 5956
diff changeset
763 if previd is not None:
971a17af5982 convert: prevent svn branches to leave the root module tree
Patrick Mezard <pmezard@gmail.com>
parents: 5956
diff changeset
764 prevmodule, prevnum = self.revsplit(previd)[1:]
6173
963000ed8cac convert: add shallow, single branch svn conversions via svn.startrev
Patrick Mezard <pmezard@gmail.com>
parents: 6172
diff changeset
765 if prevnum >= self.startrev:
963000ed8cac convert: add shallow, single branch svn conversions via svn.startrev
Patrick Mezard <pmezard@gmail.com>
parents: 6172
diff changeset
766 parents = [previd]
963000ed8cac convert: add shallow, single branch svn conversions via svn.startrev
Patrick Mezard <pmezard@gmail.com>
parents: 6172
diff changeset
767 self.ui.note('found parent of branch %s at %d: %s\n' %
963000ed8cac convert: add shallow, single branch svn conversions via svn.startrev
Patrick Mezard <pmezard@gmail.com>
parents: 6172
diff changeset
768 (self.module, prevnum, prevmodule))
5119
4cef0b93969d convert: svn: hoist up branch creation check
Brendan Cully <brendan@kublai.com>
parents: 5118
diff changeset
769 else:
4cef0b93969d convert: svn: hoist up branch creation check
Brendan Cully <brendan@kublai.com>
parents: 5118
diff changeset
770 self.ui.debug("No copyfrom path, don't know what to do.\n")
4cef0b93969d convert: svn: hoist up branch creation check
Brendan Cully <brendan@kublai.com>
parents: 5118
diff changeset
771
5120
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
772 paths = []
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
773 # filter out unrelated paths
4940
961379b2c586 convert/subversion: reduce memory usage by filtering early
Bryan O'Sullivan <bos@serpentine.com>
parents: 4927
diff changeset
774 for path, ent in orig_paths:
6540
55bd855fc0af convert: improve subversion branch filtering
Patrick Mezard <pmezard@gmail.com>
parents: 6539
diff changeset
775 if self.getrelpath(path) is None:
4788
62e1b6412b62 convert: svn: add an early return to move most changeset parsing out an indent level
Brendan Cully <brendan@kublai.com>
parents: 4787
diff changeset
776 continue
5120
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
777 paths.append((path, ent))
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
778
4788
62e1b6412b62 convert: svn: add an early return to move most changeset parsing out an indent level
Brendan Cully <brendan@kublai.com>
parents: 4787
diff changeset
779 # Example SVN datetime. Includes microseconds.
62e1b6412b62 convert: svn: add an early return to move most changeset parsing out an indent level
Brendan Cully <brendan@kublai.com>
parents: 4787
diff changeset
780 # ISO-8601 conformant
62e1b6412b62 convert: svn: add an early return to move most changeset parsing out an indent level
Brendan Cully <brendan@kublai.com>
parents: 4787
diff changeset
781 # '2007-01-04T17:35:00.902377Z'
5617
924fd86f0579 convert: fix SVN date parser dropping the final whole second digit
David J. Mellor <dmellor@whistlingcat.com>
parents: 5521
diff changeset
782 date = util.parsedate(date[:19] + " UTC", ["%Y-%m-%dT%H:%M:%S"])
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
783
5916
b6deda0f69fa convert: Do not abort with TypeError if svn commit message is None (issue934)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5883
diff changeset
784 log = message and self.recode(message) or ''
4788
62e1b6412b62 convert: svn: add an early return to move most changeset parsing out an indent level
Brendan Cully <brendan@kublai.com>
parents: 4787
diff changeset
785 author = author and self.recode(author) or ''
5120
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
786 try:
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
787 branch = self.module.split("/")[-1]
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
788 if branch == 'trunk':
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
789 branch = ''
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
790 except IndexError:
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
791 branch = None
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
792
4788
62e1b6412b62 convert: svn: add an early return to move most changeset parsing out an indent level
Brendan Cully <brendan@kublai.com>
parents: 4787
diff changeset
793 cset = commit(author=author,
4957
cdd33a048289 removed trailing whitespace
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4949
diff changeset
794 date=util.datestr(date),
cdd33a048289 removed trailing whitespace
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4949
diff changeset
795 desc=log,
4795
ea618c5934f3 convert: svn: get parent for branch creation events
Brendan Cully <brendan@kublai.com>
parents: 4794
diff changeset
796 parents=parents,
4873
28b23b9073a8 convert: record the source revision in the changelog
Brendan Cully <brendan@kublai.com>
parents: 4848
diff changeset
797 branch=branch,
28b23b9073a8 convert: record the source revision in the changelog
Brendan Cully <brendan@kublai.com>
parents: 4848
diff changeset
798 rev=rev.encode('utf-8'))
4788
62e1b6412b62 convert: svn: add an early return to move most changeset parsing out an indent level
Brendan Cully <brendan@kublai.com>
parents: 4787
diff changeset
799
4796
26857a6f9dd0 convert: svn: pull out broken batching code, add alpha tags support
Brendan Cully <brendan@kublai.com>
parents: 4795
diff changeset
800 self.commits[rev] = cset
5872
7d4149cccc5d convert: fix cross-branches subversion revisions handling
Patrick Mezard <pmezard@gmail.com>
parents: 5871
diff changeset
801 # The parents list is *shared* among self.paths and the
7d4149cccc5d convert: fix cross-branches subversion revisions handling
Patrick Mezard <pmezard@gmail.com>
parents: 5871
diff changeset
802 # commit object. Both will be updated below.
7d4149cccc5d convert: fix cross-branches subversion revisions handling
Patrick Mezard <pmezard@gmail.com>
parents: 5871
diff changeset
803 self.paths[rev] = (paths, cset.parents)
4796
26857a6f9dd0 convert: svn: pull out broken batching code, add alpha tags support
Brendan Cully <brendan@kublai.com>
parents: 4795
diff changeset
804 if self.child_cset and not self.child_cset.parents:
5872
7d4149cccc5d convert: fix cross-branches subversion revisions handling
Patrick Mezard <pmezard@gmail.com>
parents: 5871
diff changeset
805 self.child_cset.parents[:] = [rev]
4788
62e1b6412b62 convert: svn: add an early return to move most changeset parsing out an indent level
Brendan Cully <brendan@kublai.com>
parents: 4787
diff changeset
806 self.child_cset = cset
5957
971a17af5982 convert: prevent svn branches to leave the root module tree
Patrick Mezard <pmezard@gmail.com>
parents: 5956
diff changeset
807 return cset, branched
4796
26857a6f9dd0 convert: svn: pull out broken batching code, add alpha tags support
Brendan Cully <brendan@kublai.com>
parents: 4795
diff changeset
808
4940
961379b2c586 convert/subversion: reduce memory usage by filtering early
Bryan O'Sullivan <bos@serpentine.com>
parents: 4927
diff changeset
809 self.ui.note('fetching revision log for "%s" from %d to %d\n' %
4797
09dae950919f convert: svn: autodetect /branches, /tags, /trunk.
Brendan Cully <brendan@kublai.com>
parents: 4796
diff changeset
810 (self.module, from_revnum, to_revnum))
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
811
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
812 try:
5871
c1244685425a convert: fix parents of last fetched svn revision
Patrick Mezard <pmezard@gmail.com>
parents: 5870
diff changeset
813 firstcset = None
6173
963000ed8cac convert: add shallow, single branch svn conversions via svn.startrev
Patrick Mezard <pmezard@gmail.com>
parents: 6172
diff changeset
814 lastonbranch = False
6850
c6bb8fae3bd2 convert: normalize paths sent to svn get_log (issue 1219)
Patrick Mezard <pmezard@gmail.com>
parents: 6848
diff changeset
815 stream = self._getlog([self.module], from_revnum, to_revnum)
5873
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
816 try:
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
817 for entry in stream:
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
818 paths, revnum, author, date, message = entry
6173
963000ed8cac convert: add shallow, single branch svn conversions via svn.startrev
Patrick Mezard <pmezard@gmail.com>
parents: 6172
diff changeset
819 if revnum < self.startrev:
963000ed8cac convert: add shallow, single branch svn conversions via svn.startrev
Patrick Mezard <pmezard@gmail.com>
parents: 6172
diff changeset
820 lastonbranch = True
963000ed8cac convert: add shallow, single branch svn conversions via svn.startrev
Patrick Mezard <pmezard@gmail.com>
parents: 6172
diff changeset
821 break
5873
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
822 if self.is_blacklisted(revnum):
6210
942287cb1f57 Removed trailing spaces from everything except test output
Thomas Arendsen Hein <thomas@intevation.de>
parents: 6173
diff changeset
823 self.ui.note('skipping blacklisted revision %d\n'
5873
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
824 % revnum)
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
825 continue
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
826 if paths is None:
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
827 self.ui.debug('revision %d has no entries\n' % revnum)
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
828 continue
6210
942287cb1f57 Removed trailing spaces from everything except test output
Thomas Arendsen Hein <thomas@intevation.de>
parents: 6173
diff changeset
829 cset, lastonbranch = parselogentry(paths, revnum, author,
6173
963000ed8cac convert: add shallow, single branch svn conversions via svn.startrev
Patrick Mezard <pmezard@gmail.com>
parents: 6172
diff changeset
830 date, message)
5873
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
831 if cset:
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
832 firstcset = cset
6173
963000ed8cac convert: add shallow, single branch svn conversions via svn.startrev
Patrick Mezard <pmezard@gmail.com>
parents: 6172
diff changeset
833 if lastonbranch:
5873
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
834 break
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
835 finally:
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
836 stream.close()
5871
c1244685425a convert: fix parents of last fetched svn revision
Patrick Mezard <pmezard@gmail.com>
parents: 5870
diff changeset
837
6173
963000ed8cac convert: add shallow, single branch svn conversions via svn.startrev
Patrick Mezard <pmezard@gmail.com>
parents: 6172
diff changeset
838 if not lastonbranch and firstcset and not firstcset.parents:
5871
c1244685425a convert: fix parents of last fetched svn revision
Patrick Mezard <pmezard@gmail.com>
parents: 5870
diff changeset
839 # The first revision of the sequence (the last fetched one)
c1244685425a convert: fix parents of last fetched svn revision
Patrick Mezard <pmezard@gmail.com>
parents: 5870
diff changeset
840 # has invalid parents if not a branch root. Find the parent
c1244685425a convert: fix parents of last fetched svn revision
Patrick Mezard <pmezard@gmail.com>
parents: 5870
diff changeset
841 # revision now, if any.
c1244685425a convert: fix parents of last fetched svn revision
Patrick Mezard <pmezard@gmail.com>
parents: 5870
diff changeset
842 try:
c1244685425a convert: fix parents of last fetched svn revision
Patrick Mezard <pmezard@gmail.com>
parents: 5870
diff changeset
843 firstrevnum = self.revnum(firstcset.rev)
c1244685425a convert: fix parents of last fetched svn revision
Patrick Mezard <pmezard@gmail.com>
parents: 5870
diff changeset
844 if firstrevnum > 1:
c1244685425a convert: fix parents of last fetched svn revision
Patrick Mezard <pmezard@gmail.com>
parents: 5870
diff changeset
845 latest = self.latest(self.module, firstrevnum - 1)
5957
971a17af5982 convert: prevent svn branches to leave the root module tree
Patrick Mezard <pmezard@gmail.com>
parents: 5956
diff changeset
846 if latest:
971a17af5982 convert: prevent svn branches to leave the root module tree
Patrick Mezard <pmezard@gmail.com>
parents: 5956
diff changeset
847 firstcset.parents.append(latest)
7381
b965605dfb2e convert: be even more tolerant when detecting svn tags
Patrick Mezard <pmezard@gmail.com>
parents: 7184
diff changeset
848 except SvnPathNotFound:
5871
c1244685425a convert: fix parents of last fetched svn revision
Patrick Mezard <pmezard@gmail.com>
parents: 5870
diff changeset
849 pass
5140
792c1d979097 Replace _ with inst for catching exceptions to not shadow gettext.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5139
diff changeset
850 except SubversionException, (inst, num):
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
851 if num == svn.core.SVN_ERR_FS_NO_SUCH_REVISION:
6214
0f76c7dc8484 convert: Fix unbound name error in the subversion backend
Joel Rosdahl <joel@rosdahl.net>
parents: 6210
diff changeset
852 raise util.Abort('svn: branch has no revision %s' % to_revnum)
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
853 raise
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
854
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
855 def _getfile(self, file, rev):
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
856 io = StringIO()
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
857 # TODO: ra.get_file transmits the whole file instead of diffs.
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
858 mode = ''
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
859 try:
5872
7d4149cccc5d convert: fix cross-branches subversion revisions handling
Patrick Mezard <pmezard@gmail.com>
parents: 5871
diff changeset
860 new_module, revnum = self.revsplit(rev)[1:]
7d4149cccc5d convert: fix cross-branches subversion revisions handling
Patrick Mezard <pmezard@gmail.com>
parents: 5871
diff changeset
861 if self.module != new_module:
7d4149cccc5d convert: fix cross-branches subversion revisions handling
Patrick Mezard <pmezard@gmail.com>
parents: 5871
diff changeset
862 self.module = new_module
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
863 self.reparent(self.module)
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
864 info = svn.ra.get_file(self.ra, file, revnum, io)
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
865 if isinstance(info, list):
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
866 info = info[-1]
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
867 mode = ("svn:executable" in info) and 'x' or ''
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
868 mode = ("svn:special" in info) and 'l' or mode
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
869 except SubversionException, e:
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
870 notfound = (svn.core.SVN_ERR_FS_NOT_FOUND,
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
871 svn.core.SVN_ERR_RA_DAV_PATH_NOT_FOUND)
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
872 if e.apr_err in notfound: # File not found
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
873 raise IOError()
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
874 raise
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
875 data = io.getvalue()
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
876 if mode == 'l':
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
877 link_prefix = "link "
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
878 if data.startswith(link_prefix):
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
879 data = data[len(link_prefix):]
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
880 return data, mode
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
881
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
882 def _find_children(self, path, revnum):
5114
35f67dd712d0 convert: svn: ensure leading / is removed from paths in _find_children (broken in 2bd996d0aaf8)
Brendan Cully <brendan@kublai.com>
parents: 5050
diff changeset
883 path = path.strip('/')
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
884 pool = Pool()
7074
b1a4f67b98d0 convert: properly encode subversion URLs (issue 1224)
Patrick Mezard <pmezard@gmail.com>
parents: 6877
diff changeset
885 rpath = '/'.join([self.baseurl, urllib.quote(path)]).strip('/')
7184
380fda3eed13 clean up trailing spaces
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7074
diff changeset
886 return ['%s/%s' % (path, x) for x in
7074
b1a4f67b98d0 convert: properly encode subversion URLs (issue 1224)
Patrick Mezard <pmezard@gmail.com>
parents: 6877
diff changeset
887 svn.client.ls(rpath, optrev(revnum), True, self.ctx, pool).keys()]
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
888
6539
7814d7bb77bc convert: rename get_entry_from_path() into an svn_source method
Patrick Mezard <pmezard@gmail.com>
parents: 6538
diff changeset
889 def getrelpath(self, path, module=None):
7814d7bb77bc convert: rename get_entry_from_path() into an svn_source method
Patrick Mezard <pmezard@gmail.com>
parents: 6538
diff changeset
890 if module is None:
7814d7bb77bc convert: rename get_entry_from_path() into an svn_source method
Patrick Mezard <pmezard@gmail.com>
parents: 6538
diff changeset
891 module = self.module
7814d7bb77bc convert: rename get_entry_from_path() into an svn_source method
Patrick Mezard <pmezard@gmail.com>
parents: 6538
diff changeset
892 # Given the repository url of this wc, say
7814d7bb77bc convert: rename get_entry_from_path() into an svn_source method
Patrick Mezard <pmezard@gmail.com>
parents: 6538
diff changeset
893 # "http://server/plone/CMFPlone/branches/Plone-2_0-branch"
7814d7bb77bc convert: rename get_entry_from_path() into an svn_source method
Patrick Mezard <pmezard@gmail.com>
parents: 6538
diff changeset
894 # extract the "entry" portion (a relative path) from what
7814d7bb77bc convert: rename get_entry_from_path() into an svn_source method
Patrick Mezard <pmezard@gmail.com>
parents: 6538
diff changeset
895 # svn log --xml says, ie
7814d7bb77bc convert: rename get_entry_from_path() into an svn_source method
Patrick Mezard <pmezard@gmail.com>
parents: 6538
diff changeset
896 # "/CMFPlone/branches/Plone-2_0-branch/tests/PloneTestCase.py"
7814d7bb77bc convert: rename get_entry_from_path() into an svn_source method
Patrick Mezard <pmezard@gmail.com>
parents: 6538
diff changeset
897 # that is to say "tests/PloneTestCase.py"
7814d7bb77bc convert: rename get_entry_from_path() into an svn_source method
Patrick Mezard <pmezard@gmail.com>
parents: 6538
diff changeset
898 if path.startswith(module):
7814d7bb77bc convert: rename get_entry_from_path() into an svn_source method
Patrick Mezard <pmezard@gmail.com>
parents: 6538
diff changeset
899 relative = path.rstrip('/')[len(module):]
7814d7bb77bc convert: rename get_entry_from_path() into an svn_source method
Patrick Mezard <pmezard@gmail.com>
parents: 6538
diff changeset
900 if relative.startswith('/'):
7814d7bb77bc convert: rename get_entry_from_path() into an svn_source method
Patrick Mezard <pmezard@gmail.com>
parents: 6538
diff changeset
901 return relative[1:]
7814d7bb77bc convert: rename get_entry_from_path() into an svn_source method
Patrick Mezard <pmezard@gmail.com>
parents: 6538
diff changeset
902 elif relative == '':
7814d7bb77bc convert: rename get_entry_from_path() into an svn_source method
Patrick Mezard <pmezard@gmail.com>
parents: 6538
diff changeset
903 return relative
7814d7bb77bc convert: rename get_entry_from_path() into an svn_source method
Patrick Mezard <pmezard@gmail.com>
parents: 6538
diff changeset
904
7814d7bb77bc convert: rename get_entry_from_path() into an svn_source method
Patrick Mezard <pmezard@gmail.com>
parents: 6538
diff changeset
905 # The path is outside our tracked tree...
7814d7bb77bc convert: rename get_entry_from_path() into an svn_source method
Patrick Mezard <pmezard@gmail.com>
parents: 6538
diff changeset
906 self.ui.debug('%r is not under %r, ignoring\n' % (path, module))
7814d7bb77bc convert: rename get_entry_from_path() into an svn_source method
Patrick Mezard <pmezard@gmail.com>
parents: 6538
diff changeset
907 return None
7814d7bb77bc convert: rename get_entry_from_path() into an svn_source method
Patrick Mezard <pmezard@gmail.com>
parents: 6538
diff changeset
908
6848
59c40c60d8d8 convert: remove leading slash from ra.check_path inputs (issue 1236)
Patrick Mezard <pmezard@gmail.com>
parents: 6847
diff changeset
909 def _checkpath(self, path, revnum):
59c40c60d8d8 convert: remove leading slash from ra.check_path inputs (issue 1236)
Patrick Mezard <pmezard@gmail.com>
parents: 6847
diff changeset
910 # ra.check_path does not like leading slashes very much, it leads
59c40c60d8d8 convert: remove leading slash from ra.check_path inputs (issue 1236)
Patrick Mezard <pmezard@gmail.com>
parents: 6847
diff changeset
911 # to PROPFIND subversion errors
59c40c60d8d8 convert: remove leading slash from ra.check_path inputs (issue 1236)
Patrick Mezard <pmezard@gmail.com>
parents: 6847
diff changeset
912 return svn.ra.check_path(self.ra, path.strip('/'), revnum)
59c40c60d8d8 convert: remove leading slash from ra.check_path inputs (issue 1236)
Patrick Mezard <pmezard@gmail.com>
parents: 6847
diff changeset
913
6850
c6bb8fae3bd2 convert: normalize paths sent to svn get_log (issue 1219)
Patrick Mezard <pmezard@gmail.com>
parents: 6848
diff changeset
914 def _getlog(self, paths, start, end, limit=0, discover_changed_paths=True,
c6bb8fae3bd2 convert: normalize paths sent to svn get_log (issue 1219)
Patrick Mezard <pmezard@gmail.com>
parents: 6848
diff changeset
915 strict_node_history=False):
c6bb8fae3bd2 convert: normalize paths sent to svn get_log (issue 1219)
Patrick Mezard <pmezard@gmail.com>
parents: 6848
diff changeset
916 # Normalize path names, svn >= 1.5 only wants paths relative to
c6bb8fae3bd2 convert: normalize paths sent to svn get_log (issue 1219)
Patrick Mezard <pmezard@gmail.com>
parents: 6848
diff changeset
917 # supplied URL
c6bb8fae3bd2 convert: normalize paths sent to svn get_log (issue 1219)
Patrick Mezard <pmezard@gmail.com>
parents: 6848
diff changeset
918 relpaths = []
c6bb8fae3bd2 convert: normalize paths sent to svn get_log (issue 1219)
Patrick Mezard <pmezard@gmail.com>
parents: 6848
diff changeset
919 for p in paths:
c6bb8fae3bd2 convert: normalize paths sent to svn get_log (issue 1219)
Patrick Mezard <pmezard@gmail.com>
parents: 6848
diff changeset
920 if not p.startswith('/'):
c6bb8fae3bd2 convert: normalize paths sent to svn get_log (issue 1219)
Patrick Mezard <pmezard@gmail.com>
parents: 6848
diff changeset
921 p = self.module + '/' + p
c6bb8fae3bd2 convert: normalize paths sent to svn get_log (issue 1219)
Patrick Mezard <pmezard@gmail.com>
parents: 6848
diff changeset
922 relpaths.append(p.strip('/'))
7074
b1a4f67b98d0 convert: properly encode subversion URLs (issue 1224)
Patrick Mezard <pmezard@gmail.com>
parents: 6877
diff changeset
923 args = [self.baseurl, relpaths, start, end, limit, discover_changed_paths,
6850
c6bb8fae3bd2 convert: normalize paths sent to svn get_log (issue 1219)
Patrick Mezard <pmezard@gmail.com>
parents: 6848
diff changeset
924 strict_node_history]
c6bb8fae3bd2 convert: normalize paths sent to svn get_log (issue 1219)
Patrick Mezard <pmezard@gmail.com>
parents: 6848
diff changeset
925 arg = encodeargs(args)
c6bb8fae3bd2 convert: normalize paths sent to svn get_log (issue 1219)
Patrick Mezard <pmezard@gmail.com>
parents: 6848
diff changeset
926 hgexe = util.hgexecutable()
c6bb8fae3bd2 convert: normalize paths sent to svn get_log (issue 1219)
Patrick Mezard <pmezard@gmail.com>
parents: 6848
diff changeset
927 cmd = '%s debugsvnlog' % util.shellquote(hgexe)
c6bb8fae3bd2 convert: normalize paths sent to svn get_log (issue 1219)
Patrick Mezard <pmezard@gmail.com>
parents: 6848
diff changeset
928 stdin, stdout = os.popen2(cmd, 'b')
c6bb8fae3bd2 convert: normalize paths sent to svn get_log (issue 1219)
Patrick Mezard <pmezard@gmail.com>
parents: 6848
diff changeset
929 stdin.write(arg)
c6bb8fae3bd2 convert: normalize paths sent to svn get_log (issue 1219)
Patrick Mezard <pmezard@gmail.com>
parents: 6848
diff changeset
930 stdin.close()
c6bb8fae3bd2 convert: normalize paths sent to svn get_log (issue 1219)
Patrick Mezard <pmezard@gmail.com>
parents: 6848
diff changeset
931 return logstream(stdout)
c6bb8fae3bd2 convert: normalize paths sent to svn get_log (issue 1219)
Patrick Mezard <pmezard@gmail.com>
parents: 6848
diff changeset
932
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
933 pre_revprop_change = '''#!/bin/sh
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
934
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
935 REPOS="$1"
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
936 REV="$2"
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
937 USER="$3"
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
938 PROPNAME="$4"
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
939 ACTION="$5"
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
940
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
941 if [ "$ACTION" = "M" -a "$PROPNAME" = "svn:log" ]; then exit 0; fi
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
942 if [ "$ACTION" = "A" -a "$PROPNAME" = "hg:convert-branch" ]; then exit 0; fi
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
943 if [ "$ACTION" = "A" -a "$PROPNAME" = "hg:convert-rev" ]; then exit 0; fi
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
944
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
945 echo "Changing prohibited revision property" >&2
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
946 exit 1
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
947 '''
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
948
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
949 class svn_sink(converter_sink, commandline):
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
950 commit_re = re.compile(r'Committed revision (\d+).', re.M)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
951
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
952 def prerun(self):
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
953 if self.wc:
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
954 os.chdir(self.wc)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
955
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
956 def postrun(self):
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
957 if self.wc:
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
958 os.chdir(self.cwd)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
959
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
960 def join(self, name):
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
961 return os.path.join(self.wc, '.svn', name)
5760
0145f9afb0e7 Removed tabs and trailing whitespace in python files
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5705
diff changeset
962
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
963 def revmapfile(self):
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
964 return self.join('hg-shamap')
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
965
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
966 def authorfile(self):
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
967 return self.join('hg-authormap')
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
968
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
969 def __init__(self, ui, path):
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
970 converter_sink.__init__(self, ui, path)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
971 commandline.__init__(self, ui, 'svn')
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
972 self.delete = []
5698
b63ef7b1441c convert: svn-sink: copy and set properties after adding dirs/files
Maxim Dounin <mdounin@mdounin.ru>
parents: 5618
diff changeset
973 self.setexec = []
b63ef7b1441c convert: svn-sink: copy and set properties after adding dirs/files
Maxim Dounin <mdounin@mdounin.ru>
parents: 5618
diff changeset
974 self.delexec = []
b63ef7b1441c convert: svn-sink: copy and set properties after adding dirs/files
Maxim Dounin <mdounin@mdounin.ru>
parents: 5618
diff changeset
975 self.copies = []
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
976 self.wc = None
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
977 self.cwd = os.getcwd()
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
978
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
979 path = os.path.realpath(path)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
980
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
981 created = False
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
982 if os.path.isfile(os.path.join(path, '.svn', 'entries')):
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
983 self.wc = path
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
984 self.run0('update')
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
985 else:
5535
7501ef26402b convert: fix svn file:// URL generation under Windows
Patrick Mezard <pmezard@gmail.com>
parents: 5528
diff changeset
986 wcpath = os.path.join(os.getcwd(), os.path.basename(path) + '-wc')
7501ef26402b convert: fix svn file:// URL generation under Windows
Patrick Mezard <pmezard@gmail.com>
parents: 5528
diff changeset
987
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
988 if os.path.isdir(os.path.dirname(path)):
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
989 if not os.path.exists(os.path.join(path, 'db', 'fs-type')):
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
990 ui.status(_('initializing svn repo %r\n') %
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
991 os.path.basename(path))
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
992 commandline(ui, 'svnadmin').run0('create', path)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
993 created = path
5842
111ed8c871bf Use util.normpath() instead of direct path string operation.
Shun-ichi GOTO <shunichi.goto@gmail.com>
parents: 5841
diff changeset
994 path = util.normpath(path)
5535
7501ef26402b convert: fix svn file:// URL generation under Windows
Patrick Mezard <pmezard@gmail.com>
parents: 5528
diff changeset
995 if not path.startswith('/'):
7501ef26402b convert: fix svn file:// URL generation under Windows
Patrick Mezard <pmezard@gmail.com>
parents: 5528
diff changeset
996 path = '/' + path
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
997 path = 'file://' + path
5760
0145f9afb0e7 Removed tabs and trailing whitespace in python files
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5705
diff changeset
998
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
999 ui.status(_('initializing svn wc %r\n') % os.path.basename(wcpath))
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1000 self.run0('checkout', path, wcpath)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1001
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1002 self.wc = wcpath
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1003 self.opener = util.opener(self.wc)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1004 self.wopener = util.opener(self.wc)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1005 self.childmap = mapfile(ui, self.join('hg-childmap'))
5536
fdee5d614fcc convert: force svn:executable when execute-bit is not supported
Patrick Mezard <pmezard@gmail.com>
parents: 5535
diff changeset
1006 self.is_exec = util.checkexec(self.wc) and util.is_exec or None
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1007
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1008 if created:
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1009 hook = os.path.join(created, 'hooks', 'pre-revprop-change')
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1010 fp = open(hook, 'w')
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1011 fp.write(pre_revprop_change)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1012 fp.close()
6877
1d38f3605b20 util: set_flags shouldn't know about repo flag formats
Matt Mackall <mpm@selenic.com>
parents: 6850
diff changeset
1013 util.set_flags(hook, False, True)
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1014
5554
2147a734dcf9 convert: tell the source repository when a rev has been converted
Bryan O'Sullivan <bos@serpentine.com>
parents: 5537
diff changeset
1015 xport = transport.SvnRaTransport(url=geturl(path))
2147a734dcf9 convert: tell the source repository when a rev has been converted
Bryan O'Sullivan <bos@serpentine.com>
parents: 5537
diff changeset
1016 self.uuid = svn.ra.get_uuid(xport.ra)
2147a734dcf9 convert: tell the source repository when a rev has been converted
Bryan O'Sullivan <bos@serpentine.com>
parents: 5537
diff changeset
1017
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1018 def wjoin(self, *names):
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1019 return os.path.join(self.wc, *names)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1020
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1021 def putfile(self, filename, flags, data):
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1022 if 'l' in flags:
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1023 self.wopener.symlink(data, filename)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1024 else:
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1025 try:
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1026 if os.path.islink(self.wjoin(filename)):
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1027 os.unlink(filename)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1028 except OSError:
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1029 pass
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1030 self.wopener(filename, 'w').write(data)
5536
fdee5d614fcc convert: force svn:executable when execute-bit is not supported
Patrick Mezard <pmezard@gmail.com>
parents: 5535
diff changeset
1031
fdee5d614fcc convert: force svn:executable when execute-bit is not supported
Patrick Mezard <pmezard@gmail.com>
parents: 5535
diff changeset
1032 if self.is_exec:
fdee5d614fcc convert: force svn:executable when execute-bit is not supported
Patrick Mezard <pmezard@gmail.com>
parents: 5535
diff changeset
1033 was_exec = self.is_exec(self.wjoin(filename))
fdee5d614fcc convert: force svn:executable when execute-bit is not supported
Patrick Mezard <pmezard@gmail.com>
parents: 5535
diff changeset
1034 else:
fdee5d614fcc convert: force svn:executable when execute-bit is not supported
Patrick Mezard <pmezard@gmail.com>
parents: 5535
diff changeset
1035 # On filesystems not supporting execute-bit, there is no way
fdee5d614fcc convert: force svn:executable when execute-bit is not supported
Patrick Mezard <pmezard@gmail.com>
parents: 5535
diff changeset
1036 # to know if it is set but asking subversion. Setting it
fdee5d614fcc convert: force svn:executable when execute-bit is not supported
Patrick Mezard <pmezard@gmail.com>
parents: 5535
diff changeset
1037 # systematically is just as expensive and much simpler.
fdee5d614fcc convert: force svn:executable when execute-bit is not supported
Patrick Mezard <pmezard@gmail.com>
parents: 5535
diff changeset
1038 was_exec = 'x' not in flags
fdee5d614fcc convert: force svn:executable when execute-bit is not supported
Patrick Mezard <pmezard@gmail.com>
parents: 5535
diff changeset
1039
6877
1d38f3605b20 util: set_flags shouldn't know about repo flag formats
Matt Mackall <mpm@selenic.com>
parents: 6850
diff changeset
1040 util.set_flags(self.wjoin(filename), False, 'x' in flags)
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1041 if was_exec:
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1042 if 'x' not in flags:
5698
b63ef7b1441c convert: svn-sink: copy and set properties after adding dirs/files
Maxim Dounin <mdounin@mdounin.ru>
parents: 5618
diff changeset
1043 self.delexec.append(filename)
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1044 else:
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1045 if 'x' in flags:
5698
b63ef7b1441c convert: svn-sink: copy and set properties after adding dirs/files
Maxim Dounin <mdounin@mdounin.ru>
parents: 5618
diff changeset
1046 self.setexec.append(filename)
b63ef7b1441c convert: svn-sink: copy and set properties after adding dirs/files
Maxim Dounin <mdounin@mdounin.ru>
parents: 5618
diff changeset
1047
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1048 def delfile(self, name):
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1049 self.delete.append(name)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1050
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1051 def copyfile(self, source, dest):
5698
b63ef7b1441c convert: svn-sink: copy and set properties after adding dirs/files
Maxim Dounin <mdounin@mdounin.ru>
parents: 5618
diff changeset
1052 self.copies.append([source, dest])
b63ef7b1441c convert: svn-sink: copy and set properties after adding dirs/files
Maxim Dounin <mdounin@mdounin.ru>
parents: 5618
diff changeset
1053
b63ef7b1441c convert: svn-sink: copy and set properties after adding dirs/files
Maxim Dounin <mdounin@mdounin.ru>
parents: 5618
diff changeset
1054 def _copyfile(self, source, dest):
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1055 # SVN's copy command pukes if the destination file exists, but
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1056 # our copyfile method expects to record a copy that has
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1057 # already occurred. Cross the semantic gap.
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1058 wdest = self.wjoin(dest)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1059 exists = os.path.exists(wdest)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1060 if exists:
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1061 fd, tempname = tempfile.mkstemp(
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1062 prefix='hg-copy-', dir=os.path.dirname(wdest))
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1063 os.close(fd)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1064 os.unlink(tempname)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1065 os.rename(wdest, tempname)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1066 try:
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1067 self.run0('copy', source, dest)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1068 finally:
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1069 if exists:
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1070 try:
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1071 os.unlink(wdest)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1072 except OSError:
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1073 pass
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1074 os.rename(tempname, wdest)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1075
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1076 def dirs_of(self, files):
6053
4e87e785c5bf convert: Compatibility fixes for python2.3
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5958
diff changeset
1077 dirs = util.set()
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1078 for f in files:
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1079 if os.path.isdir(self.wjoin(f)):
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1080 dirs.add(f)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1081 for i in strutil.rfindall(f, '/'):
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1082 dirs.add(f[:i])
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1083 return dirs
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1084
5698
b63ef7b1441c convert: svn-sink: copy and set properties after adding dirs/files
Maxim Dounin <mdounin@mdounin.ru>
parents: 5618
diff changeset
1085 def add_dirs(self, files):
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1086 add_dirs = [d for d in self.dirs_of(files)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1087 if not os.path.exists(self.wjoin(d, '.svn', 'entries'))]
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1088 if add_dirs:
5537
e01c748cb632 convert: add directories to subversion from root to leaves
Patrick Mezard <pmezard@gmail.com>
parents: 5536
diff changeset
1089 add_dirs.sort()
5832
2192ed187319 convert: add commandline.xargs(), use it in svn_sink class
Maxim Dounin <mdounin@mdounin.ru>
parents: 5806
diff changeset
1090 self.xargs(add_dirs, 'add', non_recursive=True, quiet=True)
5698
b63ef7b1441c convert: svn-sink: copy and set properties after adding dirs/files
Maxim Dounin <mdounin@mdounin.ru>
parents: 5618
diff changeset
1091 return add_dirs
b63ef7b1441c convert: svn-sink: copy and set properties after adding dirs/files
Maxim Dounin <mdounin@mdounin.ru>
parents: 5618
diff changeset
1092
b63ef7b1441c convert: svn-sink: copy and set properties after adding dirs/files
Maxim Dounin <mdounin@mdounin.ru>
parents: 5618
diff changeset
1093 def add_files(self, files):
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1094 if files:
5832
2192ed187319 convert: add commandline.xargs(), use it in svn_sink class
Maxim Dounin <mdounin@mdounin.ru>
parents: 5806
diff changeset
1095 self.xargs(files, 'add', quiet=True)
5698
b63ef7b1441c convert: svn-sink: copy and set properties after adding dirs/files
Maxim Dounin <mdounin@mdounin.ru>
parents: 5618
diff changeset
1096 return files
5760
0145f9afb0e7 Removed tabs and trailing whitespace in python files
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5705
diff changeset
1097
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1098 def tidy_dirs(self, names):
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1099 dirs = list(self.dirs_of(names))
6053
4e87e785c5bf convert: Compatibility fixes for python2.3
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5958
diff changeset
1100 dirs.sort()
4e87e785c5bf convert: Compatibility fixes for python2.3
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5958
diff changeset
1101 dirs.reverse()
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1102 deleted = []
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1103 for d in dirs:
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1104 wd = self.wjoin(d)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1105 if os.listdir(wd) == '.svn':
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1106 self.run0('delete', d)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1107 deleted.append(d)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1108 return deleted
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1109
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1110 def addchild(self, parent, child):
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1111 self.childmap[parent] = child
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1112
5554
2147a734dcf9 convert: tell the source repository when a rev has been converted
Bryan O'Sullivan <bos@serpentine.com>
parents: 5537
diff changeset
1113 def revid(self, rev):
2147a734dcf9 convert: tell the source repository when a rev has been converted
Bryan O'Sullivan <bos@serpentine.com>
parents: 5537
diff changeset
1114 return u"svn:%s@%s" % (self.uuid, rev)
5698
b63ef7b1441c convert: svn-sink: copy and set properties after adding dirs/files
Maxim Dounin <mdounin@mdounin.ru>
parents: 5618
diff changeset
1115
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1116 def putcommit(self, files, parents, commit):
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1117 for parent in parents:
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1118 try:
5554
2147a734dcf9 convert: tell the source repository when a rev has been converted
Bryan O'Sullivan <bos@serpentine.com>
parents: 5537
diff changeset
1119 return self.revid(self.childmap[parent])
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1120 except KeyError:
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1121 pass
6053
4e87e785c5bf convert: Compatibility fixes for python2.3
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5958
diff changeset
1122 entries = util.set(self.delete)
5698
b63ef7b1441c convert: svn-sink: copy and set properties after adding dirs/files
Maxim Dounin <mdounin@mdounin.ru>
parents: 5618
diff changeset
1123 files = util.frozenset(files)
b63ef7b1441c convert: svn-sink: copy and set properties after adding dirs/files
Maxim Dounin <mdounin@mdounin.ru>
parents: 5618
diff changeset
1124 entries.update(self.add_dirs(files.difference(entries)))
b63ef7b1441c convert: svn-sink: copy and set properties after adding dirs/files
Maxim Dounin <mdounin@mdounin.ru>
parents: 5618
diff changeset
1125 if self.copies:
b63ef7b1441c convert: svn-sink: copy and set properties after adding dirs/files
Maxim Dounin <mdounin@mdounin.ru>
parents: 5618
diff changeset
1126 for s, d in self.copies:
b63ef7b1441c convert: svn-sink: copy and set properties after adding dirs/files
Maxim Dounin <mdounin@mdounin.ru>
parents: 5618
diff changeset
1127 self._copyfile(s, d)
b63ef7b1441c convert: svn-sink: copy and set properties after adding dirs/files
Maxim Dounin <mdounin@mdounin.ru>
parents: 5618
diff changeset
1128 self.copies = []
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1129 if self.delete:
5832
2192ed187319 convert: add commandline.xargs(), use it in svn_sink class
Maxim Dounin <mdounin@mdounin.ru>
parents: 5806
diff changeset
1130 self.xargs(self.delete, 'delete')
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1131 self.delete = []
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1132 entries.update(self.add_files(files.difference(entries)))
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1133 entries.update(self.tidy_dirs(entries))
5698
b63ef7b1441c convert: svn-sink: copy and set properties after adding dirs/files
Maxim Dounin <mdounin@mdounin.ru>
parents: 5618
diff changeset
1134 if self.delexec:
5832
2192ed187319 convert: add commandline.xargs(), use it in svn_sink class
Maxim Dounin <mdounin@mdounin.ru>
parents: 5806
diff changeset
1135 self.xargs(self.delexec, 'propdel', 'svn:executable')
5698
b63ef7b1441c convert: svn-sink: copy and set properties after adding dirs/files
Maxim Dounin <mdounin@mdounin.ru>
parents: 5618
diff changeset
1136 self.delexec = []
b63ef7b1441c convert: svn-sink: copy and set properties after adding dirs/files
Maxim Dounin <mdounin@mdounin.ru>
parents: 5618
diff changeset
1137 if self.setexec:
5832
2192ed187319 convert: add commandline.xargs(), use it in svn_sink class
Maxim Dounin <mdounin@mdounin.ru>
parents: 5806
diff changeset
1138 self.xargs(self.setexec, 'propset', 'svn:executable', '*')
5698
b63ef7b1441c convert: svn-sink: copy and set properties after adding dirs/files
Maxim Dounin <mdounin@mdounin.ru>
parents: 5618
diff changeset
1139 self.setexec = []
b63ef7b1441c convert: svn-sink: copy and set properties after adding dirs/files
Maxim Dounin <mdounin@mdounin.ru>
parents: 5618
diff changeset
1140
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1141 fd, messagefile = tempfile.mkstemp(prefix='hg-convert-')
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1142 fp = os.fdopen(fd, 'w')
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1143 fp.write(commit.desc)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1144 fp.close()
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1145 try:
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1146 output = self.run0('commit',
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1147 username=util.shortuser(commit.author),
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1148 file=messagefile,
5790
f85c0034a062 convert: svn_sink: workaround of command line size limitation on win32.
Shun-ichi GOTO <shunichi.goto@gmail.com>
parents: 5789
diff changeset
1149 encoding='utf-8')
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1150 try:
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1151 rev = self.commit_re.search(output).group(1)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1152 except AttributeError:
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1153 self.ui.warn(_('unexpected svn output:\n'))
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1154 self.ui.warn(output)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1155 raise util.Abort(_('unable to cope with svn output'))
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1156 if commit.rev:
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1157 self.run('propset', 'hg:convert-rev', commit.rev,
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1158 revprop=True, revision=rev)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1159 if commit.branch and commit.branch != 'default':
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1160 self.run('propset', 'hg:convert-branch', commit.branch,
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1161 revprop=True, revision=rev)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1162 for parent in parents:
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1163 self.addchild(parent, rev)
5554
2147a734dcf9 convert: tell the source repository when a rev has been converted
Bryan O'Sullivan <bos@serpentine.com>
parents: 5537
diff changeset
1164 return self.revid(rev)
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1165 finally:
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1166 os.unlink(messagefile)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1167
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1168 def puttags(self, tags):
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
1169 self.ui.warn(_('XXX TAGS NOT IMPLEMENTED YET\n'))