##// END OF EJS Templates
splicemap: improve error handling when source is hg (issue2084)...
Ben Goswami -
r19120:58e782f0 default
parent child Browse files
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 parent1'
157 raise util.Abort(_('syntax error in %s(%d): child '\
142 '[,parent2] expected') % (path, i + 1))
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