Show More
@@ -29,7 +29,7 testedwith = 'internal' | |||||
29 | _('FILE')), |
|
29 | _('FILE')), | |
30 | ('s', 'source-type', '', _('source repository type'), _('TYPE')), |
|
30 | ('s', 'source-type', '', _('source repository type'), _('TYPE')), | |
31 | ('d', 'dest-type', '', _('destination repository type'), _('TYPE')), |
|
31 | ('d', 'dest-type', '', _('destination repository type'), _('TYPE')), | |
32 |
('r', 'rev', |
|
32 | ('r', 'rev', [], _('import up to source revision REV'), _('REV')), | |
33 | ('A', 'authormap', '', _('remap usernames using this file'), _('FILE')), |
|
33 | ('A', 'authormap', '', _('remap usernames using this file'), _('FILE')), | |
34 | ('', 'filemap', '', _('remap file names using contents of file'), |
|
34 | ('', 'filemap', '', _('remap file names using contents of file'), | |
35 | _('FILE')), |
|
35 | _('FILE')), |
@@ -33,8 +33,8 supportedkinds = ('file', 'symlink') | |||||
33 | class bzr_source(converter_source): |
|
33 | class bzr_source(converter_source): | |
34 | """Reads Bazaar repositories by using the Bazaar Python libraries""" |
|
34 | """Reads Bazaar repositories by using the Bazaar Python libraries""" | |
35 |
|
35 | |||
36 | def __init__(self, ui, path, rev=None): |
|
36 | def __init__(self, ui, path, revs=None): | |
37 | super(bzr_source, self).__init__(ui, path, rev=rev) |
|
37 | super(bzr_source, self).__init__(ui, path, revs=revs) | |
38 |
|
38 | |||
39 | if not os.path.exists(os.path.join(path, '.bzr')): |
|
39 | if not os.path.exists(os.path.join(path, '.bzr')): | |
40 | raise NoRepo(_('%s does not look like a Bazaar repository') |
|
40 | raise NoRepo(_('%s does not look like a Bazaar repository') | |
@@ -95,20 +95,20 class bzr_source(converter_source): | |||||
95 | return self.sourcerepo.find_branches(using=True) |
|
95 | return self.sourcerepo.find_branches(using=True) | |
96 |
|
96 | |||
97 | def getheads(self): |
|
97 | def getheads(self): | |
98 | if not self.rev: |
|
98 | if not self.revs: | |
99 | # Set using=True to avoid nested repositories (see issue3254) |
|
99 | # Set using=True to avoid nested repositories (see issue3254) | |
100 | heads = sorted([b.last_revision() for b in self._bzrbranches()]) |
|
100 | heads = sorted([b.last_revision() for b in self._bzrbranches()]) | |
101 | else: |
|
101 | else: | |
102 | revid = None |
|
102 | revid = None | |
103 | for branch in self._bzrbranches(): |
|
103 | for branch in self._bzrbranches(): | |
104 | try: |
|
104 | try: | |
105 | r = RevisionSpec.from_string(self.rev) |
|
105 | r = RevisionSpec.from_string(self.revs[0]) | |
106 | info = r.in_history(branch) |
|
106 | info = r.in_history(branch) | |
107 | except errors.BzrError: |
|
107 | except errors.BzrError: | |
108 | pass |
|
108 | pass | |
109 | revid = info.rev_id |
|
109 | revid = info.rev_id | |
110 | if revid is None: |
|
110 | if revid is None: | |
111 | raise util.Abort(_('%s is not a valid revision') % self.rev) |
|
111 | raise util.Abort(_('%s is not a valid revision') % self.revs[0]) | |
112 | heads = [revid] |
|
112 | heads = [revid] | |
113 | # Empty repositories return 'null:', which cannot be retrieved |
|
113 | # Empty repositories return 'null:', which cannot be retrieved | |
114 | heads = [h for h in heads if h != 'null:'] |
|
114 | heads = [h for h in heads if h != 'null:'] |
@@ -59,12 +59,12 class commit(object): | |||||
59 | class converter_source(object): |
|
59 | class converter_source(object): | |
60 | """Conversion source interface""" |
|
60 | """Conversion source interface""" | |
61 |
|
61 | |||
62 | def __init__(self, ui, path=None, rev=None): |
|
62 | def __init__(self, ui, path=None, revs=None): | |
63 | """Initialize conversion source (or raise NoRepo("message") |
|
63 | """Initialize conversion source (or raise NoRepo("message") | |
64 | exception if path is not a valid repository)""" |
|
64 | exception if path is not a valid repository)""" | |
65 | self.ui = ui |
|
65 | self.ui = ui | |
66 | self.path = path |
|
66 | self.path = path | |
67 | self.rev = rev |
|
67 | self.revs = revs | |
68 |
|
68 | |||
69 | self.encoding = 'utf-8' |
|
69 | self.encoding = 'utf-8' | |
70 |
|
70 |
@@ -46,14 +46,14 sink_converters = [ | |||||
46 | ('svn', svn_sink), |
|
46 | ('svn', svn_sink), | |
47 | ] |
|
47 | ] | |
48 |
|
48 | |||
49 | def convertsource(ui, path, type, rev): |
|
49 | def convertsource(ui, path, type, revs): | |
50 | exceptions = [] |
|
50 | exceptions = [] | |
51 | if type and type not in [s[0] for s in source_converters]: |
|
51 | if type and type not in [s[0] for s in source_converters]: | |
52 | raise util.Abort(_('%s: invalid source repository type') % type) |
|
52 | raise util.Abort(_('%s: invalid source repository type') % type) | |
53 | for name, source, sortmode in source_converters: |
|
53 | for name, source, sortmode in source_converters: | |
54 | try: |
|
54 | try: | |
55 | if not type or name == type: |
|
55 | if not type or name == type: | |
56 | return source(ui, path, rev), sortmode |
|
56 | return source(ui, path, revs), sortmode | |
57 | except (NoRepo, MissingTool) as inst: |
|
57 | except (NoRepo, MissingTool) as inst: | |
58 | exceptions.append(inst) |
|
58 | exceptions.append(inst) | |
59 | if not ui.quiet: |
|
59 | if not ui.quiet: |
@@ -15,8 +15,8 from common import makedatetimestamp | |||||
15 | import cvsps |
|
15 | import cvsps | |
16 |
|
16 | |||
17 | class convert_cvs(converter_source): |
|
17 | class convert_cvs(converter_source): | |
18 | def __init__(self, ui, path, rev=None): |
|
18 | def __init__(self, ui, path, revs=None): | |
19 | super(convert_cvs, self).__init__(ui, path, rev=rev) |
|
19 | super(convert_cvs, self).__init__(ui, path, revs=revs) | |
20 |
|
20 | |||
21 | cvs = os.path.join(path, "CVS") |
|
21 | cvs = os.path.join(path, "CVS") | |
22 | if not os.path.exists(cvs): |
|
22 | if not os.path.exists(cvs): | |
@@ -41,14 +41,17 class convert_cvs(converter_source): | |||||
41 | self.changeset = {} |
|
41 | self.changeset = {} | |
42 |
|
42 | |||
43 | maxrev = 0 |
|
43 | maxrev = 0 | |
44 | if self.rev: |
|
44 | if self.revs: | |
|
45 | if len(self.revs) > 1: | |||
|
46 | raise util.Abort(_('cvs source does not support specifying ' | |||
|
47 | 'multiple revs')) | |||
45 | # TODO: handle tags |
|
48 | # TODO: handle tags | |
46 | try: |
|
49 | try: | |
47 | # patchset number? |
|
50 | # patchset number? | |
48 | maxrev = int(self.rev) |
|
51 | maxrev = int(self.revs[0]) | |
49 | except ValueError: |
|
52 | except ValueError: | |
50 | raise util.Abort(_('revision %s is not a patchset number') |
|
53 | raise util.Abort(_('revision %s is not a patchset number') | |
51 | % self.rev) |
|
54 | % self.revs[0]) | |
52 |
|
55 | |||
53 | d = os.getcwd() |
|
56 | d = os.getcwd() | |
54 | try: |
|
57 | try: |
@@ -27,8 +27,8 except ImportError: | |||||
27 | pass |
|
27 | pass | |
28 |
|
28 | |||
29 | class darcs_source(converter_source, commandline): |
|
29 | class darcs_source(converter_source, commandline): | |
30 | def __init__(self, ui, path, rev=None): |
|
30 | def __init__(self, ui, path, revs=None): | |
31 | converter_source.__init__(self, ui, path, rev=rev) |
|
31 | converter_source.__init__(self, ui, path, revs=revs) | |
32 | commandline.__init__(self, ui, 'darcs') |
|
32 | commandline.__init__(self, ui, 'darcs') | |
33 |
|
33 | |||
34 | # check for _darcs, ElementTree so that we can easily skip |
|
34 | # check for _darcs, ElementTree so that we can easily skip |
@@ -86,8 +86,12 class convert_git(converter_source): | |||||
86 | data = fh.read() |
|
86 | data = fh.read() | |
87 | return data, fh.close() |
|
87 | return data, fh.close() | |
88 |
|
88 | |||
89 | def __init__(self, ui, path, rev=None): |
|
89 | def __init__(self, ui, path, revs=None): | |
90 | super(convert_git, self).__init__(ui, path, rev=rev) |
|
90 | super(convert_git, self).__init__(ui, path, revs=revs) | |
|
91 | ||||
|
92 | if revs and len(revs) > 1: | |||
|
93 | raise util.Abort(_("git source does not support specifying " | |||
|
94 | "multiple revs")) | |||
91 |
|
95 | |||
92 | if os.path.isdir(path + "/.git"): |
|
96 | if os.path.isdir(path + "/.git"): | |
93 | path += "/.git" |
|
97 | path += "/.git" | |
@@ -119,11 +123,12 class convert_git(converter_source): | |||||
119 | f.close() |
|
123 | f.close() | |
120 |
|
124 | |||
121 | def getheads(self): |
|
125 | def getheads(self): | |
122 | if not self.rev: |
|
126 | if not self.revs: | |
123 | heads, ret = self.gitread('git rev-parse --branches --remotes') |
|
127 | heads, ret = self.gitread('git rev-parse --branches --remotes') | |
124 | heads = heads.splitlines() |
|
128 | heads = heads.splitlines() | |
125 | else: |
|
129 | else: | |
126 |
heads, ret = self.gitread("git rev-parse --verify %s" % |
|
130 | heads, ret = self.gitread("git rev-parse --verify %s" % | |
|
131 | self.revs[0]) | |||
127 | heads = [heads[:-1]] |
|
132 | heads = [heads[:-1]] | |
128 | if ret: |
|
133 | if ret: | |
129 | raise util.Abort(_('cannot retrieve git heads')) |
|
134 | raise util.Abort(_('cannot retrieve git heads')) |
@@ -27,8 +27,8 class gnuarch_source(converter_source, c | |||||
27 | self.ren_files = {} |
|
27 | self.ren_files = {} | |
28 | self.ren_dirs = {} |
|
28 | self.ren_dirs = {} | |
29 |
|
29 | |||
30 | def __init__(self, ui, path, rev=None): |
|
30 | def __init__(self, ui, path, revs=None): | |
31 | super(gnuarch_source, self).__init__(ui, path, rev=rev) |
|
31 | super(gnuarch_source, self).__init__(ui, path, revs=revs) | |
32 |
|
32 | |||
33 | if not os.path.exists(os.path.join(path, '{arch}')): |
|
33 | if not os.path.exists(os.path.join(path, '{arch}')): | |
34 | raise NoRepo(_("%s does not look like a GNU Arch repository") |
|
34 | raise NoRepo(_("%s does not look like a GNU Arch repository") |
@@ -372,8 +372,11 class mercurial_sink(converter_sink): | |||||
372 | return rev in self.repo |
|
372 | return rev in self.repo | |
373 |
|
373 | |||
374 | class mercurial_source(converter_source): |
|
374 | class mercurial_source(converter_source): | |
375 | def __init__(self, ui, path, rev=None): |
|
375 | def __init__(self, ui, path, revs=None): | |
376 | converter_source.__init__(self, ui, path, rev) |
|
376 | converter_source.__init__(self, ui, path, revs) | |
|
377 | if revs and len(revs) > 1: | |||
|
378 | raise util.Abort(_("mercurial source does not support specifying " | |||
|
379 | "multiple revisions")) | |||
377 | self.ignoreerrors = ui.configbool('convert', 'hg.ignoreerrors', False) |
|
380 | self.ignoreerrors = ui.configbool('convert', 'hg.ignoreerrors', False) | |
378 | self.ignored = set() |
|
381 | self.ignored = set() | |
379 | self.saverev = ui.configbool('convert', 'hg.saverev', False) |
|
382 | self.saverev = ui.configbool('convert', 'hg.saverev', False) | |
@@ -407,12 +410,12 class mercurial_source(converter_source) | |||||
407 | self.keep = children.__contains__ |
|
410 | self.keep = children.__contains__ | |
408 | else: |
|
411 | else: | |
409 | self.keep = util.always |
|
412 | self.keep = util.always | |
410 | if rev: |
|
413 | if revs: | |
411 | self._heads = [self.repo[rev].node()] |
|
414 | self._heads = [self.repo[revs[0]].node()] | |
412 | else: |
|
415 | else: | |
413 | self._heads = self.repo.heads() |
|
416 | self._heads = self.repo.heads() | |
414 | else: |
|
417 | else: | |
415 | if rev or startnode is not None: |
|
418 | if revs or startnode is not None: | |
416 | raise util.Abort(_('hg.revs cannot be combined with ' |
|
419 | raise util.Abort(_('hg.revs cannot be combined with ' | |
417 | 'hg.startrev or --rev')) |
|
420 | 'hg.startrev or --rev')) | |
418 | nodes = set() |
|
421 | nodes = set() |
@@ -13,14 +13,17 from common import commandline | |||||
13 | from mercurial.i18n import _ |
|
13 | from mercurial.i18n import _ | |
14 |
|
14 | |||
15 | class monotone_source(converter_source, commandline): |
|
15 | class monotone_source(converter_source, commandline): | |
16 | def __init__(self, ui, path=None, rev=None): |
|
16 | def __init__(self, ui, path=None, revs=None): | |
17 | converter_source.__init__(self, ui, path, rev) |
|
17 | converter_source.__init__(self, ui, path, revs) | |
|
18 | if revs and len(revs) > 1: | |||
|
19 | raise util.Abort(_('monotone source does not support specifying ' | |||
|
20 | 'multiple revs')) | |||
18 | commandline.__init__(self, ui, 'mtn') |
|
21 | commandline.__init__(self, ui, 'mtn') | |
19 |
|
22 | |||
20 | self.ui = ui |
|
23 | self.ui = ui | |
21 | self.path = path |
|
24 | self.path = path | |
22 | self.automatestdio = False |
|
25 | self.automatestdio = False | |
23 | self.rev = rev |
|
26 | self.revs = revs | |
24 |
|
27 | |||
25 | norepo = NoRepo(_("%s does not look like a monotone repository") |
|
28 | norepo = NoRepo(_("%s does not look like a monotone repository") | |
26 | % path) |
|
29 | % path) | |
@@ -219,10 +222,10 class monotone_source(converter_source, | |||||
219 | # implement the converter_source interface: |
|
222 | # implement the converter_source interface: | |
220 |
|
223 | |||
221 | def getheads(self): |
|
224 | def getheads(self): | |
222 | if not self.rev: |
|
225 | if not self.revs: | |
223 | return self.mtnrun("leaves").splitlines() |
|
226 | return self.mtnrun("leaves").splitlines() | |
224 | else: |
|
227 | else: | |
225 |
return |
|
228 | return self.revs | |
226 |
|
229 | |||
227 | def getchanges(self, rev, full): |
|
230 | def getchanges(self, rev, full): | |
228 | if full: |
|
231 | if full: |
@@ -24,8 +24,8 def loaditer(f): | |||||
24 | pass |
|
24 | pass | |
25 |
|
25 | |||
26 | class p4_source(converter_source): |
|
26 | class p4_source(converter_source): | |
27 | def __init__(self, ui, path, rev=None): |
|
27 | def __init__(self, ui, path, revs=None): | |
28 | super(p4_source, self).__init__(ui, path, rev=rev) |
|
28 | super(p4_source, self).__init__(ui, path, revs=revs) | |
29 |
|
29 | |||
30 | if "/" in path and not path.startswith('//'): |
|
30 | if "/" in path and not path.startswith('//'): | |
31 | raise NoRepo(_('%s does not look like a P4 repository') % path) |
|
31 | raise NoRepo(_('%s does not look like a P4 repository') % path) | |
@@ -49,6 +49,9 class p4_source(converter_source): | |||||
49 | r":[^$\n]*\$") |
|
49 | r":[^$\n]*\$") | |
50 | self.re_keywords_old = re.compile("\$(Id|Header):[^$\n]*\$") |
|
50 | self.re_keywords_old = re.compile("\$(Id|Header):[^$\n]*\$") | |
51 |
|
51 | |||
|
52 | if revs and len(revs) > 1: | |||
|
53 | raise util.Abort(_("p4 source does not support specifying " | |||
|
54 | "multiple revisions")) | |||
52 | self._parse(ui, path) |
|
55 | self._parse(ui, path) | |
53 |
|
56 | |||
54 | def _parse_view(self, path): |
|
57 | def _parse_view(self, path): | |
@@ -99,7 +102,7 class p4_source(converter_source): | |||||
99 | startrev = self.ui.config('convert', 'p4.startrev', default=0) |
|
102 | startrev = self.ui.config('convert', 'p4.startrev', default=0) | |
100 | self.p4changes = [x for x in self.p4changes |
|
103 | self.p4changes = [x for x in self.p4changes | |
101 | if ((not startrev or int(x) >= int(startrev)) and |
|
104 | if ((not startrev or int(x) >= int(startrev)) and | |
102 | (not self.rev or int(x) <= int(self.rev)))] |
|
105 | (not self.revs or int(x) <= int(self.revs[0])))] | |
103 |
|
106 | |||
104 | # now read the full changelists to get the list of file revisions |
|
107 | # now read the full changelists to get the list of file revisions | |
105 | ui.status(_('collecting p4 changelists\n')) |
|
108 | ui.status(_('collecting p4 changelists\n')) |
@@ -268,8 +268,8 def issvnurl(ui, url): | |||||
268 | # the parent module. A revision has at most one parent. |
|
268 | # the parent module. A revision has at most one parent. | |
269 | # |
|
269 | # | |
270 | class svn_source(converter_source): |
|
270 | class svn_source(converter_source): | |
271 | def __init__(self, ui, url, rev=None): |
|
271 | def __init__(self, ui, url, revs=None): | |
272 | super(svn_source, self).__init__(ui, url, rev=rev) |
|
272 | super(svn_source, self).__init__(ui, url, revs=revs) | |
273 |
|
273 | |||
274 | if not (url.startswith('svn://') or url.startswith('svn+ssh://') or |
|
274 | if not (url.startswith('svn://') or url.startswith('svn+ssh://') or | |
275 | (os.path.exists(url) and |
|
275 | (os.path.exists(url) and | |
@@ -325,11 +325,15 class svn_source(converter_source): | |||||
325 | "to libsvn version %s") |
|
325 | "to libsvn version %s") | |
326 | % (self.url, svnversion)) |
|
326 | % (self.url, svnversion)) | |
327 |
|
327 | |||
328 | if rev: |
|
328 | if revs: | |
|
329 | if len(revs) > 1: | |||
|
330 | raise util.Abort(_('subversion source does not support ' | |||
|
331 | 'specifying multiple revisions')) | |||
329 | try: |
|
332 | try: | |
330 | latest = int(rev) |
|
333 | latest = int(revs[0]) | |
331 | except ValueError: |
|
334 | except ValueError: | |
332 |
raise util.Abort(_('svn: revision %s is not an integer') % |
|
335 | raise util.Abort(_('svn: revision %s is not an integer') % | |
|
336 | revs[0]) | |||
333 |
|
337 | |||
334 | self.trunkname = self.ui.config('convert', 'svn.trunk', |
|
338 | self.trunkname = self.ui.config('convert', 'svn.trunk', | |
335 | 'trunk').strip('/') |
|
339 | 'trunk').strip('/') |
@@ -304,11 +304,11 | |||||
304 | does not convert tags from the source repo to the target |
|
304 | does not convert tags from the source repo to the target | |
305 | repo. The default is False. |
|
305 | repo. The default is False. | |
306 |
|
306 | |||
307 | options: |
|
307 | options ([+] can be repeated): | |
308 |
|
308 | |||
309 | -s --source-type TYPE source repository type |
|
309 | -s --source-type TYPE source repository type | |
310 | -d --dest-type TYPE destination repository type |
|
310 | -d --dest-type TYPE destination repository type | |
311 |
-r --rev REV |
|
311 | -r --rev REV [+] import up to source revision REV | |
312 | -A --authormap FILE remap usernames using this file |
|
312 | -A --authormap FILE remap usernames using this file | |
313 | --filemap FILE remap file names using contents of file |
|
313 | --filemap FILE remap file names using contents of file | |
314 | --full apply filemap changes by converting all files again |
|
314 | --full apply filemap changes by converting all files again |
General Comments 0
You need to be logged in to leave comments.
Login now