diff options
Diffstat (limited to 'mercurial/hg.py')
-rw-r--r-- | mercurial/hg.py | 189 |
1 files changed, 78 insertions, 111 deletions
diff --git a/mercurial/hg.py b/mercurial/hg.py index 7d452df..0f37d26 100644 --- a/mercurial/hg.py +++ b/mercurial/hg.py @@ -9,8 +9,8 @@ from i18n import _ from lock import release from node import hex, nullid -import localrepo, bundlerepo, httppeer, sshpeer, statichttprepo, bookmarks -import lock, util, extensions, error, node, scmutil +import localrepo, bundlerepo, httprepo, sshrepo, statichttprepo, bookmarks +import lock, util, extensions, error, node import cmdutil, discovery import merge as mergemod import verify as verifymod @@ -20,22 +20,21 @@ def _local(path): path = util.expandpath(util.urllocalpath(path)) return (os.path.isfile(path) and bundlerepo or localrepo) -def addbranchrevs(lrepo, other, branches, revs): - peer = other.peer() # a courtesy to callers using a localrepo for other +def addbranchrevs(lrepo, repo, branches, revs): hashbranch, branches = branches if not hashbranch and not branches: return revs or None, revs and revs[0] or None revs = revs and list(revs) or [] - if not peer.capable('branchmap'): + if not repo.capable('branchmap'): if branches: raise util.Abort(_("remote branch lookup not supported")) revs.append(hashbranch) return revs, revs[0] - branchmap = peer.branchmap() + branchmap = repo.branchmap() def primary(branch): if branch == '.': - if not lrepo: + if not lrepo or not lrepo.local(): raise util.Abort(_("dirstate branch not accessible")) branch = lrepo.dirstate.branch() if branch in branchmap: @@ -65,9 +64,9 @@ def parseurl(path, branches=None): schemes = { 'bundle': bundlerepo, 'file': _local, - 'http': httppeer, - 'https': httppeer, - 'ssh': sshpeer, + 'http': httprepo, + 'https': httprepo, + 'ssh': sshrepo, 'static-http': statichttprepo, } @@ -89,29 +88,20 @@ def islocal(repo): return False return repo.local() -def _peerorrepo(ui, path, create=False): +def repository(ui, path='', create=False): """return a repository object for the specified path""" - obj = _peerlookup(path).instance(ui, path, create) - ui = getattr(obj, "ui", ui) + repo = _peerlookup(path).instance(ui, path, create) + ui = getattr(repo, "ui", ui) for name, module in extensions.extensions(): hook = getattr(module, 'reposetup', None) if hook: - hook(ui, obj) - return obj - -def repository(ui, path='', create=False): - """return a repository object for the specified path""" - peer = _peerorrepo(ui, path, create) - repo = peer.local() - if not repo: - raise util.Abort(_("repository '%s' is not local") % - (path or peer.url())) + hook(ui, repo) return repo -def peer(uiorrepo, opts, path, create=False): +def peer(ui, opts, path, create=False): '''return a repository peer for the specified path''' - rui = remoteui(uiorrepo, opts) - return _peerorrepo(rui, path, create).peer() + rui = remoteui(ui, opts) + return repository(rui, path, create) def defaultdest(source): '''return default destination of clone if none is given''' @@ -134,7 +124,7 @@ def share(ui, source, dest=None, update=True): srcrepo = repository(ui, source) rev, checkout = addbranchrevs(srcrepo, srcrepo, branches, None) else: - srcrepo = source.local() + srcrepo = source origsource = source = srcrepo.url() checkout = None @@ -184,46 +174,13 @@ def share(ui, source, dest=None, update=True): continue _update(r, uprev) -def copystore(ui, srcrepo, destpath): - '''copy files from store of srcrepo in destpath - - returns destlock - ''' - destlock = None - try: - hardlink = None - num = 0 - srcpublishing = srcrepo.ui.configbool('phases', 'publish', True) - for f in srcrepo.store.copylist(): - if srcpublishing and f.endswith('phaseroots'): - continue - src = os.path.join(srcrepo.sharedpath, f) - dst = os.path.join(destpath, f) - dstbase = os.path.dirname(dst) - if dstbase and not os.path.exists(dstbase): - os.mkdir(dstbase) - if os.path.exists(src): - if dst.endswith('data'): - # lock to avoid premature writing to the target - destlock = lock.lock(os.path.join(dstbase, "lock")) - hardlink, n = util.copyfiles(src, dst, hardlink) - num += n - if hardlink: - ui.debug("linked %d files\n" % num) - else: - ui.debug("copied %d files\n" % num) - return destlock - except: # re-raises - release(destlock) - raise - def clone(ui, peeropts, source, dest=None, pull=False, rev=None, update=True, stream=False, branch=None): """Make a copy of an existing repository. Create a copy of an existing repository in a new directory. The source and destination are URLs, as passed to the repository - function. Returns a pair of repository peers, the source and + function. Returns a pair of repository objects, the source and newly created destination. The location of the source is added to the new repository's @@ -257,12 +214,12 @@ def clone(ui, peeropts, source, dest=None, pull=False, rev=None, if isinstance(source, str): origsource = ui.expandpath(source) source, branch = parseurl(origsource, branch) - srcpeer = peer(ui, peeropts, source) + srcrepo = repository(remoteui(ui, peeropts), source) else: - srcpeer = source.peer() # in case we were called with a localrepo + srcrepo = source branch = (None, branch or []) - origsource = source = srcpeer.url() - rev, checkout = addbranchrevs(srcpeer, srcpeer, branch, rev) + origsource = source = srcrepo.url() + rev, checkout = addbranchrevs(srcrepo, srcrepo, branch, rev) if dest is None: dest = defaultdest(source) @@ -273,8 +230,6 @@ def clone(ui, peeropts, source, dest=None, pull=False, rev=None, dest = util.urllocalpath(dest) source = util.urllocalpath(source) - if not dest: - raise util.Abort(_("empty destination path is not valid")) if os.path.exists(dest): if not os.path.isdir(dest): raise util.Abort(_("destination '%s' already exists") % dest) @@ -292,7 +247,6 @@ def clone(ui, peeropts, source, dest=None, pull=False, rev=None, self.rmtree(self.dir_, True) srclock = destlock = dircleanup = None - srcrepo = srcpeer.local() try: abspath = origsource if islocal(origsource): @@ -302,8 +256,7 @@ def clone(ui, peeropts, source, dest=None, pull=False, rev=None, dircleanup = DirCleanup(dest) copy = False - if (srcrepo and srcrepo.cancopy() and islocal(dest) - and not srcrepo.revs("secret()")): + if srcrepo.cancopy() and islocal(dest): copy = not pull and not rev if copy: @@ -334,16 +287,34 @@ def clone(ui, peeropts, source, dest=None, pull=False, rev=None, % dest) raise - destlock = copystore(ui, srcrepo, destpath) + hardlink = None + num = 0 + for f in srcrepo.store.copylist(): + src = os.path.join(srcrepo.sharedpath, f) + dst = os.path.join(destpath, f) + dstbase = os.path.dirname(dst) + if dstbase and not os.path.exists(dstbase): + os.mkdir(dstbase) + if os.path.exists(src): + if dst.endswith('data'): + # lock to avoid premature writing to the target + destlock = lock.lock(os.path.join(dstbase, "lock")) + hardlink, n = util.copyfiles(src, dst, hardlink) + num += n + if hardlink: + ui.debug("linked %d files\n" % num) + else: + ui.debug("copied %d files\n" % num) # we need to re-init the repo after manually copying the data # into it - destpeer = peer(ui, peeropts, dest) + destrepo = repository(remoteui(ui, peeropts), dest) srcrepo.hook('outgoing', source='clone', node=node.hex(node.nullid)) else: try: - destpeer = peer(ui, peeropts, dest, create=True) + destrepo = repository(remoteui(ui, peeropts), dest, + create=True) except OSError, inst: if inst.errno == errno.EEXIST: dircleanup.close() @@ -353,52 +324,35 @@ def clone(ui, peeropts, source, dest=None, pull=False, rev=None, revs = None if rev: - if not srcpeer.capable('lookup'): + if not srcrepo.capable('lookup'): raise util.Abort(_("src repository does not support " "revision lookup and so doesn't " "support clone by revision")) - revs = [srcpeer.lookup(r) for r in rev] + revs = [srcrepo.lookup(r) for r in rev] checkout = revs[0] - if destpeer.local(): - destpeer.local().clone(srcpeer, heads=revs, stream=stream) - elif srcrepo: - srcrepo.push(destpeer, revs=revs) + if destrepo.local(): + destrepo.clone(srcrepo, heads=revs, stream=stream) + elif srcrepo.local(): + srcrepo.push(destrepo, revs=revs) else: raise util.Abort(_("clone from remote to remote not supported")) if dircleanup: dircleanup.close() - # clone all bookmarks except divergent ones - destrepo = destpeer.local() - if destrepo and srcpeer.capable("pushkey"): - rb = srcpeer.listkeys('bookmarks') - for k, n in rb.iteritems(): - try: - m = destrepo.lookup(n) - destrepo._bookmarks[k] = m - except error.RepoLookupError: - pass - if rb: - bookmarks.write(destrepo) - elif srcrepo and destpeer.capable("pushkey"): - for k, n in srcrepo._bookmarks.iteritems(): - destpeer.pushkey('bookmarks', k, '', hex(n)) - - if destrepo: + if destrepo.local(): fp = destrepo.opener("hgrc", "w", text=True) fp.write("[paths]\n") - u = util.url(abspath) - u.passwd = None - defaulturl = str(u) - fp.write("default = %s\n" % defaulturl) + fp.write("default = %s\n" % abspath) fp.close() - destrepo.ui.setconfig('paths', 'default', defaulturl) + destrepo.ui.setconfig('paths', 'default', abspath) if update: if update is not True: - checkout = srcrepo.lookup(update) + checkout = update + if srcrepo.local(): + checkout = srcrepo.lookup(update) for test in (checkout, 'default', 'tip'): if test is None: continue @@ -411,13 +365,26 @@ def clone(ui, peeropts, source, dest=None, pull=False, rev=None, destrepo.ui.status(_("updating to branch %s\n") % bn) _update(destrepo, uprev) - return srcpeer, destpeer + # clone all bookmarks + if destrepo.local() and srcrepo.capable("pushkey"): + rb = srcrepo.listkeys('bookmarks') + for k, n in rb.iteritems(): + try: + m = destrepo.lookup(n) + destrepo._bookmarks[k] = m + except error.RepoLookupError: + pass + if rb: + bookmarks.write(destrepo) + elif srcrepo.local() and destrepo.capable("pushkey"): + for k, n in srcrepo._bookmarks.iteritems(): + destrepo.pushkey('bookmarks', k, '', hex(n)) + + return srcrepo, destrepo finally: release(srclock, destlock) if dircleanup is not None: dircleanup.cleanup() - if srcpeer is not None: - srcpeer.close() def _showstats(repo, stats): repo.ui.status(_("%d files updated, %d files merged, " @@ -518,14 +485,14 @@ def _outgoing(ui, repo, dest, opts): ui.status(_('comparing with %s\n') % util.hidepassword(dest)) revs, checkout = addbranchrevs(repo, repo, branches, opts.get('rev')) if revs: - revs = [repo.lookup(rev) for rev in scmutil.revrange(repo, revs)] + revs = [repo.lookup(rev) for rev in revs] other = peer(repo, opts, dest) - outgoing = discovery.findcommonoutgoing(repo, other, revs, - force=opts.get('force')) - o = outgoing.missing + common, outheads = discovery.findcommonoutgoing(repo, other, revs, + force=opts.get('force')) + o = repo.changelog.findmissing(common, outheads) if not o: - scmutil.nochangesfound(repo.ui, repo, outgoing.excluded) + ui.status(_("no changes found\n")) return None return o @@ -570,7 +537,7 @@ def verify(repo): def remoteui(src, opts): 'build a remote ui from ui or repo and opts' - if util.safehasattr(src, 'baseui'): # looks like a repository + if hasattr(src, 'baseui'): # looks like a repository dst = src.baseui.copy() # drop repo-specific config src = src.ui # copy target options from repo else: # assume it's a global ui object |