From 9139c6368e7f564ce277920e68dd6882f1946585 Mon Sep 17 00:00:00 2001 From: Vadim Gelfer Date: Fri, 28 Jul 2006 10:46:25 -0700 Subject: [PATCH 1/2] hg.py: add islocal() and defaultdest() functions, refactor islocal tells if a repo or url is local. defaultdest returns default path for clone if explicit path not given. clone can now take repo or url as source --- mercurial/hg.py | 47 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 42 insertions(+), 5 deletions(-) diff --git a/mercurial/hg.py b/mercurial/hg.py index a3442051fe..c29c889b08 100644 --- a/mercurial/hg.py +++ b/mercurial/hg.py @@ -57,6 +57,23 @@ schemes = { 'static-http': static_http, } +remote_schemes = [ + 'bundle', + 'hg', + 'http', + 'https', + 'old-http', + 'ssh', + 'static-http', + ] + +def islocal(repo): + '''return true if repo or path is local''' + if isinstance(repo, str): + c = repo.find(':') + return c <= 0 or repo[:c] not in remote_schemes + return repo.local() + def repository(ui, path=None, create=0): scheme = None if path: @@ -74,6 +91,10 @@ def repository(ui, path=None, create=0): scheme) return ctor(ui, path) +def defaultdest(source): + '''return default destination of clone if none is given''' + return os.path.basename(os.path.normpath(source)) + def clone(ui, source, dest=None, pull=False, rev=None, update=True, stream=False): """Make a copy of an existing repository. @@ -90,7 +111,9 @@ def clone(ui, source, dest=None, pull=False, rev=None, update=True, If an exception is raised, the partly cloned/updated destination repository will be deleted. - Keyword arguments: + Arguments: + + source: repository object or URL dest: URL of destination repository to create (defaults to base name of source repository) @@ -105,8 +128,24 @@ def clone(ui, source, dest=None, pull=False, rev=None, update=True, update: update working directory after clone completes, if destination is local repository """ + if isinstance(source, str): + src_repo = repository(ui, source) + else: + src_repo = source + source = src_repo.url() + if dest is None: - dest = os.path.basename(os.path.normpath(source)) + dest = defaultdest(source) + + def localpath(path): + if path.startswith('file://'): + return path[7:] + if path.startswith('file:'): + return path[5:] + return path + + dest = localpath(dest) + source = localpath(source) if os.path.exists(dest): raise util.Abort(_("destination '%s' already exists"), dest) @@ -121,8 +160,6 @@ def clone(ui, source, dest=None, pull=False, rev=None, update=True, if self.dir_: self.rmtree(self.dir_, True) - src_repo = repository(ui, source) - dest_repo = None try: dest_repo = repository(ui, dest) @@ -133,7 +170,7 @@ def clone(ui, source, dest=None, pull=False, rev=None, update=True, dest_path = None dir_cleanup = None if dest_repo.local(): - dest_path = os.path.realpath(dest) + dest_path = os.path.realpath(dest_repo.root) dir_cleanup = DirCleanup(dest_path) abspath = source From 9f04cf77e66f09c7bb6a47cc315d81cef385d9b4 Mon Sep 17 00:00:00 2001 From: Vadim Gelfer Date: Fri, 28 Jul 2006 10:46:41 -0700 Subject: [PATCH 2/2] mq: add qclone command --- hgext/mq.py | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) diff --git a/hgext/mq.py b/hgext/mq.py index 590c55eb2d..89ed0f6eff 100644 --- a/hgext/mq.py +++ b/hgext/mq.py @@ -38,7 +38,8 @@ versionstr = "0.45" repomap = {} -commands.norepo += " qversion" +commands.norepo += " qclone qversion" + class queue: def __init__(self, ui, path, patchdir=None): self.basepath = path @@ -1177,6 +1178,52 @@ def init(ui, repo, **opts): r.add(['.hgignore', 'series']) return 0 +def clone(ui, source, dest=None, **opts): + '''clone main and patch repository at same time + + If source is local, destination will have no patches applied. If + source is remote, this command can not check if patches are + applied in source, so cannot guarantee that patches are not + applied in destination. If you clone remote repository, be sure + before that it has no patches applied. + + Source patch repository is looked for in /.hg/patches by + default. Use -p to change. + ''' + ui.setconfig_remoteopts(**opts) + if dest is None: + dest = hg.defaultdest(source) + sr = hg.repository(ui, ui.expandpath(source)) + qbase, destrev = None, None + if sr.local(): + reposetup(ui, sr) + sq = repomap[sr] + if sq.applied: + qbase = revlog.bin(sq.applied[0].split(':')[0]) + if not hg.islocal(dest): + destrev = sr.parents(qbase)[0] + ui.note(_('cloning main repo\n')) + sr, dr = hg.clone(ui, sr, dest, + pull=opts['pull'], + rev=destrev, + update=False, + stream=opts['uncompressed']) + ui.note(_('cloning patch repo\n')) + spr, dpr = hg.clone(ui, opts['patches'] or (sr.url() + '/.hg/patches'), + dr.url() + '/.hg/patches', + pull=opts['pull'], + update=not opts['noupdate'], + stream=opts['uncompressed']) + if dr.local(): + if qbase: + ui.note(_('stripping applied patches from destination repo\n')) + reposetup(ui, dr) + dq = repomap[dr] + dq.strip(dr, qbase, update=False, backup=None) + if not opts['noupdate']: + ui.note(_('updating destination repo\n')) + dr.update(dr.changelog.tip()) + def commit(ui, repo, *pats, **opts): """commit changes in the queue repository""" q = repomap[repo] @@ -1369,6 +1416,16 @@ def reposetup(ui, repo): cmdtable = { "qapplied": (applied, [], 'hg qapplied [PATCH]'), + "qclone": (clone, + [('', 'pull', None, _('use pull protocol to copy metadata')), + ('U', 'noupdate', None, _('do not update the new working directories')), + ('', 'uncompressed', None, + _('use uncompressed transfer (fast over LAN)')), + ('e', 'ssh', '', _('specify ssh command to use')), + ('p', 'patches', '', _('location of source patch repo')), + ('', 'remotecmd', '', + _('specify hg command to run on the remote side'))], + 'hg qclone [OPTION]... SOURCE [DEST]'), "qcommit|qci": (commit, commands.table["^commit|ci"][1],