Show More
@@ -5,7 +5,7 b'' | |||||
5 | # This software may be used and distributed according to the terms of the |
|
5 | # This software may be used and distributed according to the terms of the | |
6 | # GNU General Public License version 2 or any later version. |
|
6 | # GNU General Public License version 2 or any later version. | |
7 |
|
7 | |||
8 | import base64, errno, subprocess, os, datetime |
|
8 | import base64, errno, subprocess, os, datetime, re | |
9 | import cPickle as pickle |
|
9 | import cPickle as pickle | |
10 | from mercurial import util |
|
10 | from mercurial import util | |
11 | from mercurial.i18n import _ |
|
11 | from mercurial.i18n import _ | |
@@ -63,6 +63,15 b' class converter_source(object):' | |||||
63 |
|
63 | |||
64 | self.encoding = 'utf-8' |
|
64 | self.encoding = 'utf-8' | |
65 |
|
65 | |||
|
66 | def checkhexformat(self, revstr): | |||
|
67 | """ fails if revstr is not a 40 byte hex. mercurial and git both uses | |||
|
68 | such format for their revision numbering | |||
|
69 | """ | |||
|
70 | matchobj = re.match(r'[0-9a-fA-F]{40,40}$', revstr) | |||
|
71 | if matchobj is None: | |||
|
72 | raise util.Abort(_('splicemap entry %s is not a valid revision' | |||
|
73 | ' identifier') % revstr) | |||
|
74 | ||||
66 | def before(self): |
|
75 | def before(self): | |
67 | pass |
|
76 | pass | |
68 |
|
77 | |||
@@ -164,6 +173,13 b' class converter_source(object):' | |||||
164 | """ |
|
173 | """ | |
165 | return {} |
|
174 | return {} | |
166 |
|
175 | |||
|
176 | def checkrevformat(self, revstr): | |||
|
177 | """revstr is a string that describes a revision in the given | |||
|
178 | source control system. Return true if revstr has correct | |||
|
179 | format. | |||
|
180 | """ | |||
|
181 | return True | |||
|
182 | ||||
167 | class converter_sink(object): |
|
183 | class converter_sink(object): | |
168 | """Conversion sink (target) interface""" |
|
184 | """Conversion sink (target) interface""" | |
169 |
|
185 |
@@ -121,9 +121,17 b' class converter(object):' | |||||
121 | self.splicemap = self.parsesplicemap(opts.get('splicemap')) |
|
121 | self.splicemap = self.parsesplicemap(opts.get('splicemap')) | |
122 | self.branchmap = mapfile(ui, opts.get('branchmap')) |
|
122 | self.branchmap = mapfile(ui, opts.get('branchmap')) | |
123 |
|
123 | |||
|
124 | def parsesplicemap(self, path): | |||
|
125 | """ check and validate the splicemap format and | |||
|
126 | return a child/parents dictionary. | |||
|
127 | Format checking has two parts. | |||
|
128 | 1. generic format which is same across all source types | |||
|
129 | 2. specific format checking which may be different for | |||
|
130 | different source type. This logic is implemented in | |||
|
131 | checkrevformat function in source files like | |||
|
132 | hg.py, subversion.py etc. | |||
|
133 | """ | |||
124 |
|
134 | |||
125 | def parsesplicemap(self, path): |
|
|||
126 | """Parse a splicemap, return a child/parents dictionary.""" |
|
|||
127 | if not path: |
|
135 | if not path: | |
128 | return {} |
|
136 | return {} | |
129 | m = {} |
|
137 | m = {} | |
@@ -136,18 +144,28 b' class converter(object):' | |||||
136 | continue |
|
144 | continue | |
137 | try: |
|
145 | try: | |
138 | child, parents = line.split(' ', 1) |
|
146 | child, parents = line.split(' ', 1) | |
|
147 | self.source.checkrevformat(child) | |||
139 | parents = parents.replace(',', ' ').split() |
|
148 | parents = parents.replace(',', ' ').split() | |
|
149 | # check if number of parents are upto 2 max | |||
|
150 | if (len(parents) > 2): | |||
|
151 | raise util.Abort(_('syntax error in %s(%d): child '\ | |||
|
152 | 'parent1[,parent2] expected') \ | |||
|
153 | % (path, i + 1)) | |||
|
154 | for parent in parents: | |||
|
155 | self.source.checkrevformat(parent) | |||
140 | except ValueError: |
|
156 | except ValueError: | |
141 |
raise util.Abort(_('syntax error in %s(%d): child |
|
157 | raise util.Abort(_('syntax error in %s(%d): child '\ | |
142 |
'[,parent2] expected') |
|
158 | 'parent1[,parent2] expected') \ | |
|
159 | % (path, i + 1)) | |||
143 | pp = [] |
|
160 | pp = [] | |
144 | for p in parents: |
|
161 | for p in parents: | |
145 | if p not in pp: |
|
162 | if p not in pp: | |
146 | pp.append(p) |
|
163 | pp.append(p) | |
147 | m[child] = pp |
|
164 | m[child] = pp | |
148 | except IOError, e: |
|
165 | # if file does not exist or error reading, exit | |
149 | if e.errno != errno.ENOENT: |
|
166 | except IOError: | |
150 | raise |
|
167 | raise util.Abort(_('splicemap file not found or error reading %s:') | |
|
168 | % path) | |||
151 | return m |
|
169 | return m | |
152 |
|
170 | |||
153 |
|
171 |
@@ -397,3 +397,7 b' class mercurial_source(converter_source)' | |||||
397 |
|
397 | |||
398 | def getbookmarks(self): |
|
398 | def getbookmarks(self): | |
399 | return bookmarks.listbookmarks(self.repo) |
|
399 | return bookmarks.listbookmarks(self.repo) | |
|
400 | ||||
|
401 | def checkrevformat(self, revstr): | |||
|
402 | """ Mercurial, revision string is a 40 byte hex """ | |||
|
403 | self.checkhexformat(revstr) |
@@ -37,6 +37,8 b'' | |||||
37 | $ hg ci -Am addaandd |
|
37 | $ hg ci -Am addaandd | |
38 | adding a |
|
38 | adding a | |
39 | adding d |
|
39 | adding d | |
|
40 | $ INVALIDID1=afd12345af | |||
|
41 | $ INVALIDID2=28173x36ddd1e67bf7098d541130558ef5534a86 | |||
40 | $ CHILDID1=`hg id --debug -i` |
|
42 | $ CHILDID1=`hg id --debug -i` | |
41 | $ echo d >> d |
|
43 | $ echo d >> d | |
42 | $ hg ci -Am changed |
|
44 | $ hg ci -Am changed | |
@@ -53,7 +55,7 b'' | |||||
53 | o 0:527cdedf31fb "addaandd" files: a d |
|
55 | o 0:527cdedf31fb "addaandd" files: a d | |
54 |
|
56 | |||
55 |
|
57 | |||
56 | test invalid splicemap |
|
58 | test invalid splicemap1 | |
57 |
|
59 | |||
58 | $ cat > splicemap <<EOF |
|
60 | $ cat > splicemap <<EOF | |
59 | > $CHILDID2 |
|
61 | > $CHILDID2 | |
@@ -62,6 +64,24 b' test invalid splicemap' | |||||
62 | abort: syntax error in splicemap(1): child parent1[,parent2] expected |
|
64 | abort: syntax error in splicemap(1): child parent1[,parent2] expected | |
63 | [255] |
|
65 | [255] | |
64 |
|
66 | |||
|
67 | test invalid splicemap2 | |||
|
68 | ||||
|
69 | $ cat > splicemap <<EOF | |||
|
70 | > $CHILDID2 $PARENTID1, $PARENTID2, $PARENTID2 | |||
|
71 | > EOF | |||
|
72 | $ hg convert --splicemap splicemap repo2 repo1 | |||
|
73 | abort: syntax error in splicemap(1): child parent1[,parent2] expected | |||
|
74 | [255] | |||
|
75 | ||||
|
76 | test invalid splicemap3 | |||
|
77 | ||||
|
78 | $ cat > splicemap <<EOF | |||
|
79 | > $INVALIDID1 $INVALIDID2 | |||
|
80 | > EOF | |||
|
81 | $ hg convert --splicemap splicemap repo2 repo1 | |||
|
82 | abort: splicemap entry afd12345af is not a valid revision identifier | |||
|
83 | [255] | |||
|
84 | ||||
65 | splice repo2 on repo1 |
|
85 | splice repo2 on repo1 | |
66 |
|
86 | |||
67 | $ cat > splicemap <<EOF |
|
87 | $ cat > splicemap <<EOF |
General Comments 0
You need to be logged in to leave comments.
Login now