##// END OF EJS Templates
convert: refactor sink initialisation, to remove hardcoding of hg...
Bryan O'Sullivan -
r5441:71e7c86a default
parent child Browse files
Show More
@@ -19,27 +19,32 b' from mercurial.i18n import _'
19 19
20 20 commands.norepo += " convert debugsvnlog"
21 21
22 sink_converters = [mercurial_sink]
23 source_converters = [convert_cvs, convert_git, svn_source,
24 mercurial_source, darcs_source]
25 def convertsource(ui, path, **opts):
26 for c in source_converters:
22 source_converters = [
23 ('cvs', convert_cvs),
24 ('git', convert_git),
25 ('svn', svn_source),
26 ('hg', mercurial_source),
27 ('darcs', darcs_source),
28 ]
29
30 sink_converters = [
31 ('hg', mercurial_sink),
32 ]
33
34 def convertsource(ui, path, type, rev):
35 for name, source in source_converters:
27 36 try:
28 return c.getcommit and c(ui, path, **opts)
29 except AttributeError:
30 pass
37 if not type or name == type:
38 return source(ui, path, rev)
31 39 except NoRepo, inst:
32 40 ui.note(_("convert: %s\n") % inst)
33 41 raise util.Abort('%s: unknown repository type' % path)
34 42
35 def convertsink(ui, path):
36 if not os.path.isdir(path):
37 raise util.Abort("%s: not a directory" % path)
38 for c in sink_converters:
43 def convertsink(ui, path, type):
44 for name, sink in sink_converters:
39 45 try:
40 return c.putcommit and c(ui, path)
41 except AttributeError:
42 pass
46 if not type or name == type:
47 return sink(ui, path)
43 48 except NoRepo, inst:
44 49 ui.note(_("convert: %s\n") % inst)
45 50 raise util.Abort('%s: unknown repository type' % path)
@@ -350,37 +355,14 b' def convert(ui, src, dest=None, revmapfi'
350 355 dest = hg.defaultdest(src) + "-hg"
351 356 ui.status("assuming destination %s\n" % dest)
352 357
353 # Try to be smart and initalize things when required
354 created = False
355 if os.path.isdir(dest):
356 if len(os.listdir(dest)) > 0:
357 try:
358 hg.repository(ui, dest)
359 ui.status("destination %s is a Mercurial repository\n" % dest)
360 except hg.RepoError:
361 raise util.Abort(
362 "destination directory %s is not empty.\n"
363 "Please specify an empty directory to be initialized\n"
364 "or an already initialized mercurial repository"
365 % dest)
366 else:
367 ui.status("initializing destination %s repository\n" % dest)
368 hg.repository(ui, dest, create=True)
369 created = True
370 elif os.path.exists(dest):
371 raise util.Abort("destination %s exists and is not a directory" % dest)
372 else:
373 ui.status("initializing destination %s repository\n" % dest)
374 hg.repository(ui, dest, create=True)
375 created = True
376
377 destc = convertsink(ui, dest)
358 destc = convertsink(ui, dest, opts.get('dest_type'))
378 359
379 360 try:
380 srcc = convertsource(ui, src, rev=opts.get('rev'))
361 srcc = convertsource(ui, src, opts.get('source_type'),
362 opts.get('rev'))
381 363 except Exception:
382 if created:
383 shutil.rmtree(dest, True)
364 for path in destc.created:
365 shutil.rmtree(path, True)
384 366 raise
385 367
386 368 fmap = opts.get('filemap')
@@ -402,8 +384,10 b' cmdtable = {'
402 384 "convert":
403 385 (convert,
404 386 [('A', 'authors', '', 'username mapping filename'),
387 ('d', 'dest-type', '', 'destination repository type'),
405 388 ('', 'filemap', '', 'remap file names using contents of file'),
406 389 ('r', 'rev', '', 'import up to target revision REV'),
390 ('s', 'source-type', '', 'source repository type'),
407 391 ('', 'datesort', None, 'try to sort changesets by date')],
408 392 'hg convert [OPTION]... SOURCE [DEST [MAPFILE]]'),
409 393 "debugsvnlog":
@@ -116,9 +116,13 b' class converter_sink(object):'
116 116
117 117 def __init__(self, ui, path):
118 118 """Initialize conversion sink (or raise NoRepo("message")
119 exception if path is not a valid repository)"""
119 exception if path is not a valid repository)
120
121 created is a list of paths to remove if a fatal error occurs
122 later"""
123 self.ui = ui
120 124 self.path = path
121 self.ui = ui
125 self.created = []
122 126
123 127 def getheads(self):
124 128 """Return a list of this repository's heads"""
@@ -21,10 +21,22 b' class mercurial_sink(converter_sink):'
21 21 self.clonebranches = ui.configbool('convert', 'hg.clonebranches', False)
22 22 self.tagsbranch = ui.config('convert', 'hg.tagsbranch', 'default')
23 23 self.lastbranch = None
24 try:
25 self.repo = hg.repository(self.ui, path)
26 except:
27 raise NoRepo("could not open hg repo %s as sink" % path)
24 if os.path.isdir(path) and len(os.listdir(path)) > 0:
25 try:
26 self.repo = hg.repository(self.ui, path)
27 ui.status(_('destination %s is a Mercurial repository\n') %
28 path)
29 except hg.RepoError, err:
30 ui.print_exc()
31 raise NoRepo(err.args[0])
32 else:
33 try:
34 ui.status(_('initializing destination %s repository\n') % path)
35 self.repo = hg.repository(self.ui, path, create=True)
36 self.created.append(path)
37 except hg.RepoError, err:
38 ui.print_exc()
39 raise NoRepo("could not create hg repo %s as sink" % path)
28 40 self.lock = None
29 41 self.wlock = None
30 42 self.filemapmode = False
@@ -3,6 +3,8 b''
3 3 echo "[extensions]" >> $HGRCPATH
4 4 echo "convert=" >> $HGRCPATH
5 5
6 hg help convert
7
6 8 hg init a
7 9 cd a
8 10 echo a > a
@@ -19,3 +21,17 b" hg ci -d'4 0' -me"
19 21 cd ..
20 22 hg convert a 2>&1 | grep -v 'subversion python bindings could not be loaded'
21 23 hg --cwd a-hg pull ../a
24
25 touch bogusfile
26 echo % should fail
27 hg convert a bogusfile
28
29 mkdir bogusdir
30 chmod 000 bogusdir
31
32 echo % should fail
33 hg convert a bogusdir
34
35 echo % should succeed
36 chmod 700 bogusdir
37 hg convert a bogusdir
@@ -1,3 +1,67 b''
1 hg convert [OPTION]... SOURCE [DEST [MAPFILE]]
2
3 Convert a foreign SCM repository to a Mercurial one.
4
5 Accepted source formats:
6 - CVS
7 - Darcs
8 - git
9 - Subversion
10
11 Accepted destination formats:
12 - Mercurial
13
14 If no revision is given, all revisions will be converted. Otherwise,
15 convert will only import up to the named revision (given in a format
16 understood by the source).
17
18 If no destination directory name is specified, it defaults to the
19 basename of the source with '-hg' appended. If the destination
20 repository doesn't exist, it will be created.
21
22 If <revmapfile> isn't given, it will be put in a default location
23 (<dest>/.hg/shamap by default). The <revmapfile> is a simple text
24 file that maps each source commit ID to the destination ID for
25 that revision, like so:
26 <source ID> <destination ID>
27
28 If the file doesn't exist, it's automatically created. It's updated
29 on each commit copied, so convert-repo can be interrupted and can
30 be run repeatedly to copy new commits.
31
32 The [username mapping] file is a simple text file that maps each source
33 commit author to a destination commit author. It is handy for source SCMs
34 that use unix logins to identify authors (eg: CVS). One line per author
35 mapping and the line format is:
36 srcauthor=whatever string you want
37
38 The filemap is a file that allows filtering and remapping of files
39 and directories. Comment lines start with '#'. Each line can
40 contain one of the following directives:
41
42 include path/to/file
43
44 exclude path/to/file
45
46 rename from/file to/file
47
48 The 'include' directive causes a file, or all files under a
49 directory, to be included in the destination repository. The
50 'exclude' directive causes files or directories to be omitted.
51 The 'rename' directive renames a file or directory. To rename
52 from a subdirectory into the root of the repository, use '.' as
53 the path to rename to.
54
55 options:
56
57 -A --authors username mapping filename
58 -d --dest-type destination repository type
59 --filemap remap file names using contents of file
60 -r --rev import up to target revision REV
61 -s --source-type source repository type
62 --datesort try to sort changesets by date
63
64 use "hg -v help convert" to show global options
1 65 adding a
2 66 assuming destination a-hg
3 67 initializing destination a-hg repository
@@ -12,3 +76,18 b' 0 e'
12 76 pulling from ../a
13 77 searching for changes
14 78 no changes found
79 % should fail
80 initializing destination bogusfile repository
81 abort: cannot create new bundle repository
82 % should fail
83 abort: Permission denied: bogusdir
84 % should succeed
85 initializing destination bogusdir repository
86 scanning source...
87 sorting...
88 converting...
89 4 a
90 3 b
91 2 c
92 1 d
93 0 e
General Comments 0
You need to be logged in to leave comments. Login now