diff --git a/hgext/histedit.py b/hgext/histedit.py --- a/hgext/histedit.py +++ b/hgext/histedit.py @@ -412,7 +412,7 @@ def histedit(ui, repo, *parent, **opts): ui.status(_('comparing with %s\n') % util.hidepassword(dest)) revs, checkout = hg.addbranchrevs(repo, repo, revs, None) - other = hg.repository(hg.remoteui(repo, opts), dest) + other = hg.peer(repo, opts, dest) if revs: revs = [repo.lookup(rev) for rev in revs] diff --git a/hgext/largefiles/localstore.py b/hgext/largefiles/localstore.py --- a/hgext/largefiles/localstore.py +++ b/hgext/largefiles/localstore.py @@ -22,9 +22,9 @@ class localstore(basestore.basestore): the user cache.''' def __init__(self, ui, repo, remote): - url = os.path.join(remote.path, '.hg', lfutil.longname) + url = os.path.join(remote.local().path, '.hg', lfutil.longname) super(localstore, self).__init__(ui, repo, util.expandpath(url)) - self.remote = remote + self.remote = remote.local() def put(self, source, hash): util.makedirs(os.path.dirname(lfutil.storepath(self.remote, hash))) diff --git a/hgext/largefiles/overrides.py b/hgext/largefiles/overrides.py --- a/hgext/largefiles/overrides.py +++ b/hgext/largefiles/overrides.py @@ -722,7 +722,7 @@ def overrideclone(orig, ui, source, dest return True if opts.get('all_largefiles'): sourcerepo, destrepo = result - success, missing = lfcommands.downloadlfiles(ui, destrepo, None) + success, missing = lfcommands.downloadlfiles(ui, destrepo.local(), None) return missing != 0 return result is None diff --git a/hgext/mq.py b/hgext/mq.py --- a/hgext/mq.py +++ b/hgext/mq.py @@ -2245,7 +2245,7 @@ def clone(ui, source, dest=None, **opts) # main repo (destination and sources) if dest is None: dest = hg.defaultdest(source) - sr = hg.repository(hg.remoteui(ui, opts), ui.expandpath(source)) + sr = hg.peer(ui, opts, ui.expandpath(source)) # patches repo (source only) if opts.get('patches'): @@ -2253,18 +2253,19 @@ def clone(ui, source, dest=None, **opts) else: patchespath = patchdir(sr) try: - hg.repository(ui, patchespath) + hg.peer(ui, opts, patchespath) except error.RepoError: raise util.Abort(_('versioned patch repository not found' ' (see init --mq)')) qbase, destrev = None, None if sr.local(): - if sr.mq.applied and sr[qbase].phase() != phases.secret: - qbase = sr.mq.applied[0].node + repo = sr.local() + if repo.mq.applied and repo[qbase].phase() != phases.secret: + qbase = repo.mq.applied[0].node if not hg.islocal(dest): - heads = set(sr.heads()) - destrev = list(heads.difference(sr.heads(qbase))) - destrev.append(sr.changelog.parents(qbase)[0]) + heads = set(repo.heads()) + destrev = list(heads.difference(repo.heads(qbase))) + destrev.append(repo.changelog.parents(qbase)[0]) elif sr.capable('lookup'): try: qbase = sr.lookup('qbase') @@ -2284,13 +2285,14 @@ def clone(ui, source, dest=None, **opts) stream=opts.get('uncompressed')) if dr.local(): + repo = dr.local() if qbase: ui.note(_('stripping applied patches from destination ' 'repository\n')) - dr.mq.strip(dr, [qbase], update=False, backup=None) + repo.mq.strip(repo, [qbase], update=False, backup=None) if not opts.get('noupdate'): ui.note(_('updating destination repository\n')) - hg.update(dr, dr.changelog.tip()) + hg.update(repo, repo.changelog.tip()) @command("qcommit|qci", commands.table["^commit|ci"][1], diff --git a/hgext/relink.py b/hgext/relink.py --- a/hgext/relink.py +++ b/hgext/relink.py @@ -43,8 +43,6 @@ def relink(ui, repo, origin=None, **opts raise util.Abort(_('hardlinks are not supported on this system')) src = hg.repository(ui, ui.expandpath(origin or 'default-relink', origin or 'default')) - if not src.local(): - raise util.Abort(_('must specify local origin repository')) ui.status(_('relinking %s to %s\n') % (src.store.path, repo.store.path)) if repo.root == src.root: ui.status(_('there is nothing to relink\n')) diff --git a/hgext/transplant.py b/hgext/transplant.py --- a/hgext/transplant.py +++ b/hgext/transplant.py @@ -139,7 +139,7 @@ class transplanter(object): continue if pulls: if source != repo: - repo.pull(source, heads=pulls) + repo.pull(source.peer(), heads=pulls) merge.update(repo, pulls[-1], False, False, None) p1, p2 = repo.dirstate.parents() pulls = [] @@ -203,7 +203,7 @@ class transplanter(object): os.unlink(patchfile) tr.close() if pulls: - repo.pull(source, heads=pulls) + repo.pull(source.peer(), heads=pulls) merge.update(repo, pulls[-1], False, False, None) finally: self.saveseries(revmap, merges) @@ -614,9 +614,9 @@ def transplant(ui, repo, *revs, **opts): sourcerepo = opts.get('source') if sourcerepo: - source = hg.peer(ui, opts, ui.expandpath(sourcerepo)) - branches = map(source.lookup, opts.get('branch', ())) - source, csets, cleanupfn = bundlerepo.getremotechanges(ui, repo, source, + peer = hg.peer(ui, opts, ui.expandpath(sourcerepo)) + branches = map(peer.lookup, opts.get('branch', ())) + source, csets, cleanupfn = bundlerepo.getremotechanges(ui, repo, peer, onlyheads=branches, force=True) else: source = repo diff --git a/mercurial/bundlerepo.py b/mercurial/bundlerepo.py --- a/mercurial/bundlerepo.py +++ b/mercurial/bundlerepo.py @@ -344,8 +344,8 @@ def getremotechanges(ui, repo, other, on bundle = None bundlerepo = None - localrepo = other - if bundlename or not other.local(): + localrepo = other.local() + if bundlename or not localrepo: # create a bundle (uncompressed if other repo is not local) if other.capable('getbundle'): @@ -356,12 +356,12 @@ def getremotechanges(ui, repo, other, on rheads = None else: cg = other.changegroupsubset(incoming, rheads, 'incoming') - bundletype = other.local() and "HG10BZ" or "HG10UN" + bundletype = localrepo and "HG10BZ" or "HG10UN" fname = bundle = changegroup.writebundle(cg, bundlename, bundletype) # keep written bundle? if bundlename: bundle = None - if not other.local(): + if not localrepo: # use the created uncompressed bundlerepo localrepo = bundlerepo = bundlerepository(ui, repo.root, fname) # this repo contains local and other now, so filter out local again diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -1784,7 +1784,7 @@ def debugdiscovery(ui, repo, remoteurl=" # make sure tests are repeatable random.seed(12323) - def doit(localheads, remoteheads): + def doit(localheads, remoteheads, remote=remote): if opts.get('old'): if localheads: raise util.Abort('cannot use localheads with old style ' @@ -3463,10 +3463,11 @@ def identify(ui, repo, source=None, rev= if source: source, branches = hg.parseurl(ui.expandpath(source)) - repo = hg.peer(ui, opts, source) - revs, checkout = hg.addbranchrevs(repo, repo, branches, None) - - if not repo.local(): + peer = hg.peer(ui, opts, source) + repo = peer.local() + revs, checkout = hg.addbranchrevs(repo, peer, branches, None) + + if not repo: if num or branch or tags: raise util.Abort( _("can't query remote revision number, branch, or tags")) @@ -3475,16 +3476,16 @@ def identify(ui, repo, source=None, rev= if not rev: rev = "tip" - remoterev = repo.lookup(rev) + remoterev = peer.lookup(rev) if default or id: output = [hexfunc(remoterev)] def getbms(): bms = [] - if 'bookmarks' in repo.listkeys('namespaces'): + if 'bookmarks' in peer.listkeys('namespaces'): hexremoterev = hex(remoterev) - bms = [bm for bm, bmr in repo.listkeys('bookmarks').iteritems() + bms = [bm for bm, bmr in peer.listkeys('bookmarks').iteritems() if bmr == hexremoterev] return bms diff --git a/mercurial/discovery.py b/mercurial/discovery.py --- a/mercurial/discovery.py +++ b/mercurial/discovery.py @@ -169,7 +169,7 @@ def checkheads(repo, remote, outgoing, r # 2. Check for new branches on the remote. if remote.local(): - remotemap = phases.visiblebranchmap(remote) + remotemap = phases.visiblebranchmap(remote.local()) else: remotemap = remote.branchmap() newbranches = branches - set(remotemap) diff --git a/mercurial/hg.py b/mercurial/hg.py --- a/mercurial/hg.py +++ b/mercurial/hg.py @@ -20,21 +20,22 @@ def _local(path): path = util.expandpath(util.urllocalpath(path)) return (os.path.isfile(path) and bundlerepo or localrepo) -def addbranchrevs(lrepo, repo, branches, revs): +def addbranchrevs(lrepo, other, branches, revs): + peer = other.peer() # a courtesy to callers using a localrepo for other 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 repo.capable('branchmap'): + if not peer.capable('branchmap'): if branches: raise util.Abort(_("remote branch lookup not supported")) revs.append(hashbranch) return revs, revs[0] - branchmap = repo.branchmap() + branchmap = peer.branchmap() def primary(branch): if branch == '.': - if not lrepo or not lrepo.local(): + if not lrepo: raise util.Abort(_("dirstate branch not accessible")) branch = lrepo.dirstate.branch() if branch in branchmap: @@ -88,20 +89,29 @@ def islocal(repo): return False return repo.local() -def repository(ui, path='', create=False): +def _peerorrepo(ui, path, create=False): """return a repository object for the specified path""" - repo = _peerlookup(path).instance(ui, path, create) - ui = getattr(repo, "ui", ui) + obj = _peerlookup(path).instance(ui, path, create) + ui = getattr(obj, "ui", ui) for name, module in extensions.extensions(): hook = getattr(module, 'reposetup', None) if hook: - hook(ui, repo) + 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())) return repo def peer(uiorrepo, opts, path, create=False): '''return a repository peer for the specified path''' rui = remoteui(uiorrepo, opts) - return repository(rui, path, create) + return _peerorrepo(rui, path, create).peer() def defaultdest(source): '''return default destination of clone if none is given''' @@ -124,7 +134,7 @@ def share(ui, source, dest=None, update= srcrepo = repository(ui, source) rev, checkout = addbranchrevs(srcrepo, srcrepo, branches, None) else: - srcrepo = source + srcrepo = source.local() origsource = source = srcrepo.url() checkout = None @@ -213,7 +223,7 @@ def clone(ui, peeropts, source, dest=Non 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 objects, the source and + function. Returns a pair of repository peers, the source and newly created destination. The location of the source is added to the new repository's @@ -247,12 +257,12 @@ def clone(ui, peeropts, source, dest=Non if isinstance(source, str): origsource = ui.expandpath(source) source, branch = parseurl(origsource, branch) - srcrepo = repository(remoteui(ui, peeropts), source) + srcpeer = peer(ui, peeropts, source) else: - srcrepo = source + srcpeer = source.peer() # in case we were called with a localrepo branch = (None, branch or []) - origsource = source = srcrepo.url() - rev, checkout = addbranchrevs(srcrepo, srcrepo, branch, rev) + origsource = source = srcpeer.url() + rev, checkout = addbranchrevs(srcpeer, srcpeer, branch, rev) if dest is None: dest = defaultdest(source) @@ -282,6 +292,7 @@ def clone(ui, peeropts, source, dest=Non self.rmtree(self.dir_, True) srclock = destlock = dircleanup = None + srcrepo = srcpeer.local() try: abspath = origsource if islocal(origsource): @@ -291,7 +302,7 @@ def clone(ui, peeropts, source, dest=Non dircleanup = DirCleanup(dest) copy = False - if srcrepo.cancopy() and islocal(dest) and not srcrepo.revs("secret()"): + if srcpeer.cancopy() and islocal(dest) and not srcrepo.revs("secret()"): copy = not pull and not rev if copy: @@ -326,13 +337,12 @@ def clone(ui, peeropts, source, dest=Non # we need to re-init the repo after manually copying the data # into it - destrepo = repository(remoteui(ui, peeropts), dest) + destpeer = peer(ui, peeropts, dest) srcrepo.hook('outgoing', source='clone', node=node.hex(node.nullid)) else: try: - destrepo = repository(remoteui(ui, peeropts), dest, - create=True) + destpeer = peer(ui, peeropts, dest, create=True) except OSError, inst: if inst.errno == errno.EEXIST: dircleanup.close() @@ -342,16 +352,16 @@ def clone(ui, peeropts, source, dest=Non revs = None if rev: - if not srcrepo.capable('lookup'): + if not srcpeer.capable('lookup'): raise util.Abort(_("src repository does not support " "revision lookup and so doesn't " "support clone by revision")) - revs = [srcrepo.lookup(r) for r in rev] + revs = [srcpeer.lookup(r) for r in rev] checkout = revs[0] - if destrepo.local(): - destrepo.clone(srcrepo, heads=revs, stream=stream) - elif srcrepo.local(): - srcrepo.push(destrepo, revs=revs) + if destpeer.local(): + destpeer.local().clone(srcpeer, heads=revs, stream=stream) + elif srcrepo: + srcrepo.push(destpeer, revs=revs) else: raise util.Abort(_("clone from remote to remote not supported")) @@ -359,8 +369,9 @@ def clone(ui, peeropts, source, dest=Non dircleanup.close() # clone all bookmarks except divergent ones - if destrepo.local() and srcrepo.capable("pushkey"): - rb = srcrepo.listkeys('bookmarks') + destrepo = destpeer.local() + if destrepo and srcpeer.capable("pushkey"): + rb = srcpeer.listkeys('bookmarks') for k, n in rb.iteritems(): try: m = destrepo.lookup(n) @@ -369,11 +380,11 @@ def clone(ui, peeropts, source, dest=Non pass if rb: bookmarks.write(destrepo) - elif srcrepo.local() and destrepo.capable("pushkey"): + elif srcrepo and destpeer.capable("pushkey"): for k, n in srcrepo._bookmarks.iteritems(): - destrepo.pushkey('bookmarks', k, '', hex(n)) + destpeer.pushkey('bookmarks', k, '', hex(n)) - if destrepo.local(): + if destrepo: fp = destrepo.opener("hgrc", "w", text=True) fp.write("[paths]\n") u = util.url(abspath) @@ -386,9 +397,7 @@ def clone(ui, peeropts, source, dest=Non if update: if update is not True: - checkout = update - if srcrepo.local(): - checkout = srcrepo.lookup(update) + checkout = srcrepo.lookup(update) for test in (checkout, 'default', 'tip'): if test is None: continue @@ -401,13 +410,13 @@ def clone(ui, peeropts, source, dest=Non destrepo.ui.status(_("updating to branch %s\n") % bn) _update(destrepo, uprev) - return srcrepo, destrepo + return srcpeer, destpeer finally: release(srclock, destlock) if dircleanup is not None: dircleanup.cleanup() - if srcrepo is not None: - srcrepo.close() + if srcpeer is not None: + srcpeer.close() def _showstats(repo, stats): repo.ui.status(_("%d files updated, %d files merged, " diff --git a/mercurial/repo.py b/mercurial/repo.py --- a/mercurial/repo.py +++ b/mercurial/repo.py @@ -33,6 +33,9 @@ class repository(object): def local(self): return False + def peer(self): + return self + def cancopy(self): return self.local() diff --git a/mercurial/setdiscovery.py b/mercurial/setdiscovery.py --- a/mercurial/setdiscovery.py +++ b/mercurial/setdiscovery.py @@ -100,7 +100,7 @@ def findcommonheads(ui, local, remote, sample = ownheads if remote.local(): # stopgap until we have a proper localpeer that supports batch() - srvheadhashes = phases.visibleheads(remote) + srvheadhashes = phases.visibleheads(remote.local()) yesno = remote.known(dag.externalizeall(sample)) elif remote.capable('batch'): batch = remote.batch() diff --git a/mercurial/subrepo.py b/mercurial/subrepo.py --- a/mercurial/subrepo.py +++ b/mercurial/subrepo.py @@ -503,9 +503,10 @@ class hgsubrepo(abstractsubrepo): % (subrelpath(self), srcurl)) parentrepo = self._repo._subparent shutil.rmtree(self._repo.path) - other, self._repo = hg.clone(self._repo._subparent.ui, {}, - other, self._repo.root, - update=False) + other, cloned = hg.clone(self._repo._subparent.ui, {}, + other, self._repo.root, + update=False) + self._repo = cloned.local() self._initrepo(parentrepo, source, create=True) else: self._repo.ui.status(_('pulling subrepo %s from %s\n')