39 except NoRepo: |
39 except NoRepo: |
40 pass |
40 pass |
41 raise util.Abort('%s: unknown repository type' % path) |
41 raise util.Abort('%s: unknown repository type' % path) |
42 |
42 |
43 class convert(object): |
43 class convert(object): |
44 def __init__(self, ui, source, dest, mapfile, opts): |
44 def __init__(self, ui, source, dest, revmapfile, opts): |
45 |
45 |
46 self.source = source |
46 self.source = source |
47 self.dest = dest |
47 self.dest = dest |
48 self.ui = ui |
48 self.ui = ui |
49 self.opts = opts |
49 self.opts = opts |
50 self.commitcache = {} |
50 self.commitcache = {} |
51 self.mapfile = mapfile |
51 self.revmapfile = revmapfile |
52 self.mapfilefd = None |
52 self.revmapfilefd = None |
53 self.authors = {} |
53 self.authors = {} |
54 self.authorfile = None |
54 self.authorfile = None |
55 |
55 |
56 self.map = {} |
56 self.map = {} |
57 try: |
57 try: |
58 origmapfile = open(self.mapfile, 'r') |
58 origrevmapfile = open(self.revmapfile, 'r') |
59 for l in origmapfile: |
59 for l in origrevmapfile: |
60 sv, dv = l[:-1].split() |
60 sv, dv = l[:-1].split() |
61 self.map[sv] = dv |
61 self.map[sv] = dv |
62 origmapfile.close() |
62 origrevmapfile.close() |
63 except IOError: |
63 except IOError: |
64 pass |
64 pass |
65 |
65 |
66 # Read first the dst author map if any |
66 # Read first the dst author map if any |
67 authorfile = self.dest.authorfile() |
67 authorfile = self.dest.authorfile() |
149 s = [e[2] for e in s] |
149 s = [e[2] for e in s] |
150 |
150 |
151 return s |
151 return s |
152 |
152 |
153 def mapentry(self, src, dst): |
153 def mapentry(self, src, dst): |
154 if self.mapfilefd is None: |
154 if self.revmapfilefd is None: |
155 try: |
155 try: |
156 self.mapfilefd = open(self.mapfile, "a") |
156 self.revmapfilefd = open(self.revmapfile, "a") |
157 except IOError, (errno, strerror): |
157 except IOError, (errno, strerror): |
158 raise util.Abort("Could not open map file %s: %s, %s\n" % (self.mapfile, errno, strerror)) |
158 raise util.Abort("Could not open map file %s: %s, %s\n" % (self.revmapfile, errno, strerror)) |
159 self.map[src] = dst |
159 self.map[src] = dst |
160 self.mapfilefd.write("%s %s\n" % (src, dst)) |
160 self.revmapfilefd.write("%s %s\n" % (src, dst)) |
161 self.mapfilefd.flush() |
161 self.revmapfilefd.flush() |
162 |
162 |
163 def writeauthormap(self): |
163 def writeauthormap(self): |
164 authorfile = self.authorfile |
164 authorfile = self.authorfile |
165 if authorfile: |
165 if authorfile: |
166 self.ui.status('Writing author map file %s\n' % authorfile) |
166 self.ui.status('Writing author map file %s\n' % authorfile) |
254 self.writeauthormap() |
254 self.writeauthormap() |
255 finally: |
255 finally: |
256 self.cleanup() |
256 self.cleanup() |
257 |
257 |
258 def cleanup(self): |
258 def cleanup(self): |
259 if self.mapfilefd: |
259 if self.revmapfilefd: |
260 self.mapfilefd.close() |
260 self.revmapfilefd.close() |
261 |
261 |
262 def _convert(ui, src, dest=None, mapfile=None, **opts): |
262 def _convert(ui, src, dest=None, revmapfile=None, **opts): |
263 """Convert a foreign SCM repository to a Mercurial one. |
263 """Convert a foreign SCM repository to a Mercurial one. |
264 |
264 |
265 Accepted source formats: |
265 Accepted source formats: |
266 - GIT |
266 - GIT |
267 - CVS |
267 - CVS |
276 |
276 |
277 If no destination directory name is specified, it defaults to the |
277 If no destination directory name is specified, it defaults to the |
278 basename of the source with '-hg' appended. If the destination |
278 basename of the source with '-hg' appended. If the destination |
279 repository doesn't exist, it will be created. |
279 repository doesn't exist, it will be created. |
280 |
280 |
281 If <mapfile> isn't given, it will be put in a default location |
281 If <revmapfile> isn't given, it will be put in a default location |
282 (<dest>/.hg/shamap by default). The <mapfile> is a simple text |
282 (<dest>/.hg/shamap by default). The <revmapfile> is a simple text |
283 file that maps each source commit ID to the destination ID for |
283 file that maps each source commit ID to the destination ID for |
284 that revision, like so: |
284 that revision, like so: |
285 <source ID> <destination ID> |
285 <source ID> <destination ID> |
286 |
286 |
287 If the file doesn't exist, it's automatically created. It's updated |
287 If the file doesn't exist, it's automatically created. It's updated |
332 except Exception: |
332 except Exception: |
333 if created: |
333 if created: |
334 shutil.rmtree(dest, True) |
334 shutil.rmtree(dest, True) |
335 raise |
335 raise |
336 |
336 |
337 if not mapfile: |
337 if not revmapfile: |
338 try: |
338 try: |
339 mapfile = destc.mapfile() |
339 revmapfile = destc.revmapfile() |
340 except: |
340 except: |
341 mapfile = os.path.join(destc, "map") |
341 revmapfile = os.path.join(destc, "map") |
342 |
342 |
343 c = convert(ui, srcc, destc, mapfile, opts) |
343 c = convert(ui, srcc, destc, revmapfile, opts) |
344 c.convert() |
344 c.convert() |
345 |
345 |
346 cmdtable = { |
346 cmdtable = { |
347 "convert": |
347 "convert": |
348 (_convert, |
348 (_convert, |