Mercurial > hg-stable
changeset 5443:58496354773f
Merge with crew
Those crew folks are getting lazy about pulling from upstream before
committing.
author | Matt Mackall <mpm@selenic.com> |
---|---|
date | Thu, 11 Oct 2007 00:46:40 -0500 |
parents | be015f9b7405 (current diff) a19167001251 (diff) |
children | a0952e4e52eb |
files | |
diffstat | 8 files changed, 162 insertions(+), 58 deletions(-) [+] |
line wrap: on
line diff
--- a/hgext/convert/__init__.py Tue Oct 09 17:44:44 2007 -0500 +++ b/hgext/convert/__init__.py Thu Oct 11 00:46:40 2007 -0500 @@ -10,7 +10,7 @@ from darcs import darcs_source from git import convert_git from hg import mercurial_source, mercurial_sink -from subversion import convert_svn, debugsvnlog +from subversion import svn_source, debugsvnlog import filemap import os, shutil @@ -19,27 +19,32 @@ commands.norepo += " convert debugsvnlog" -sink_converters = [mercurial_sink] -source_converters = [convert_cvs, convert_git, convert_svn, - mercurial_source, darcs_source] -def convertsource(ui, path, **opts): - for c in source_converters: +source_converters = [ + ('cvs', convert_cvs), + ('git', convert_git), + ('svn', svn_source), + ('hg', mercurial_source), + ('darcs', darcs_source), + ] + +sink_converters = [ + ('hg', mercurial_sink), + ] + +def convertsource(ui, path, type, rev): + for name, source in source_converters: try: - return c.getcommit and c(ui, path, **opts) - except AttributeError: - pass + if not type or name == type: + return source(ui, path, rev) except NoRepo, inst: ui.note(_("convert: %s\n") % inst) raise util.Abort('%s: unknown repository type' % path) -def convertsink(ui, path): - if not os.path.isdir(path): - raise util.Abort("%s: not a directory" % path) - for c in sink_converters: +def convertsink(ui, path, type): + for name, sink in sink_converters: try: - return c.putcommit and c(ui, path) - except AttributeError: - pass + if not type or name == type: + return sink(ui, path) except NoRepo, inst: ui.note(_("convert: %s\n") % inst) raise util.Abort('%s: unknown repository type' % path) @@ -350,37 +355,14 @@ dest = hg.defaultdest(src) + "-hg" ui.status("assuming destination %s\n" % dest) - # Try to be smart and initalize things when required - created = False - if os.path.isdir(dest): - if len(os.listdir(dest)) > 0: - try: - hg.repository(ui, dest) - ui.status("destination %s is a Mercurial repository\n" % dest) - except hg.RepoError: - raise util.Abort( - "destination directory %s is not empty.\n" - "Please specify an empty directory to be initialized\n" - "or an already initialized mercurial repository" - % dest) - else: - ui.status("initializing destination %s repository\n" % dest) - hg.repository(ui, dest, create=True) - created = True - elif os.path.exists(dest): - raise util.Abort("destination %s exists and is not a directory" % dest) - else: - ui.status("initializing destination %s repository\n" % dest) - hg.repository(ui, dest, create=True) - created = True - - destc = convertsink(ui, dest) + destc = convertsink(ui, dest, opts.get('dest_type')) try: - srcc = convertsource(ui, src, rev=opts.get('rev')) + srcc = convertsource(ui, src, opts.get('source_type'), + opts.get('rev')) except Exception: - if created: - shutil.rmtree(dest, True) + for path in destc.created: + shutil.rmtree(path, True) raise fmap = opts.get('filemap') @@ -402,8 +384,10 @@ "convert": (convert, [('A', 'authors', '', 'username mapping filename'), + ('d', 'dest-type', '', 'destination repository type'), ('', 'filemap', '', 'remap file names using contents of file'), ('r', 'rev', '', 'import up to target revision REV'), + ('s', 'source-type', '', 'source repository type'), ('', 'datesort', None, 'try to sort changesets by date')], 'hg convert [OPTION]... SOURCE [DEST [MAPFILE]]'), "debugsvnlog":
--- a/hgext/convert/common.py Tue Oct 09 17:44:44 2007 -0500 +++ b/hgext/convert/common.py Thu Oct 11 00:46:40 2007 -0500 @@ -20,13 +20,15 @@ SKIPREV = 'SKIP' class commit(object): - def __init__(self, author, date, desc, parents, branch=None, rev=None): + def __init__(self, author, date, desc, parents, branch=None, rev=None, + extra={}): self.author = author self.date = date self.desc = desc self.parents = parents self.branch = branch self.rev = rev + self.extra = extra class converter_source(object): """Conversion source interface""" @@ -114,8 +116,13 @@ def __init__(self, ui, path): """Initialize conversion sink (or raise NoRepo("message") - exception if path is not a valid repository)""" - raise NotImplementedError() + exception if path is not a valid repository) + + created is a list of paths to remove if a fatal error occurs + later""" + self.ui = ui + self.path = path + self.created = [] def getheads(self): """Return a list of this repository's heads"""
--- a/hgext/convert/hg.py Tue Oct 09 17:44:44 2007 -0500 +++ b/hgext/convert/hg.py Thu Oct 11 00:46:40 2007 -0500 @@ -16,16 +16,27 @@ class mercurial_sink(converter_sink): def __init__(self, ui, path): - self.path = path - self.ui = ui + converter_sink.__init__(self, ui, path) self.branchnames = ui.configbool('convert', 'hg.usebranchnames', True) self.clonebranches = ui.configbool('convert', 'hg.clonebranches', False) self.tagsbranch = ui.config('convert', 'hg.tagsbranch', 'default') self.lastbranch = None - try: - self.repo = hg.repository(self.ui, path) - except: - raise NoRepo("could not open hg repo %s as sink" % path) + if os.path.isdir(path) and len(os.listdir(path)) > 0: + try: + self.repo = hg.repository(self.ui, path) + ui.status(_('destination %s is a Mercurial repository\n') % + path) + except hg.RepoError, err: + ui.print_exc() + raise NoRepo(err.args[0]) + else: + try: + ui.status(_('initializing destination %s repository\n') % path) + self.repo = hg.repository(self.ui, path, create=True) + self.created.append(path) + except hg.RepoError, err: + ui.print_exc() + raise NoRepo("could not create hg repo %s as sink" % path) self.lock = None self.wlock = None self.filemapmode = False @@ -108,7 +119,7 @@ p2 = parents.pop(0) text = commit.desc - extra = {} + extra = commit.extra.copy() if self.branchnames and commit.branch: extra['branch'] = commit.branch if commit.rev: @@ -174,7 +185,11 @@ converter_source.__init__(self, ui, path, rev) try: self.repo = hg.repository(self.ui, path) - except: + # try to provoke an exception if this isn't really a hg + # repo, but some other bogus compatible-looking url + self.repo.heads() + except hg.RepoError: + ui.print_exc() raise NoRepo("could not open hg repo %s as source" % path) self.lastrev = None self.lastctx = None @@ -226,7 +241,7 @@ parents = [hex(p.node()) for p in ctx.parents() if p.node() != nullid] return commit(author=ctx.user(), date=util.datestr(ctx.date()), desc=ctx.description(), parents=parents, - branch=ctx.branch()) + branch=ctx.branch(), extra=ctx.extra()) def gettags(self): tags = [t for t in self.repo.tagslist() if t[0] != 'tip']
--- a/hgext/convert/subversion.py Tue Oct 09 17:44:44 2007 -0500 +++ b/hgext/convert/subversion.py Thu Oct 11 00:46:40 2007 -0500 @@ -93,9 +93,9 @@ get_log_child(sys.stdout, *args) # SVN conversion code stolen from bzr-svn and tailor -class convert_svn(converter_source): +class svn_source(converter_source): def __init__(self, ui, url, rev=None): - super(convert_svn, self).__init__(ui, url, rev=rev) + super(svn_source, self).__init__(ui, url, rev=rev) try: SubversionException @@ -128,6 +128,7 @@ self.paths = {} self.uuid = svn.ra.get_uuid(self.ra).decode(self.encoding) except SubversionException, e: + ui.print_exc() raise NoRepo("couldn't open SVN repo %s" % self.url) if rev:
--- a/mercurial/context.py Tue Oct 09 17:44:44 2007 -0500 +++ b/mercurial/context.py Thu Oct 11 00:46:40 2007 -0500 @@ -82,6 +82,7 @@ def files(self): return self._changeset[3] def description(self): return self._changeset[4] def branch(self): return self._changeset[5].get("branch") + def extra(self): return self._changeset[5] def tags(self): return self._repo.nodetags(self._node) def parents(self):
--- a/tests/test-convert Tue Oct 09 17:44:44 2007 -0500 +++ b/tests/test-convert Thu Oct 11 00:46:40 2007 -0500 @@ -3,6 +3,8 @@ echo "[extensions]" >> $HGRCPATH echo "convert=" >> $HGRCPATH +hg help convert + hg init a cd a echo a > a @@ -19,3 +21,17 @@ cd .. hg convert a 2>&1 | grep -v 'subversion python bindings could not be loaded' hg --cwd a-hg pull ../a + +touch bogusfile +echo % should fail +hg convert a bogusfile + +mkdir bogusdir +chmod 000 bogusdir + +echo % should fail +hg convert a bogusdir + +echo % should succeed +chmod 700 bogusdir +hg convert a bogusdir
--- a/tests/test-convert-darcs Tue Oct 09 17:44:44 2007 -0500 +++ b/tests/test-convert-darcs Thu Oct 11 00:46:40 2007 -0500 @@ -7,6 +7,7 @@ echo 'hgext.graphlog =' >> $HGRCPATH DARCS_EMAIL='test@example.org'; export DARCS_EMAIL +HOME=do_not_use_HOME_darcs; export HOME echo % initialize darcs repo mkdir darcs-repo
--- a/tests/test-convert.out Tue Oct 09 17:44:44 2007 -0500 +++ b/tests/test-convert.out Thu Oct 11 00:46:40 2007 -0500 @@ -1,3 +1,67 @@ +hg convert [OPTION]... SOURCE [DEST [MAPFILE]] + +Convert a foreign SCM repository to a Mercurial one. + + Accepted source formats: + - CVS + - Darcs + - git + - Subversion + + Accepted destination formats: + - Mercurial + + If no revision is given, all revisions will be converted. Otherwise, + convert will only import up to the named revision (given in a format + understood by the source). + + If no destination directory name is specified, it defaults to the + basename of the source with '-hg' appended. If the destination + repository doesn't exist, it will be created. + + If <revmapfile> isn't given, it will be put in a default location + (<dest>/.hg/shamap by default). The <revmapfile> is a simple text + file that maps each source commit ID to the destination ID for + that revision, like so: + <source ID> <destination ID> + + If the file doesn't exist, it's automatically created. It's updated + on each commit copied, so convert-repo can be interrupted and can + be run repeatedly to copy new commits. + + The [username mapping] file is a simple text file that maps each source + commit author to a destination commit author. It is handy for source SCMs + that use unix logins to identify authors (eg: CVS). One line per author + mapping and the line format is: + srcauthor=whatever string you want + + The filemap is a file that allows filtering and remapping of files + and directories. Comment lines start with '#'. Each line can + contain one of the following directives: + + include path/to/file + + exclude path/to/file + + rename from/file to/file + + The 'include' directive causes a file, or all files under a + directory, to be included in the destination repository. The + 'exclude' directive causes files or directories to be omitted. + The 'rename' directive renames a file or directory. To rename + from a subdirectory into the root of the repository, use '.' as + the path to rename to. + +options: + + -A --authors username mapping filename + -d --dest-type destination repository type + --filemap remap file names using contents of file + -r --rev import up to target revision REV + -s --source-type source repository type + --datesort try to sort changesets by date + +use "hg -v help convert" to show global options adding a assuming destination a-hg initializing destination a-hg repository @@ -12,3 +76,18 @@ pulling from ../a searching for changes no changes found +% should fail +initializing destination bogusfile repository +abort: cannot create new bundle repository +% should fail +abort: Permission denied: bogusdir +% should succeed +initializing destination bogusdir repository +scanning source... +sorting... +converting... +4 a +3 b +2 c +1 d +0 e