##// END OF EJS Templates
test: use `printenv.py --line` in `test-ssh.t`...
test: use `printenv.py --line` in `test-ssh.t` This makes the output easier to update and read.

File last commit:

r41522:2fe2f1ba default
r41793:9a8d41fa default
Show More
hg.py
1234 lines | 44.0 KiB | text/x-python | PythonLexer
mpm@selenic.com
Add back links from file revisions to changeset revisions...
r0 # hg.py - repository classes for mercurial
#
Thomas Arendsen Hein
Updated copyright notices and add "and others" to "hg version"
r4635 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
Vadim Gelfer
update copyrights.
r2859 # Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
mpm@selenic.com
Add back links from file revisions to changeset revisions...
r0 #
Martin Geisler
updated license to be explicit about GPL version 2
r8225 # This software may be used and distributed according to the terms of the
Matt Mackall
Update license to GPLv2+
r10263 # GNU General Public License version 2 or any later version.
mpm@selenic.com
Add back links from file revisions to changeset revisions...
r0
Gregory Szorc
hg: use absolute_import
r25939 from __future__ import absolute_import
import errno
Augie Fackler
cleanup: replace uses of util.(md5|sha1|sha256|sha512) with hashlib.\1...
r29341 import hashlib
Gregory Szorc
hg: use absolute_import
r25939 import os
import shutil
Augie Fackler
cleanup: use stat_result[stat.ST_MTIME] instead of stat_result.st_mtime...
r36799 import stat
Gregory Szorc
hg: use absolute_import
r25939
from .i18n import _
Pulkit Goyal
merge: add `--abort` flag which can abort the merge...
r35722 from .node import (
nullid,
)
Jordi Gutiérrez Hermoso
config: use the same hgrc for a cloned repo as for an uninitted repo...
r22837
Gregory Szorc
hg: use absolute_import
r25939 from . import (
bookmarks,
bundlerepo,
Boris Feld
caches: make 'cachetocopy' available in scmutil...
r35784 cacheutil,
Gregory Szorc
hg: use absolute_import
r25939 cmdutil,
FUJIWARA Katsunori
commands: centralize code to update with extra care for non-file components...
r28501 destutil,
Gregory Szorc
hg: use absolute_import
r25939 discovery,
error,
exchange,
extensions,
httppeer,
localrepo,
lock,
Yuya Nishihara
cmdutil: drop aliases for logcmdutil functions (API)...
r35906 logcmdutil,
Pulkit Goyal
remotenames: rename related file and storage dir to logexchange...
r35348 logexchange,
Gregory Szorc
hg: use absolute_import
r25939 merge as mergemod,
Gregory Szorc
hg: recognize include and exclude patterns when cloning...
r39586 narrowspec,
Gregory Szorc
hg: use absolute_import
r25939 node,
phases,
Gregory Szorc
hg: raise Abort on invalid path...
r41625 pycompat,
Martin von Zweigbergk
narrow: detect if narrowspec was changed in a different share...
r41072 repository as repositorymod,
Gregory Szorc
hg: use absolute_import
r25939 scmutil,
sshpeer,
statichttprepo,
ui as uimod,
unionrepo,
url,
util,
verify as verifymod,
Pierre-Yves David
vfs: use 'vfs' module directly in 'mercurial.hg'...
r31218 vfs as vfsmod,
Gregory Szorc
hg: use absolute_import
r25939 )
release = lock.release
mpm@selenic.com
Add back links from file revisions to changeset revisions...
r0
Martijn Pieters
share: move magic string to a constant
r29424 # shared features
sharedbookmarks = 'bookmarks'
Vadim Gelfer
clean up hg.py: move repo constructor code into each repo module
r2740 def _local(path):
Mads Kiilerich
util: rename the util.localpath that uses url to urllocalpath (issue2875)...
r14825 path = util.expandpath(util.urllocalpath(path))
Gregory Szorc
hg: raise Abort on invalid path...
r41625
try:
isfile = os.path.isfile(path)
# Python 2 raises TypeError, Python 3 ValueError.
except (TypeError, ValueError) as e:
raise error.Abort(_('invalid path %s: %s') % (
path, pycompat.bytestr(e)))
return isfile and bundlerepo or localrepo
Vadim Gelfer
hg.repository: make protocol table driven....
r2469
Sune Foldager
peer: introduce peer methods to prepare for peer classes...
r17191 def addbranchrevs(lrepo, other, branches, revs):
peer = other.peer() # a courtesy to callers using a localrepo for other
Sune Foldager
improve --branch processing (and differentiate from # syntax)...
r11322 hashbranch, branches = branches
if not hashbranch and not branches:
Pierre-Yves David
repair: use `first` instead of direct indexing...
r22818 x = revs or None
Martin von Zweigbergk
addbranchrevs: no longer accept revset as "revs" (API)...
r37499 if revs:
Pierre-Yves David
repair: use `first` instead of direct indexing...
r22818 y = revs[0]
else:
y = None
return x, y
Jordi Gutiérrez Hermoso
style: kill ersatz if-else ternary operators...
r24306 if revs:
revs = list(revs)
else:
revs = []
Sune Foldager
peer: introduce peer methods to prepare for peer classes...
r17191 if not peer.capable('branchmap'):
Sune Foldager
improve --branch processing (and differentiate from # syntax)...
r11322 if branches:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_("remote branch lookup not supported"))
Sune Foldager
improve --branch processing (and differentiate from # syntax)...
r11322 revs.append(hashbranch)
Sune Foldager
addbranchrevs: fallback for older servers
r10380 return revs, revs[0]
Gregory Szorc
hg: use command executor for wire protocol commands...
r37658
with peer.commandexecutor() as e:
branchmap = e.callcommand('branchmap', {}).result()
Sune Foldager
improve --branch processing (and differentiate from # syntax)...
r11322
Matt Mackall
branch: operate on branch names in local string space where possible...
r13047 def primary(branch):
if branch == '.':
Sune Foldager
peer: introduce peer methods to prepare for peer classes...
r17191 if not lrepo:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_("dirstate branch not accessible"))
Matt Mackall
branch: operate on branch names in local string space where possible...
r13047 branch = lrepo.dirstate.branch()
if branch in branchmap:
revs.extend(node.hex(r) for r in reversed(branchmap[branch]))
Sune Foldager
improve --branch processing (and differentiate from # syntax)...
r11322 return True
Sune Foldager
interpret repo#name url syntax as branch instead of revision...
r10365 else:
Sune Foldager
improve --branch processing (and differentiate from # syntax)...
r11322 return False
for branch in branches:
Matt Mackall
branch: operate on branch names in local string space where possible...
r13047 if not primary(branch):
Sune Foldager
improve --branch processing (and differentiate from # syntax)...
r11322 raise error.RepoLookupError(_("unknown branch '%s'") % branch)
if hashbranch:
Matt Mackall
branch: operate on branch names in local string space where possible...
r13047 if not primary(hashbranch):
Sune Foldager
improve --branch processing (and differentiate from # syntax)...
r11322 revs.append(hashbranch)
Sune Foldager
interpret repo#name url syntax as branch instead of revision...
r10365 return revs, revs[0]
Brodie Rao
hg: use url.url to parse branch names in parseurl()
r13824 def parseurl(path, branches=None):
Sune Foldager
improve --branch processing (and differentiate from # syntax)...
r11322 '''parse url#branch, returning (url, (branch, branches))'''
Matt Mackall
move parseurl from cmdutil to hg
r5177
Brodie Rao
url: move URL parsing functions into util to improve startup time...
r14076 u = util.url(path)
Thomas Arendsen Hein
hg: make parseurl() consistently return normalised path...
r13897 branch = None
if u.fragment:
branch = u.fragment
u.fragment = None
Pulkit Goyal
py3: replace str() with bytes()
r31841 return bytes(u), (branch, branches or [])
Matt Mackall
move parseurl from cmdutil to hg
r5177
Matt Mackall
hg: move peerschemes back to schemes...
r14606 schemes = {
Matt Mackall
hg: split peer and repo lookup tables
r14568 'bundle': bundlerepo,
Mads Kiilerich
unionrepo: read-only operations on a union of two localrepos...
r18944 'union': unionrepo,
Matt Mackall
hg: split peer and repo lookup tables
r14568 'file': _local,
Peter Arrenbrecht
peer: introduce real peer classes...
r17192 'http': httppeer,
'https': httppeer,
'ssh': sshpeer,
Matt Mackall
hg: split peer and repo lookup tables
r14568 'static-http': statichttprepo,
}
def _peerlookup(path):
u = util.url(path)
scheme = u.scheme or 'file'
Matt Mackall
hg: move peerschemes back to schemes...
r14606 thing = schemes.get(scheme) or schemes['file']
Matt Mackall
hg: split peer and repo lookup tables
r14568 try:
return thing(path)
except TypeError:
Yuya Nishihara
hg: explicitly check that peer lookup object has instance() if call failed...
r25365 # we can't test callable(thing) because 'thing' can be an unloaded
# module that implements __call__
if not util.safehasattr(thing, 'instance'):
raise
Matt Mackall
hg: split peer and repo lookup tables
r14568 return thing
Matt Mackall
hg: rearrange peer scheme lookup...
r14605 def islocal(repo):
Siddharth Agarwal
hg: note that islocal only accepts paths pointing to repos...
r20355 '''return true if repo (or path pointing to repo) is local'''
Pulkit Goyal
py3: check for bytes instead of str in isinstance
r33018 if isinstance(repo, bytes):
Matt Mackall
hg: rearrange peer scheme lookup...
r14605 try:
return _peerlookup(repo).islocal(repo)
except AttributeError:
return False
return repo.local()
Siddharth Agarwal
url: use open and not url.open for local files (issue3624)
r17887 def openpath(ui, path):
'''open path with open if local, url.open if remote'''
Siddharth Agarwal
hg.openpath: use url.islocal to tell if the path is local (issue3624)...
r20354 pathurl = util.url(path, parsequery=False, parsefragment=False)
if pathurl.islocal():
return util.posixfile(pathurl.localpath(), 'rb')
Siddharth Agarwal
url: use open and not url.open for local files (issue3624)
r17887 else:
return url.open(ui, path)
FUJIWARA Katsunori
hg: introduce "wirepeersetupfuncs" to setup wire peer by extensions (issue4109)...
r20858 # a list of (ui, repo) functions called for wire peer initialization
wirepeersetupfuncs = []
Gregory Szorc
hg: pass command intents to repo/peer creation (API)...
r37735 def _peerorrepo(ui, path, create=False, presetupfuncs=None,
Gregory Szorc
hg: allow extra arguments to be passed to repo creation (API)...
r39585 intents=None, createopts=None):
Matt Mackall
hg: rearrange peer scheme lookup...
r14605 """return a repository object for the specified path"""
Gregory Szorc
hg: allow extra arguments to be passed to repo creation (API)...
r39585 obj = _peerlookup(path).instance(ui, path, create, intents=intents,
createopts=createopts)
Sune Foldager
peer: introduce peer methods to prepare for peer classes...
r17191 ui = getattr(obj, "ui", ui)
Jun Wu
dispatch: make request accept additional reposetups...
r32379 for f in presetupfuncs or []:
f(ui, obj)
Yuya Nishihara
extensions: use ui.log() interface to provide detailed loading information...
r41032 ui.log(b'extension', b'- executing reposetup hooks\n')
Boris Feld
extensions: trace the total time of running all reposetup callbacks...
r39546 with util.timedcm('all reposetup') as allreposetupstats:
for name, module in extensions.extensions(ui):
Yuya Nishihara
extensions: use ui.log() interface to provide detailed loading information...
r41032 ui.log(b'extension', b' - running reposetup for %s\n', name)
Boris Feld
extensions: trace the total time of running all reposetup callbacks...
r39546 hook = getattr(module, 'reposetup', None)
if hook:
with util.timedcm('reposetup %r', name) as stats:
hook(ui, obj)
Yuya Nishihara
extensions: use ui.log() interface to provide detailed loading information...
r41032 ui.log(b'extension', b' > reposetup for %s took %s\n',
name, stats)
ui.log(b'extension', b'> all reposetup took %s\n', allreposetupstats)
FUJIWARA Katsunori
hg: introduce "wirepeersetupfuncs" to setup wire peer by extensions (issue4109)...
r20858 if not obj.local():
for f in wirepeersetupfuncs:
f(ui, obj)
Sune Foldager
peer: introduce peer methods to prepare for peer classes...
r17191 return obj
Gregory Szorc
hg: allow extra arguments to be passed to repo creation (API)...
r39585 def repository(ui, path='', create=False, presetupfuncs=None, intents=None,
createopts=None):
Sune Foldager
peer: introduce peer methods to prepare for peer classes...
r17191 """return a repository object for the specified path"""
Gregory Szorc
hg: pass command intents to repo/peer creation (API)...
r37735 peer = _peerorrepo(ui, path, create, presetupfuncs=presetupfuncs,
Gregory Szorc
hg: allow extra arguments to be passed to repo creation (API)...
r39585 intents=intents, createopts=createopts)
Sune Foldager
peer: introduce peer methods to prepare for peer classes...
r17191 repo = peer.local()
if not repo:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_("repository '%s' is not local") %
Sune Foldager
peer: introduce peer methods to prepare for peer classes...
r17191 (path or peer.url()))
Kevin Bullock
filtering: rename filters to their antonyms...
r18382 return repo.filtered('visible')
Matt Mackall
hg: rearrange peer scheme lookup...
r14605
Gregory Szorc
hg: allow extra arguments to be passed to repo creation (API)...
r39585 def peer(uiorrepo, opts, path, create=False, intents=None, createopts=None):
Matt Mackall
hg: add peer method
r14554 '''return a repository peer for the specified path'''
Idan Kamara
peer: change arg name to convey it can be a repo as well
r14839 rui = remoteui(uiorrepo, opts)
Gregory Szorc
hg: allow extra arguments to be passed to repo creation (API)...
r39585 return _peerorrepo(rui, path, create, intents=intents,
createopts=createopts).peer()
Matt Mackall
hg: add peer method
r14554
Vadim Gelfer
hg.py: add islocal() and defaultdest() functions, refactor...
r2719 def defaultdest(source):
Yuya Nishihara
clone: add doctest for default destination
r20799 '''return default destination of clone if none is given
Yuya Nishihara
doctest: bulk-replace string literals with b'' for Python 3...
r34133 >>> defaultdest(b'foo')
Yuya Nishihara
clone: add doctest for default destination
r20799 'foo'
Yuya Nishihara
doctest: bulk-replace string literals with b'' for Python 3...
r34133 >>> defaultdest(b'/foo/bar')
Yuya Nishihara
clone: add doctest for default destination
r20799 'bar'
Yuya Nishihara
doctest: bulk-replace string literals with b'' for Python 3...
r34133 >>> defaultdest(b'/')
Yuya Nishihara
clone: add doctest for default destination
r20799 ''
Yuya Nishihara
doctest: bulk-replace string literals with b'' for Python 3...
r34133 >>> defaultdest(b'')
Yuya Nishihara
clone: abort if default destination has no meaningful name (BC)...
r20800 ''
Yuya Nishihara
doctest: bulk-replace string literals with b'' for Python 3...
r34133 >>> defaultdest(b'http://example.org/')
Yuya Nishihara
clone: abort if default destination has no meaningful name (BC)...
r20800 ''
Yuya Nishihara
doctest: bulk-replace string literals with b'' for Python 3...
r34133 >>> defaultdest(b'http://example.org/foo/')
Yuya Nishihara
clone: add doctest for default destination
r20799 'foo'
'''
Yuya Nishihara
clone: abort if default destination has no meaningful name (BC)...
r20800 path = util.url(source).path
if not path:
return ''
return os.path.basename(os.path.normpath(path))
Matt Mackall
Add a doc string
r2774
Gregory Szorc
hg: move share._getsrcrepo into core...
r36177 def sharedreposource(repo):
"""Returns repository object for source repository of a shared repo.
If repo is not a shared repository, returns None.
"""
if repo.sharedpath == repo.path:
return None
if util.safehasattr(repo, 'srcrepo') and repo.srcrepo:
return repo.srcrepo
# the sharedpath always ends in the .hg; we want the path to the repo
source = repo.vfs.split(repo.sharedpath)[0]
srcurl, branches = parseurl(source)
srcrepo = repository(repo.ui, srcurl)
repo.srcrepo = srcrepo
return srcrepo
Dan Villiom Podlaski Christiansen
share: add --relative flag to store a relative path to the source...
r31133 def share(ui, source, dest=None, update=True, bookmarks=True, defaultpath=None,
relative=False):
Matt Mackall
add helper function to create shared repos
r8800 '''create a shared repository'''
if not islocal(source):
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('can only share local repositories'))
Matt Mackall
add helper function to create shared repos
r8800
Matt Mackall
share: allow dest to default to the basename of source
r8807 if not dest:
Brendan Cully
share: use defaultdest to compute unspecified destination...
r10099 dest = defaultdest(source)
Matt Mackall
Merge with i18n-stable
r9344 else:
dest = ui.expandpath(dest)
Matt Mackall
share: allow dest to default to the basename of source
r8807
Gregory Szorc
py3: check for bytes instead of str in hg.share()...
r36066 if isinstance(source, bytes):
Matt Mackall
add helper function to create shared repos
r8800 origsource = ui.expandpath(source)
Sune Foldager
interpret repo#name url syntax as branch instead of revision...
r10365 source, branches = parseurl(origsource)
Matt Mackall
add helper function to create shared repos
r8800 srcrepo = repository(ui, source)
Sune Foldager
interpret repo#name url syntax as branch instead of revision...
r10365 rev, checkout = addbranchrevs(srcrepo, srcrepo, branches, None)
Matt Mackall
add helper function to create shared repos
r8800 else:
Sune Foldager
peer: introduce peer methods to prepare for peer classes...
r17191 srcrepo = source.local()
Matt Mackall
add helper function to create shared repos
r8800 checkout = None
Gregory Szorc
localrepo: support writing shared file (API)...
r39885 shareditems = set()
if bookmarks:
shareditems.add(sharedbookmarks)
Gregory Szorc
localrepo: support shared repo creation...
r39884 r = repository(ui, dest, create=True, createopts={
'sharedrepo': srcrepo,
'sharedrelative': relative,
Gregory Szorc
localrepo: support writing shared file (API)...
r39885 'shareditems': shareditems,
Gregory Szorc
localrepo: support shared repo creation...
r39884 })
Matt Mackall
add helper function to create shared repos
r8800
Gregory Szorc
localrepo: support writing shared file (API)...
r39885 postshare(srcrepo, r, defaultpath=defaultpath)
Martin von Zweigbergk
share: reload repo after adjusting it in postshare()...
r40609 r = repository(ui, dest)
Gregory Szorc
hg: perform update after pulling during clone with share (issue5103)...
r28632 _postshareupdate(r, update, checkout=checkout)
Matt Harbison
subrepo: share instead of clone if the parent repo is shared (issue5675) (BC)...
r34816 return r
Matt Mackall
add helper function to create shared repos
r8800
Matt Harbison
share: move the implementation of 'unshare' to the 'hg' module...
r34879 def unshare(ui, repo):
"""convert a shared repository to a normal one
Copy the store data to the repo and remove the sharedpath data.
Gregory Szorc
hg: don't reuse repo instance after unshare()...
r39642
Returns a new repository object representing the unshared repository.
The passed repository object is not usable after this function is
called.
Matt Harbison
share: move the implementation of 'unshare' to the 'hg' module...
r34879 """
Martin von Zweigbergk
unshare: use context manager for locks...
r41436 with repo.lock():
Matt Harbison
share: move the implementation of 'unshare' to the 'hg' module...
r34879 # we use locks here because if we race with commit, we
# can end up with extra data in the cloned revlogs that's
# not pointed to by changesets, thus causing verify to
# fail
destlock = copystore(ui, repo, repo.path)
Martin von Zweigbergk
unshare: use context manager for locks...
r41436 with destlock or util.nullcontextmanager():
Matt Harbison
share: move the implementation of 'unshare' to the 'hg' module...
r34879
Martin von Zweigbergk
unshare: use context manager for locks...
r41436 sharefile = repo.vfs.join('sharedpath')
util.rename(sharefile, sharefile + '.old')
repo.requirements.discard('shared')
repo.requirements.discard('relshared')
repo._writerequirements()
Matt Harbison
share: move the implementation of 'unshare' to the 'hg' module...
r34879
Gregory Szorc
hg: don't reuse repo instance after unshare()...
r39642 # Removing share changes some fundamental properties of the repo instance.
# So we instantiate a new repo object and operate on it rather than
# try to keep the existing repo usable.
newrepo = repository(repo.baseui, repo.root, create=False)
Matt Harbison
share: move the implementation of 'unshare' to the 'hg' module...
r34879
Matt Harbison
subrepo: implement 'unshare' for Mercurial subrepos...
r34880 # TODO: figure out how to access subrepos that exist, but were previously
# removed from .hgsub
Gregory Szorc
hg: don't reuse repo instance after unshare()...
r39642 c = newrepo['.']
Matt Harbison
subrepo: implement 'unshare' for Mercurial subrepos...
r34880 subs = c.substate
for s in sorted(subs):
c.sub(s).unshare()
Gregory Szorc
hg: don't reuse repo instance after unshare()...
r39642 localrepo.poisonrepository(repo)
return newrepo
Gregory Szorc
localrepo: support writing shared file (API)...
r39885 def postshare(sourcerepo, destrepo, defaultpath=None):
Gregory Szorc
hg: establish function for performing post-share actions...
r27354 """Called after a new shared repo is created.
The new repo only has a requirements file and pointer to the source.
This function configures additional shared data.
Extensions can wrap this function and write additional entries to
destrepo/.hg/shared to indicate additional pieces of data to be shared.
"""
Gregory Szorc
hg: set default path correctly when doing a clone+share (issue5378)...
r30041 default = defaultpath or sourcerepo.ui.config('paths', 'default')
Gregory Szorc
hg: establish function for performing post-share actions...
r27354 if default:
Yuya Nishihara
share: convert EOL of hgrc before writing to bytes IO...
r35640 template = ('[paths]\n'
'default = %s\n')
destrepo.vfs.write('hgrc', util.tonativeeol(template % default))
Martin von Zweigbergk
narrow: detect if narrowspec was changed in a different share...
r41072 if repositorymod.NARROW_REQUIREMENT in sourcerepo.requirements:
with destrepo.wlock():
Martin von Zweigbergk
narrow: copy store narrowspec to working copy immediately...
r41265 narrowspec.copytoworkingcopy(destrepo)
Gregory Szorc
hg: establish function for performing post-share actions...
r27354
Gregory Szorc
hg: perform update after pulling during clone with share (issue5103)...
r28632 def _postshareupdate(repo, update, checkout=None):
"""Maybe perform a working directory update after a shared repo is created.
``update`` can be a boolean or a revision to update to.
"""
if not update:
return
repo.ui.status(_("updating working directory\n"))
if update is not True:
checkout = update
for test in (checkout, 'default', 'tip'):
if test is None:
continue
try:
uprev = repo.lookup(test)
break
except error.RepoLookupError:
continue
_update(repo, uprev)
Simon Heimberg
hg: extract copying the store out of clone
r15078 def copystore(ui, srcrepo, destpath):
'''copy files from store of srcrepo in destpath
returns destlock
'''
destlock = None
try:
hardlink = None
Martin von Zweigbergk
copystore: use progress helper...
r38399 topic = _('linking') if hardlink else _('copying')
av6
copystore: provide unit to ui.makeprogress()
r40671 with ui.makeprogress(topic, unit=_('files')) as progress:
Matt Harbison
hg: ensure the progress bar is completed when copying the store...
r39425 num = 0
srcpublishing = srcrepo.publishing()
srcvfs = vfsmod.vfs(srcrepo.sharedpath)
dstvfs = vfsmod.vfs(destpath)
for f in srcrepo.store.copylist():
if srcpublishing and f.endswith('phaseroots'):
continue
dstbase = os.path.dirname(f)
if dstbase and not dstvfs.exists(dstbase):
dstvfs.mkdir(dstbase)
if srcvfs.exists(f):
if f.endswith('data'):
# 'dstbase' may be empty (e.g. revlog format 0)
lockfile = os.path.join(dstbase, "lock")
# lock to avoid premature writing to the target
destlock = lock.lock(dstvfs, lockfile)
hardlink, n = util.copyfiles(srcvfs.join(f), dstvfs.join(f),
hardlink, progress)
num += n
if hardlink:
ui.debug("linked %d files\n" % num)
else:
ui.debug("copied %d files\n" % num)
Simon Heimberg
hg: extract copying the store out of clone
r15078 return destlock
Brodie Rao
check-code: ignore naked excepts with a "re-raise" comment...
r16705 except: # re-raises
Simon Heimberg
hg: extract copying the store out of clone
r15078 release(destlock)
raise
Gregory Szorc
hg: support for auto sharing stores when cloning...
r25761 def clonewithshare(ui, peeropts, sharepath, source, srcpeer, dest, pull=False,
rev=None, update=True, stream=False):
"""Perform a clone using a shared repo.
The store for the repository will be located at <sharepath>/.hg. The
specified revisions will be cloned or pulled from "source". A shared repo
will be created at "dest" and a working copy will be created if "update" is
True.
"""
revs = None
if rev:
if not srcpeer.capable('lookup'):
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_("src repository does not support "
Gregory Szorc
hg: support for auto sharing stores when cloning...
r25761 "revision lookup and so doesn't "
"support clone by revision"))
Gregory Szorc
hg: use command executor for wire protocol commands...
r37658
# TODO this is batchable.
remoterevs = []
for r in rev:
with srcpeer.commandexecutor() as e:
remoterevs.append(e.callcommand('lookup', {
'key': r,
}).result())
revs = remoterevs
Gregory Szorc
hg: support for auto sharing stores when cloning...
r25761
Gregory Szorc
hg: obtain lock when creating share from pooled repo (issue5104)...
r28289 # Obtain a lock before checking for or cloning the pooled repo otherwise
# 2 clients may race creating or populating it.
pooldir = os.path.dirname(sharepath)
# lock class requires the directory to exist.
try:
util.makedir(pooldir, False)
except OSError as e:
if e.errno != errno.EEXIST:
raise
Pierre-Yves David
vfs: use 'vfs' module directly in 'mercurial.hg'...
r31218 poolvfs = vfsmod.vfs(pooldir)
Gregory Szorc
hg: support for auto sharing stores when cloning...
r25761 basename = os.path.basename(sharepath)
Gregory Szorc
hg: obtain lock when creating share from pooled repo (issue5104)...
r28289 with lock.lock(poolvfs, '%s.lock' % basename):
if os.path.exists(sharepath):
ui.status(_('(sharing from existing pooled repository %s)\n') %
basename)
else:
ui.status(_('(sharing from new pooled repository %s)\n') % basename)
# Always use pull mode because hardlinks in share mode don't work
# well. Never update because working copies aren't necessary in
# share mode.
clone(ui, peeropts, source, dest=sharepath, pull=True,
Martin von Zweigbergk
clone: rename "rev" to "revs" since there can be many...
r37279 revs=rev, update=False, stream=stream)
Gregory Szorc
hg: support for auto sharing stores when cloning...
r25761
Gregory Szorc
hg: set default path correctly when doing a clone+share (issue5378)...
r30041 # Resolve the value to put in [paths] section for the source.
if islocal(source):
defaultpath = os.path.abspath(util.urllocalpath(source))
else:
defaultpath = source
Gregory Szorc
hg: support for auto sharing stores when cloning...
r25761 sharerepo = repository(ui, path=sharepath)
Martin von Zweigbergk
share: avoid a now-unnecessary reload of the repo...
r40610 destrepo = share(ui, sharerepo, dest=dest, update=False, bookmarks=False,
defaultpath=defaultpath)
Gregory Szorc
hg: support for auto sharing stores when cloning...
r25761
# We need to perform a pull against the dest repo to fetch bookmarks
# and other non-store data that isn't shared by default. In the case of
# non-existing shared repo, this means we pull from the remote twice. This
# is a bit weird. But at the time it was implemented, there wasn't an easy
# way to pull just non-changegroup data.
exchange.pull(destrepo, srcpeer, heads=revs)
Gregory Szorc
hg: perform update after pulling during clone with share (issue5103)...
r28632 _postshareupdate(destrepo, update)
Gregory Szorc
hg: support for auto sharing stores when cloning...
r25761 return srcpeer, peer(ui, peeropts, dest)
local-clone: extract the closure copying caches...
r32492 # Recomputing branch cache might be slow on big repos,
# so just copy it
def _copycache(srcrepo, dstcachedir, fname):
"""copy a cache from srcrepo to destcachedir (if it exists)"""
srcbranchcache = srcrepo.vfs.join('cache/%s' % fname)
dstbranchcache = os.path.join(dstcachedir, fname)
if os.path.exists(srcbranchcache):
if not os.path.exists(dstcachedir):
os.mkdir(dstcachedir)
util.copyfile(srcbranchcache, dstbranchcache)
Martin von Zweigbergk
clone: rename "rev" to "revs" since there can be many...
r37279 def clone(ui, peeropts, source, dest=None, pull=False, revs=None,
Gregory Szorc
hg: recognize include and exclude patterns when cloning...
r39586 update=True, stream=False, branch=None, shareopts=None,
Gregory Szorc
exchange: support declaring pull depth...
r40367 storeincludepats=None, storeexcludepats=None, depth=None):
Vadim Gelfer
clone: move code into hg module. make doc better....
r2597 """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
Sune Foldager
peer: introduce peer methods to prepare for peer classes...
r17191 function. Returns a pair of repository peers, the source and
Vadim Gelfer
clone: move code into hg module. make doc better....
r2597 newly created destination.
The location of the source is added to the new repository's
.hg/hgrc file, as the default to be used for future pulls and
pushes.
If an exception is raised, the partly cloned/updated destination
repository will be deleted.
Vadim Gelfer
clean up trailing white space.
r2600
Vadim Gelfer
hg.py: add islocal() and defaultdest() functions, refactor...
r2719 Arguments:
source: repository object or URL
Vadim Gelfer
clone: move code into hg module. make doc better....
r2597
dest: URL of destination repository to create (defaults to base
name of source repository)
Siddharth Agarwal
hg.clone: set 'stream' depending on whether --pull was requested or not...
r23545 pull: always pull from source repository, even in local case or if the
server prefers streaming
Vadim Gelfer
clone: move code into hg module. make doc better....
r2597
Vadim Gelfer
clone: disable stream support on server side by default....
r2621 stream: stream raw data uncompressed from repository (fast over
LAN, slow over WAN)
Vadim Gelfer
clone: do not make streaming default. add --stream option instead.
r2613
Martin von Zweigbergk
clone: rename "rev" to "revs" since there can be many...
r37279 revs: revision to clone up to (implies pull=True)
Vadim Gelfer
clone: move code into hg module. make doc better....
r2597
update: update working directory after clone completes, if
Bryan O'Sullivan
repo: add rjoin method
r6526 destination is local repository (True means update to default rev,
anything else is treated as a revision)
Sune Foldager
add -b/--branch option to clone, bundle, incoming, outgoing, pull, push
r10379
branch: branches to clone
Gregory Szorc
hg: support for auto sharing stores when cloning...
r25761
shareopts: dict of options to control auto sharing behavior. The "pool" key
activates auto sharing mode and defines the directory for stores. The
"mode" key determines how to construct the directory name of the shared
repository. "identity" means the name is derived from the node of the first
changeset in the repository. "remote" means the name is derived from the
remote's path/URL. Defaults to "identity."
Gregory Szorc
hg: recognize include and exclude patterns when cloning...
r39586
storeincludepats and storeexcludepats: sets of file patterns to include and
exclude in the repository copy, respectively. If not defined, all files
will be included (a "full" clone). Otherwise a "narrow" clone containing
only the requested files will be performed. If ``storeincludepats`` is not
defined but ``storeexcludepats`` is, ``storeincludepats`` is assumed to be
``path:.``. If both are empty sets, no files will be cloned.
Vadim Gelfer
clone: move code into hg module. make doc better....
r2597 """
Matt Mackall
Add support for url#id syntax...
r4478
Pulkit Goyal
py3: replace str with bytes in isinstance()...
r32970 if isinstance(source, bytes):
Alexis S. L. Carvalho
clone: make things work when source is a repo object
r6089 origsource = ui.expandpath(source)
Martin von Zweigbergk
parseurl: consistently call second output "branches"...
r37278 source, branches = parseurl(origsource, branch)
Sune Foldager
peer: introduce peer methods to prepare for peer classes...
r17191 srcpeer = peer(ui, peeropts, source)
Vadim Gelfer
hg.py: add islocal() and defaultdest() functions, refactor...
r2719 else:
Sune Foldager
peer: introduce peer methods to prepare for peer classes...
r17191 srcpeer = source.peer() # in case we were called with a localrepo
Martin von Zweigbergk
parseurl: consistently call second output "branches"...
r37278 branches = (None, branch or [])
Sune Foldager
peer: introduce peer methods to prepare for peer classes...
r17191 origsource = source = srcpeer.url()
Martin von Zweigbergk
clone: rename "rev" to "revs" since there can be many...
r37279 revs, checkout = addbranchrevs(srcpeer, srcpeer, branches, revs)
Vadim Gelfer
hg.py: add islocal() and defaultdest() functions, refactor...
r2719
Vadim Gelfer
clone: move code into hg module. make doc better....
r2597 if dest is None:
Vadim Gelfer
hg.py: add islocal() and defaultdest() functions, refactor...
r2719 dest = defaultdest(source)
Yuya Nishihara
clone: abort if default destination has no meaningful name (BC)...
r20800 if dest:
ui.status(_("destination directory: %s\n") % dest)
Matt Mackall
Merge with i18n-stable
r9344 else:
dest = ui.expandpath(dest)
Vadim Gelfer
hg.py: add islocal() and defaultdest() functions, refactor...
r2719
Mads Kiilerich
util: rename the util.localpath that uses url to urllocalpath (issue2875)...
r14825 dest = util.urllocalpath(dest)
source = util.urllocalpath(source)
Vadim Gelfer
clone: move code into hg module. make doc better....
r2597
FUJIWARA Katsunori
localrepo: use the path relative to "self.vfs" instead of "path" argument...
r17159 if not dest:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_("empty destination path is not valid"))
Chinmay Joshi
hg: use vfs functions in clone...
r21803
Pierre-Yves David
vfs: use 'vfs' module directly in 'mercurial.hg'...
r31218 destvfs = vfsmod.vfs(dest, expandpath=True)
Chinmay Joshi
hg: use vfs functions in clone...
r21803 if destvfs.lexists():
if not destvfs.isdir():
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_("destination '%s' already exists") % dest)
Chinmay Joshi
hg: update newly added listdir function of vfs in clone...
r21804 elif destvfs.listdir():
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_("destination '%s' is not empty") % dest)
Vadim Gelfer
clone: move code into hg module. make doc better....
r2597
Gregory Szorc
hg: recognize include and exclude patterns when cloning...
r39586 createopts = {}
narrow = False
if storeincludepats is not None:
narrowspec.validatepatterns(storeincludepats)
narrow = True
if storeexcludepats is not None:
narrowspec.validatepatterns(storeexcludepats)
narrow = True
if narrow:
# Include everything by default if only exclusion patterns defined.
if storeexcludepats and not storeincludepats:
storeincludepats = {'path:.'}
createopts['narrowfiles'] = True
Gregory Szorc
localrepo: support marking repos as having shallow file storage...
r40426 if depth:
createopts['shallowfilestore'] = True
Matt Harbison
lfs: autoload the extension when cloning from repo with lfs enabled...
r40360 if srcpeer.capable(b'lfs-serve'):
# Repository creation honors the config if it disabled the extension, so
# we can't just announce that lfs will be enabled. This check avoids
# saying that lfs will be enabled, and then saying it's an unknown
# feature. The lfs creation option is set in either case so that a
# requirement is added. If the extension is explicitly disabled but the
# requirement is set, the clone aborts early, before transferring any
# data.
createopts['lfs'] = True
if extensions.disabledext('lfs'):
ui.status(_('(remote is using large file support (lfs), but it is '
'explicitly disabled in the local configuration)\n'))
else:
ui.status(_('(remote is using large file support (lfs); lfs will '
'be enabled for this repository)\n'))
Gregory Szorc
hg: support for auto sharing stores when cloning...
r25761 shareopts = shareopts or {}
sharepool = shareopts.get('pool')
sharenamemode = shareopts.get('mode')
FUJIWARA Katsunori
hg: avoid auto sharing when the clone destination is remote...
r26026 if sharepool and islocal(dest):
Gregory Szorc
hg: support for auto sharing stores when cloning...
r25761 sharepath = None
if sharenamemode == 'identity':
# Resolve the name from the initial changeset in the remote
# repository. This returns nullid when the remote is empty. It
# raises RepoLookupError if revision 0 is filtered or otherwise
# not available. If we fail to resolve, sharing is not enabled.
try:
Gregory Szorc
hg: use command executor for wire protocol commands...
r37658 with srcpeer.commandexecutor() as e:
rootnode = e.callcommand('lookup', {
'key': '0',
}).result()
Gregory Szorc
hg: support for auto sharing stores when cloning...
r25761 if rootnode != node.nullid:
sharepath = os.path.join(sharepool, node.hex(rootnode))
else:
ui.status(_('(not using pooled storage: '
'remote appears to be empty)\n'))
except error.RepoLookupError:
ui.status(_('(not using pooled storage: '
'unable to resolve identity of remote)\n'))
elif sharenamemode == 'remote':
Augie Fackler
cleanup: replace uses of util.(md5|sha1|sha256|sha512) with hashlib.\1...
r29341 sharepath = os.path.join(
Pulkit Goyal
py3: use node.hex(h.digest()) instead of h.hexdigest()...
r35600 sharepool, node.hex(hashlib.sha1(source).digest()))
Gregory Szorc
hg: support for auto sharing stores when cloning...
r25761 else:
liscju
i18n: translate abort messages...
r29389 raise error.Abort(_('unknown share naming mode: %s') %
sharenamemode)
Gregory Szorc
hg: support for auto sharing stores when cloning...
r25761
Gregory Szorc
hg: recognize include and exclude patterns when cloning...
r39586 # TODO this is a somewhat arbitrary restriction.
if narrow:
ui.status(_('(pooled storage not supported for narrow clones)\n'))
sharepath = None
Gregory Szorc
hg: support for auto sharing stores when cloning...
r25761 if sharepath:
return clonewithshare(ui, peeropts, sharepath, source, srcpeer,
Martin von Zweigbergk
clone: rename "rev" to "revs" since there can be many...
r37279 dest, pull=pull, rev=revs, update=update,
Gregory Szorc
hg: support for auto sharing stores when cloning...
r25761 stream=stream)
Augie Fackler
hg: replace DirCleanup class with normal try/finally use
r18441 srclock = destlock = cleandir = None
Sune Foldager
peer: introduce peer methods to prepare for peer classes...
r17191 srcrepo = srcpeer.local()
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 try:
Brendan Cully
clone: make default path absolute for all local paths...
r14377 abspath = origsource
if islocal(origsource):
Mads Kiilerich
util: rename the util.localpath that uses url to urllocalpath (issue2875)...
r14825 abspath = os.path.abspath(util.urllocalpath(origsource))
Brendan Cully
clone: make default path absolute for all local paths...
r14377
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 if islocal(dest):
Augie Fackler
hg: replace DirCleanup class with normal try/finally use
r18441 cleandir = dest
Vadim Gelfer
clone: move code into hg module. make doc better....
r2597
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 copy = False
Sune Foldager
peer: remove cancopy from peer api; use directly on repo instead
r17194 if (srcrepo and srcrepo.cancopy() and islocal(dest)
Pierre-Yves David
clfilter: introduce a `hassecret` function...
r17671 and not phases.hassecret(srcrepo)):
Martin von Zweigbergk
clone: rename "rev" to "revs" since there can be many...
r37279 copy = not pull and not revs
Vadim Gelfer
clone: move code into hg module. make doc better....
r2597
Gregory Szorc
hg: recognize include and exclude patterns when cloning...
r39586 # TODO this is a somewhat arbitrary restriction.
if narrow:
copy = False
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 if copy:
try:
# we use a lock here because if we race with commit, we
# can end up with extra data in the cloned revlogs that's
# not pointed to by changesets, thus causing verify to
# fail
Martin Geisler
hg: remove underscores in clone function
r14463 srclock = srcrepo.lock(wait=False)
Matt Mackall
error: move lock errors...
r7640 except error.LockError:
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 copy = False
Vadim Gelfer
clone: move code into hg module. make doc better....
r2597
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 if copy:
Martin Geisler
hg: remove underscores in clone function
r14463 srcrepo.hook('preoutgoing', throw=True, source='clone')
Matt Mackall
backout dbdb777502dc (issue3077) (issue3071)...
r15381 hgdir = os.path.realpath(os.path.join(dest, ".hg"))
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 if not os.path.exists(dest):
Matt Harbison
clone: allow local cloning to create more than one level of directories...
r39221 util.makedirs(dest)
Steve Borho
on clone failure, only remove directories we created...
r7935 else:
# only clean up directories we create ourselves
Augie Fackler
hg: replace DirCleanup class with normal try/finally use
r18441 cleandir = hgdir
Matt Mackall
clone: fix race with same target directory (issue716)...
r5569 try:
Martin Geisler
hg: remove underscores in clone function
r14463 destpath = hgdir
util.makedir(destpath, notindexed=True)
Gregory Szorc
global: mass rewrite to use modern exception syntax...
r25660 except OSError as inst:
Matt Mackall
clone: fix race with same target directory (issue716)...
r5569 if inst.errno == errno.EEXIST:
Augie Fackler
hg: replace DirCleanup class with normal try/finally use
r18441 cleandir = None
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_("destination '%s' already exists")
Matt Mackall
clone: fix race with same target directory (issue716)...
r5569 % dest)
raise
Vadim Gelfer
clone: move code into hg module. make doc better....
r2597
Simon Heimberg
hg: extract copying the store out of clone
r15078 destlock = copystore(ui, srcrepo, destpath)
Pierre-Yves David
clone: copy `.hg/bookmarks` during copy clone...
r22646 # copy bookmarks over
Pierre-Yves David
hg-mod: directly use repo.vfs.join...
r31322 srcbookmarks = srcrepo.vfs.join('bookmarks')
Pierre-Yves David
clone: copy `.hg/bookmarks` during copy clone...
r22646 dstbookmarks = os.path.join(destpath, 'bookmarks')
if os.path.exists(srcbookmarks):
util.copyfile(srcbookmarks, dstbookmarks)
Vadim Gelfer
clone: move code into hg module. make doc better....
r2597
Tomasz Kleczek
branchcache: fetch source branchcache during clone (issue3378)...
r17740 dstcachedir = os.path.join(destpath, 'cache')
Boris Feld
caches: make 'cachetocopy' available in scmutil...
r35784 for cache in cacheutil.cachetocopy(srcrepo):
local-clone: extract the listing of caches to copy...
r32493 _copycache(srcrepo, dstcachedir, cache)
Tomasz Kleczek
branchcache: fetch source branchcache during clone (issue3378)...
r17740
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 # we need to re-init the repo after manually copying the data
# into it
Simon Heimberg
peer: subrepo isolation, pass repo instead of repo.ui to hg.peer...
r17874 destpeer = peer(srcrepo, peeropts, dest)
Martin Geisler
hg: remove underscores in clone function
r14463 srcrepo.hook('outgoing', source='clone',
Martin Geisler
clone, patch, convert: use hex(nullid) instead of '0'*40
r12144 node=node.hex(node.nullid))
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 else:
Matt Mackall
clone: fix race with same target directory (issue716)...
r5569 try:
Gregory Szorc
hg: recognize include and exclude patterns when cloning...
r39586 # only pass ui when no srcrepo
destpeer = peer(srcrepo or ui, peeropts, dest, create=True,
createopts=createopts)
Gregory Szorc
global: mass rewrite to use modern exception syntax...
r25660 except OSError as inst:
Matt Mackall
clone: fix race with same target directory (issue716)...
r5569 if inst.errno == errno.EEXIST:
Augie Fackler
hg: replace DirCleanup class with normal try/finally use
r18441 cleandir = None
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_("destination '%s' already exists")
Matt Mackall
clone: fix race with same target directory (issue716)...
r5569 % dest)
raise
Vadim Gelfer
clone: move code into hg module. make doc better....
r2597
Martin von Zweigbergk
clone: rename "rev" to "revs" since there can be many...
r37279 if revs:
Sune Foldager
peer: introduce peer methods to prepare for peer classes...
r17191 if not srcpeer.capable('lookup'):
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_("src repository does not support "
Martin Geisler
hg: better wrapping of string literal
r9171 "revision lookup and so doesn't "
"support clone by revision"))
Gregory Szorc
hg: use command executor for wire protocol commands...
r37658
# TODO this is batchable.
remoterevs = []
for rev in revs:
with srcpeer.commandexecutor() as e:
remoterevs.append(e.callcommand('lookup', {
'key': rev,
}).result())
revs = remoterevs
Brett Carter
clone: try updating to the actual changeset specified in options...
r8417 checkout = revs[0]
Martin von Zweigbergk
clone: rename "rev" to "revs" since there can be many...
r37279 else:
revs = None
Augie Fackler
localrepo: remove clone method by hoisting into hg.py...
r27165 local = destpeer.local()
if local:
Gregory Szorc
hg: write narrow patterns after repo creation...
r39591 if narrow:
Martin von Zweigbergk
narrow: detect if narrowspec was changed in a different share...
r41072 with local.wlock(), local.lock():
Gregory Szorc
hg: write narrow patterns after repo creation...
r39591 local.setnarrowpats(storeincludepats, storeexcludepats)
Martin von Zweigbergk
narrow: move copytonarrowspec() out of setnarrowpats()...
r41272 narrowspec.copytoworkingcopy(local)
Gregory Szorc
hg: write narrow patterns after repo creation...
r39591
Boris Feld
clonebundle: make it possible to retrieve the initial bundle through largefile...
r35581 u = util.url(abspath)
defaulturl = bytes(u)
local.ui.setconfig('paths', 'default', defaulturl, 'clone')
Siddharth Agarwal
hg.clone: set 'stream' depending on whether --pull was requested or not...
r23545 if not stream:
if pull:
stream = False
else:
stream = None
Augie Fackler
localrepo: remove clone method by hoisting into hg.py...
r27165 # internal config: ui.quietbookmarkmove
Jun Wu
clone: get rid of ui.backupconfig
r31456 overrides = {('ui', 'quietbookmarkmove'): True}
with local.ui.configoverride(overrides, 'clone'):
Augie Fackler
localrepo: remove clone method by hoisting into hg.py...
r27165 exchange.pull(local, srcpeer, revs,
Gregory Szorc
exchange: support defining narrow file patterns for pull...
r39589 streamclonerequested=stream,
includepats=storeincludepats,
Gregory Szorc
exchange: support declaring pull depth...
r40367 excludepats=storeexcludepats,
depth=depth)
Sune Foldager
peer: introduce peer methods to prepare for peer classes...
r17191 elif srcrepo:
Gregory Szorc
hg: recognize include and exclude patterns when cloning...
r39586 # TODO lift restriction once exchange.push() accepts narrow
# push.
if narrow:
raise error.Abort(_('narrow clone not available for '
'remote destinations'))
Pierre-Yves David
clone: explicitly push bookmarks when cloning from local to remote...
r22647 exchange.push(srcrepo, destpeer, revs=revs,
bookmarks=srcrepo._bookmarks.keys())
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 else:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_("clone from remote to remote not supported")
)
Vadim Gelfer
clone: move code into hg module. make doc better....
r2597
Augie Fackler
hg: replace DirCleanup class with normal try/finally use
r18441 cleandir = None
Vadim Gelfer
clone: move code into hg module. make doc better....
r2597
Sune Foldager
peer: introduce peer methods to prepare for peer classes...
r17191 destrepo = destpeer.local()
if destrepo:
Jordi Gutiérrez Hermoso
config: use the same hgrc for a cloned repo as for an uninitted repo...
r22837 template = uimod.samplehgrcs['cloned']
Augie Fackler
clone: don't save user's password in .hg/hgrc (Issue3122)
r15552 u = util.url(abspath)
u.passwd = None
Yuya Nishihara
py3: use bytes IO to write sample hgrc...
r33650 defaulturl = bytes(u)
Yuya Nishihara
clone: use utility function to write hgrc
r35638 destrepo.vfs.write('hgrc', util.tonativeeol(template % defaulturl))
Mads Kiilerich
config: set a 'source' in most cases where config don't come from file but code...
r20790 destrepo.ui.setconfig('paths', 'default', defaulturl, 'clone')
Matt Mackall
subrepo: add update/merge logic
r8814
Pulkit Goyal
clone: add support for storing remotenames while cloning...
r35332 if ui.configbool('experimental', 'remotenames'):
Pulkit Goyal
remotenames: rename related file and storage dir to logexchange...
r35348 logexchange.pullremotenames(destrepo, srcpeer)
Pulkit Goyal
clone: add support for storing remotenames while cloning...
r35332
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 if update:
Bryan O'Sullivan
repo: add rjoin method
r6526 if update is not True:
Gregory Szorc
hg: use command executor for wire protocol commands...
r37658 with srcpeer.commandexecutor() as e:
checkout = e.callcommand('lookup', {
'key': update,
}).result()
Thomas Arendsen Hein
clone: make sure to use "@" as bookmark and "default" as branch (issue3677)...
r17867 uprev = None
Adrian Buehlmann
clone: show status "updating to bookmark @"...
r17882 status = None
Thomas Arendsen Hein
clone: make sure to use "@" as bookmark and "default" as branch (issue3677)...
r17867 if checkout is not None:
Boris Feld
clone: process 'lookup' return as an arbitrary symbol...
r38776 # Some extensions (at least hg-git and hg-subversion) have
# a peer.lookup() implementation that returns a name instead
# of a nodeid. We work around it here until we've figured
# out a better solution.
if len(checkout) == 20 and checkout in destrepo:
Martin von Zweigbergk
clone: avoid using repo.lookup() with binary nodeid...
r37498 uprev = checkout
Boris Feld
clone: process 'lookup' return as an arbitrary symbol...
r38776 elif scmutil.isrevsymbol(destrepo, checkout):
uprev = scmutil.revsymbol(destrepo, checkout).node()
Martin von Zweigbergk
clone: avoid using repo.lookup() with binary nodeid...
r37498 else:
Sean Farley
clone: check update rev for being True...
r26354 if update is not True:
try:
uprev = destrepo.lookup(update)
except error.RepoLookupError:
pass
Thomas Arendsen Hein
clone: make sure to use "@" as bookmark and "default" as branch (issue3677)...
r17867 if uprev is None:
try:
uprev = destrepo._bookmarks['@']
Thomas Arendsen Hein
clone: activate @ bookmark if updating to it...
r17870 update = '@'
Adrian Buehlmann
clone: show status "updating to bookmark @"...
r17882 bn = destrepo[uprev].branch()
if bn == 'default':
status = _("updating to bookmark @\n")
else:
FUJIWARA Katsunori
i18n: fix "% inside _()" problems...
r20868 status = (_("updating to bookmark @ on branch %s\n")
Sean Farley
clone: fix over-indented continuation line
r26353 % bn)
Thomas Arendsen Hein
clone: make sure to use "@" as bookmark and "default" as branch (issue3677)...
r17867 except KeyError:
try:
uprev = destrepo.branchtip('default')
except error.RepoLookupError:
uprev = destrepo.lookup('tip')
Adrian Buehlmann
clone: show status "updating to bookmark @"...
r17882 if not status:
bn = destrepo[uprev].branch()
status = _("updating to branch %s\n") % bn
destrepo.ui.status(status)
Martin Geisler
hg: remove underscores in clone function
r14463 _update(destrepo, uprev)
Thomas Arendsen Hein
clone: activate bookmark specified with --updaterev
r17703 if update in destrepo._bookmarks:
Ryan McElroy
bookmarks: rename setcurrent to activate (API)...
r24945 bookmarks.activate(destrepo, update)
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 finally:
Matt Mackall
bookmarks: backout locking change in 12dea4d998ec...
r15908 release(srclock, destlock)
Augie Fackler
hg: replace DirCleanup class with normal try/finally use
r18441 if cleandir is not None:
shutil.rmtree(cleandir, True)
Sune Foldager
peer: introduce peer methods to prepare for peer classes...
r17191 if srcpeer is not None:
srcpeer.close()
simon@laptop-tosh
hg: move return statement after finally block...
r19313 return srcpeer, destpeer
Matt Mackall
Move merge code to its own module...
r2775
timeless
hg: add quietempty flag to _showstats...
r27402 def _showstats(repo, stats, quietempty=False):
Gregory Szorc
merge: deprecate accessing update results by index...
r37143 if quietempty and stats.isempty():
timeless
hg: add quietempty flag to _showstats...
r27402 return
Martin Geisler
hg: avoid combining translated strings...
r9454 repo.ui.status(_("%d files updated, %d files merged, "
Gregory Szorc
merge: return an attrs class from update() and applyupdates()...
r37125 "%d files removed, %d files unresolved\n") % (
stats.updatedcount, stats.mergedcount,
stats.removedcount, stats.unresolvedcount))
Matt Mackall
merge: pull user messages out to hg.py...
r3316
Martin von Zweigbergk
update: accept --merge to allow merging across topo branches (issue5125)
r31166 def updaterepo(repo, node, overwrite, updatecheck=None):
Simon Heimberg
subrepo: only do clean update when overwrite is set (issue3276)...
r17895 """Update the working directory to node.
When overwrite is set, changes are clobbered, merged else
returns stats (see pydoc mercurial.merge.applyupdates)"""
Martin von Zweigbergk
update: clarify update() call sites by specifying argument names...
r40402 return mergemod.update(repo, node, branchmerge=False, force=overwrite,
Martin von Zweigbergk
update: accept --merge to allow merging across topo branches (issue5125)
r31166 labels=['working copy', 'destination'],
updatecheck=updatecheck)
Simon Heimberg
subrepo: only do clean update when overwrite is set (issue3276)...
r17895
Martin von Zweigbergk
update: accept --merge to allow merging across topo branches (issue5125)
r31166 def update(repo, node, quietempty=False, updatecheck=None):
"""update the working directory to node"""
stats = updaterepo(repo, node, False, updatecheck=updatecheck)
timeless
update: add quietempty flag to _showstats...
r27404 _showstats(repo, stats, quietempty)
Gregory Szorc
merge: deprecate accessing update results by index...
r37143 if stats.unresolvedcount:
Matt Mackall
resolve: new command...
r6518 repo.ui.status(_("use 'hg resolve' to retry unresolved file merges\n"))
Gregory Szorc
merge: deprecate accessing update results by index...
r37143 return stats.unresolvedcount > 0
Matt Mackall
Move merge code to its own module...
r2775
Benoit Boissinot
add a comment about the need of hg._update()
r7546 # naming conflict in clone()
_update = update
timeless
histedit: omit useless message from abort...
r27403 def clean(repo, node, show_stats=True, quietempty=False):
Matt Mackall
Introduce update helper functions: update, merge, clean, and revert
r2808 """forcibly switch the working directory to node, clobbering changes"""
Simon Heimberg
subrepo: only do clean update when overwrite is set (issue3276)...
r17895 stats = updaterepo(repo, node, True)
Mads Kiilerich
vfs: use repo.vfs.unlinkpath
r31311 repo.vfs.unlinkpath('graftstate', ignoremissing=True)
Matt Mackall
many, many trivial check-code fixups
r10282 if show_stats:
timeless
histedit: omit useless message from abort...
r27403 _showstats(repo, stats, quietempty)
Gregory Szorc
merge: deprecate accessing update results by index...
r37143 return stats.unresolvedcount > 0
Matt Mackall
Move merge code to its own module...
r2775
FUJIWARA Katsunori
commands: centralize code to update with extra care for non-file components...
r28501 # naming conflict in updatetotally()
_clean = clean
Martin von Zweigbergk
update: accept --merge to allow merging across topo branches (issue5125)
r31166 def updatetotally(ui, repo, checkout, brev, clean=False, updatecheck=None):
FUJIWARA Katsunori
commands: centralize code to update with extra care for non-file components...
r28501 """Update the working directory with extra care for non-file components
This takes care of non-file components below:
:bookmark: might be advanced or (in)activated
This takes arguments below:
:checkout: to which revision the working directory is updated
:brev: a name, which might be a bookmark to be activated after updating
:clean: whether changes in the working directory can be discarded
Martin von Zweigbergk
update: accept --merge to allow merging across topo branches (issue5125)
r31166 :updatecheck: how to deal with a dirty working directory
Valid values for updatecheck are (None => linear):
* abort: abort if the working directory is dirty
* none: don't check (merge working directory changes into destination)
* linear: check that update is linear before merging working directory
changes into destination
Martin von Zweigbergk
update: allow setting default update check to "noconflict"...
r31168 * noconflict: check that the update does not result in file merges
FUJIWARA Katsunori
commands: centralize code to update with extra care for non-file components...
r28501
This returns whether conflict is detected at updating or not.
"""
Martin von Zweigbergk
update: accept --merge to allow merging across topo branches (issue5125)
r31166 if updatecheck is None:
Augie Fackler
config: graduate experimental.updatecheck to commands.update.check...
r34706 updatecheck = ui.config('commands', 'update.check')
Martin von Zweigbergk
update: allow setting default update check to "noconflict"...
r31168 if updatecheck not in ('abort', 'none', 'linear', 'noconflict'):
Martin von Zweigbergk
update: add experimental config for default way of handling dirty wdir...
r31167 # If not configured, or invalid value configured
updatecheck = 'linear'
FUJIWARA Katsunori
hg: acquire wlock while updating the working directory via updatetotally...
r28503 with repo.wlock():
FUJIWARA Katsunori
commands: centralize code to update with extra care for non-file components...
r28501 movemarkfrom = None
warndest = False
if checkout is None:
Martin von Zweigbergk
destutil: drop now-unused "check" parameter from destupdate()
r30962 updata = destutil.destupdate(repo, clean=clean)
FUJIWARA Katsunori
commands: centralize code to update with extra care for non-file components...
r28501 checkout, movemarkfrom, brev = updata
warndest = True
if clean:
ret = _clean(repo, checkout)
else:
Martin von Zweigbergk
update: accept --merge to allow merging across topo branches (issue5125)
r31166 if updatecheck == 'abort':
Martin von Zweigbergk
update: move check for dirty wdir into hg.updatetotally()...
r30963 cmdutil.bailifchanged(repo, merge=False)
Martin von Zweigbergk
update: accept --merge to allow merging across topo branches (issue5125)
r31166 updatecheck = 'none'
ret = _update(repo, checkout, updatecheck=updatecheck)
FUJIWARA Katsunori
commands: centralize code to update with extra care for non-file components...
r28501
if not ret and movemarkfrom:
if movemarkfrom == repo['.'].node():
pass # no-op update
elif bookmarks.update(repo, [movemarkfrom], repo['.'].node()):
Pierre-Yves David
update: label bookmark name in message...
r29902 b = ui.label(repo._activebookmark, 'bookmarks.active')
ui.status(_("updating bookmark %s\n") % b)
FUJIWARA Katsunori
commands: centralize code to update with extra care for non-file components...
r28501 else:
# this can happen with a non-linear update
Pierre-Yves David
update: label bookmark name in message...
r29902 b = ui.label(repo._activebookmark, 'bookmarks')
ui.status(_("(leaving bookmark %s)\n") % b)
FUJIWARA Katsunori
commands: centralize code to update with extra care for non-file components...
r28501 bookmarks.deactivate(repo)
elif brev in repo._bookmarks:
if brev != repo._activebookmark:
Pierre-Yves David
update: label bookmark name in message...
r29902 b = ui.label(brev, 'bookmarks.active')
ui.status(_("(activating bookmark %s)\n") % b)
FUJIWARA Katsunori
commands: centralize code to update with extra care for non-file components...
r28501 bookmarks.activate(repo, brev)
elif brev:
if repo._activebookmark:
Pierre-Yves David
update: label bookmark name in message...
r29902 b = ui.label(repo._activebookmark, 'bookmarks')
ui.status(_("(leaving bookmark %s)\n") % b)
FUJIWARA Katsunori
commands: centralize code to update with extra care for non-file components...
r28501 bookmarks.deactivate(repo)
if warndest:
destutil.statusotherdests(ui, repo)
return ret
Pulkit Goyal
merge: add `--abort` flag which can abort the merge...
r35722 def merge(repo, node, force=None, remind=True, mergeforce=False, labels=None,
abort=False):
Greg Ward
merge: document some internal return values.
r13162 """Branch merge with node, resolving changes. Return true if any
unresolved conflicts."""
Pulkit Goyal
merge: add `--abort` flag which can abort the merge...
r35722 if not abort:
Martin von Zweigbergk
update: clarify update() call sites by specifying argument names...
r40402 stats = mergemod.update(repo, node, branchmerge=True, force=force,
mergeforce=mergeforce, labels=labels)
Pulkit Goyal
merge: add `--abort` flag which can abort the merge...
r35722 else:
ms = mergemod.mergestate.read(repo)
if ms.active():
# there were conflicts
Pulkit Goyal
merge: use public interface ms.localctx instead of ms._local
r35731 node = ms.localctx.hex()
Pulkit Goyal
merge: add `--abort` flag which can abort the merge...
r35722 else:
# there were no conficts, mergestate was not stored
node = repo['.'].hex()
repo.ui.status(_("aborting the merge, updating back to"
" %s\n") % node[:12])
stats = mergemod.update(repo, node, branchmerge=False, force=True,
labels=labels)
Matt Mackall
merge: pull user messages out to hg.py...
r3316 _showstats(repo, stats)
Gregory Szorc
merge: deprecate accessing update results by index...
r37143 if stats.unresolvedcount:
Augie Fackler
merge: better error messages to lead users to hg update --clean to abandon merges....
r7821 repo.ui.status(_("use 'hg resolve' to retry unresolved file merges "
Pulkit Goyal
merge: add `--abort` flag which can abort the merge...
r35722 "or 'hg merge --abort' to abandon\n"))
elif remind and not abort:
Matt Mackall
merge: pull user messages out to hg.py...
r3316 repo.ui.status(_("(branch merge, don't forget to commit)\n"))
Gregory Szorc
merge: deprecate accessing update results by index...
r37143 return stats.unresolvedcount > 0
Matt Mackall
Introduce update helper functions: update, merge, clean, and revert
r2808
Nicolas Dumazet
incoming: unify code for incoming and graphlog.incoming
r12730 def _incoming(displaychlist, subreporecurse, ui, repo, source,
opts, buffered=False):
"""
Helper for incoming / gincoming.
displaychlist gets called with
(remoterepo, incomingchangesetlist, displayer) parameters,
and is supposed to contain only code that can't be unified.
"""
source, branches = parseurl(ui.expandpath(source), opts.get('branch'))
Matt Mackall
hg: change various repository() users to use peer() where appropriate...
r14556 other = peer(repo, opts, source)
Brodie Rao
url: move URL parsing functions into util to improve startup time...
r14076 ui.status(_('comparing with %s\n') % util.hidepassword(source))
Nicolas Dumazet
incoming: unify code for incoming and graphlog.incoming
r12730 revs, checkout = addbranchrevs(repo, other, branches, opts.get('rev'))
if revs:
revs = [other.lookup(rev) for rev in revs]
Peter Arrenbrecht
bundlerepo: fix and improve getremotechanges...
r14161 other, chlist, cleanupfn = bundlerepo.getremotechanges(ui, repo, other,
revs, opts["bundle"], opts["force"])
try:
if not chlist:
ui.status(_("no changes found\n"))
return subreporecurse()
Augie Fackler
incoming: delay pager activation until right before printing changes...
r31057 ui.pager('incoming')
Yuya Nishihara
logcmdutil: hold makefilematcher/makehunksfilter() by changesetpriner (API)...
r36020 displayer = logcmdutil.changesetdisplayer(ui, other, opts,
buffered=buffered)
Nicolas Dumazet
incoming: unify code for incoming and graphlog.incoming
r12730 displaychlist(other, chlist, displayer)
displayer.close()
finally:
Peter Arrenbrecht
bundlerepo: fix and improve getremotechanges...
r14161 cleanupfn()
Nicolas Dumazet
incoming: unify code for incoming and graphlog.incoming
r12730 subreporecurse()
return 0 # exit code is zero since we found incoming changes
Martin Geisler
incoming: move code from commands to cmdutil...
r12273 def incoming(ui, repo, source, opts):
Nicolas Dumazet
incoming: unify code for incoming and graphlog.incoming
r12730 def subreporecurse():
Erik Zielke
incoming/outgoing: Fix recursion on sub repositories...
r12400 ret = 1
if opts.get('subrepos'):
ctx = repo[None]
for subpath in sorted(ctx.substate):
sub = ctx.sub(subpath)
ret = min(ret, sub.incoming(ui, source, opts))
return ret
Nicolas Dumazet
incoming: unify code for incoming and graphlog.incoming
r12730 def display(other, chlist, displayer):
Yuya Nishihara
cmdutil: drop aliases for logcmdutil functions (API)...
r35906 limit = logcmdutil.getlimit(opts)
Martin Geisler
incoming: move code from commands to cmdutil...
r12273 if opts.get('newest_first'):
Nicolas Dumazet
incoming: rename variable...
r12729 chlist.reverse()
Martin Geisler
incoming: move code from commands to cmdutil...
r12273 count = 0
Nicolas Dumazet
incoming: rename variable...
r12729 for n in chlist:
Martin Geisler
incoming: move code from commands to cmdutil...
r12273 if limit is not None and count >= limit:
break
parents = [p for p in other.changelog.parents(n) if p != nullid]
if opts.get('no_merges') and len(parents) == 2:
continue
count += 1
displayer.show(other[n])
Nicolas Dumazet
incoming: unify code for incoming and graphlog.incoming
r12730 return _incoming(display, subreporecurse, ui, repo, source, opts)
Martin Geisler
incoming: move code from commands to cmdutil...
r12273
Nicolas Dumazet
outgoing: unify common graphlog.outgoing and hg.outgoing code
r12735 def _outgoing(ui, repo, dest, opts):
Hollis Blanchard
outgoing: respect ":pushurl" paths (issue5365)...
r35454 path = ui.paths.getpath(dest, default=('default-push', 'default'))
if not path:
raise error.Abort(_('default repository not configured!'),
hint=_("see 'hg help config.paths'"))
dest = path.pushloc or path.loc
branches = path.branch, opts.get('branch') or []
Brodie Rao
url: move URL parsing functions into util to improve startup time...
r14076 ui.status(_('comparing with %s\n') % util.hidepassword(dest))
Nicolas Dumazet
outgoing: unify common graphlog.outgoing and hg.outgoing code
r12735 revs, checkout = addbranchrevs(repo, repo, branches, opts.get('rev'))
if revs:
Martin von Zweigbergk
outgoing: avoid repo.lookup() for converting revnum to nodeid...
r37329 revs = [repo[rev].node() for rev in scmutil.revrange(repo, revs)]
Nicolas Dumazet
outgoing: unify common graphlog.outgoing and hg.outgoing code
r12735
Matt Mackall
hg: change various repository() users to use peer() where appropriate...
r14556 other = peer(repo, opts, dest)
Martin von Zweigbergk
outgoing: run on filtered repo...
r32172 outgoing = discovery.findcommonoutgoing(repo, other, revs,
Pierre-Yves David
discovery: introduce outgoing object for result of findcommonoutgoing...
r15837 force=opts.get('force'))
o = outgoing.missing
Nicolas Dumazet
outgoing: unify common graphlog.outgoing and hg.outgoing code
r12735 if not o:
Patrick Mezard
discovery: add extinct changesets to outgoing.excluded...
r17248 scmutil.nochangesfound(repo.ui, repo, outgoing.excluded)
FUJIWARA Katsunori
hg: make "_outgoing()" return peer object for remote repository...
r21050 return o, other
Nicolas Dumazet
outgoing: unify common graphlog.outgoing and hg.outgoing code
r12735
Martin Geisler
outgoing: move code from commands to cmdutil...
r12271 def outgoing(ui, repo, dest, opts):
Erik Zielke
incoming/outgoing: Fix recursion on sub repositories...
r12400 def recurse():
ret = 1
if opts.get('subrepos'):
ctx = repo[None]
for subpath in sorted(ctx.substate):
sub = ctx.sub(subpath)
ret = min(ret, sub.outgoing(ui, dest, opts))
return ret
Yuya Nishihara
cmdutil: drop aliases for logcmdutil functions (API)...
r35906 limit = logcmdutil.getlimit(opts)
FUJIWARA Katsunori
hg: make "_outgoing()" return peer object for remote repository...
r21050 o, other = _outgoing(ui, repo, dest, opts)
FUJIWARA Katsunori
hg: make "_outgoing()" return empty list instead of "None"...
r21049 if not o:
FUJIWARA Katsunori
outgoing: introduce "outgoinghooks" to avoid redundant outgoing check...
r21051 cmdutil.outgoinghooks(ui, repo, other, opts, o)
Erik Zielke
incoming/outgoing: Fix recursion on sub repositories...
r12400 return recurse()
Martin Geisler
outgoing: move code from commands to cmdutil...
r12271 if opts.get('newest_first'):
o.reverse()
Augie Fackler
outgoing: avoid running pager until we're actually showing changes...
r31058 ui.pager('outgoing')
Yuya Nishihara
cmdutil: drop aliases for logcmdutil functions (API)...
r35906 displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
Martin Geisler
outgoing: move code from commands to cmdutil...
r12271 count = 0
for n in o:
if limit is not None and count >= limit:
break
parents = [p for p in repo.changelog.parents(n) if p != nullid]
if opts.get('no_merges') and len(parents) == 2:
continue
count += 1
displayer.show(repo[n])
displayer.close()
FUJIWARA Katsunori
outgoing: introduce "outgoinghooks" to avoid redundant outgoing check...
r21051 cmdutil.outgoinghooks(ui, repo, other, opts, o)
Erik Zielke
incoming/outgoing: Fix recursion on sub repositories...
r12400 recurse()
return 0 # exit code is zero since we found outgoing changes
Martin Geisler
outgoing: move code from commands to cmdutil...
r12271
Matt Mackall
Move repo.verify
r2778 def verify(repo):
"""verify the consistency of a repository"""
Matt Harbison
verify: check the subrepository references in .hgsubstate...
r25591 ret = verifymod.verify(repo)
# Broken subrepo references in hidden csets don't seem worth worrying about,
# since they can't be pushed/pulled, and --hidden can be used if they are a
# concern.
# pathto() is needed for -R case
revs = repo.revs("filelog(%s)",
util.pathto(repo.root, repo.getcwd(), '.hgsubstate'))
if revs:
repo.ui.status(_('checking subrepo links\n'))
for rev in revs:
ctx = repo[rev]
try:
for subpath in ctx.substate:
Matt Harbison
verify: don't init subrepo when missing one is referenced (issue5128) (API)...
r29021 try:
ret = (ctx.sub(subpath, allowcreate=False).verify()
or ret)
except error.RepoError as e:
Pulkit Goyal
py3: use '%d' for integers instead of '%s'...
r37597 repo.ui.warn(('%d: %s\n') % (rev, e))
Matt Harbison
verify: check the subrepository references in .hgsubstate...
r25591 except Exception:
repo.ui.warn(_('.hgsubstate is corrupt in revision %s\n') %
node.short(ctx.node()))
return ret
Matt Mackall
remoteui: move from cmdutil to hg
r11273
def remoteui(src, opts):
'build a remote ui from ui or repo and opts'
Augie Fackler
hg: use safehasattr instead of hasattr
r14952 if util.safehasattr(src, 'baseui'): # looks like a repository
Matt Mackall
remoteui: move from cmdutil to hg
r11273 dst = src.baseui.copy() # drop repo-specific config
src = src.ui # copy target options from repo
else: # assume it's a global ui object
dst = src.copy() # keep all global options
# copy ssh-specific options
for o in 'ssh', 'remotecmd':
v = opts.get(o) or src.config('ui', o)
if v:
Mads Kiilerich
config: set a 'source' in most cases where config don't come from file but code...
r20790 dst.setconfig("ui", o, v, 'copied')
Matt Mackall
remoteui: move from cmdutil to hg
r11273
# copy bundle-specific options
r = src.config('bundle', 'mainreporoot')
if r:
Mads Kiilerich
config: set a 'source' in most cases where config don't come from file but code...
r20790 dst.setconfig('bundle', 'mainreporoot', r, 'copied')
Matt Mackall
remoteui: move from cmdutil to hg
r11273
Mads Kiilerich
https: use web.cacerts configuration from local repo to validate remote repo
r13192 # copy selected local settings to the remote ui
Gregory Szorc
hg: copy [hostsecurity] options to remote ui instances (issue5305)...
r29616 for sect in ('auth', 'hostfingerprints', 'hostsecurity', 'http_proxy'):
Matt Mackall
remoteui: move from cmdutil to hg
r11273 for key, val in src.configitems(sect):
Mads Kiilerich
config: set a 'source' in most cases where config don't come from file but code...
r20790 dst.setconfig(sect, key, val, 'copied')
Mads Kiilerich
https: use web.cacerts configuration from local repo to validate remote repo
r13192 v = src.config('web', 'cacerts')
Yuya Nishihara
ssl: remove special case of web.cacerts=! from remoteui()...
r29594 if v:
Mads Kiilerich
config: set a 'source' in most cases where config don't come from file but code...
r20790 dst.setconfig('web', 'cacerts', util.expandpath(v), 'copied')
Matt Mackall
remoteui: move from cmdutil to hg
r11273
return dst
Gregory Szorc
hg: establish a cache for localrepository instances...
r26219
# Files of interest
# Used to check if the repository has changed looking at mtime and size of
Mads Kiilerich
spelling: trivial spell checking
r26781 # these files.
Gregory Szorc
hg: establish a cache for localrepository instances...
r26219 foi = [('spath', '00changelog.i'),
('spath', 'phaseroots'), # ! phase can change content at the same size
('spath', 'obsstore'),
('path', 'bookmarks'), # ! bookmark can change content at the same size
]
class cachedlocalrepo(object):
"""Holds a localrepository that can be cached and reused."""
def __init__(self, repo):
"""Create a new cached repo from an existing repo.
We assume the passed in repo was recently created. If the
repo has changed between when it was created and when it was
turned into a cache, it may not refresh properly.
"""
assert isinstance(repo, localrepo.localrepository)
self._repo = repo
self._state, self.mtime = self._repostate()
FUJIWARA Katsunori
hg: make cachedlocalrepo cache appropriate repoview object...
r28119 self._filtername = repo.filtername
Gregory Szorc
hg: establish a cache for localrepository instances...
r26219
def fetch(self):
"""Refresh (if necessary) and return a repository.
If the cached instance is out of date, it will be recreated
automatically and returned.
Returns a tuple of the repo and a boolean indicating whether a new
repo instance was created.
"""
# We compare the mtimes and sizes of some well-known files to
# determine if the repo changed. This is not precise, as mtimes
# are susceptible to clock skew and imprecise filesystems and
# file content can change while maintaining the same size.
state, mtime = self._repostate()
if state == self._state:
return self._repo, False
FUJIWARA Katsunori
hg: make cachedlocalrepo cache appropriate repoview object...
r28119 repo = repository(self._repo.baseui, self._repo.url())
if self._filtername:
self._repo = repo.filtered(self._filtername)
else:
self._repo = repo.unfiltered()
Gregory Szorc
hg: establish a cache for localrepository instances...
r26219 self._state = state
self.mtime = mtime
return self._repo, True
def _repostate(self):
state = []
maxmtime = -1
for attr, fname in foi:
prefix = getattr(self._repo, attr)
p = os.path.join(prefix, fname)
try:
st = os.stat(p)
except OSError:
st = os.stat(prefix)
Augie Fackler
cleanup: use stat_result[stat.ST_MTIME] instead of stat_result.st_mtime...
r36799 state.append((st[stat.ST_MTIME], st.st_size))
maxmtime = max(maxmtime, st[stat.ST_MTIME])
Gregory Szorc
hg: establish a cache for localrepository instances...
r26219
return tuple(state), maxmtime
def copy(self):
Gregory Szorc
hg: always create new localrepository instance...
r26240 """Obtain a copy of this class instance.
A new localrepository instance is obtained. The new instance should be
completely independent of the original.
"""
repo = repository(self._repo.baseui, self._repo.origroot)
FUJIWARA Katsunori
hg: make cachedlocalrepo cache appropriate repoview object...
r28119 if self._filtername:
repo = repo.filtered(self._filtername)
else:
repo = repo.unfiltered()
Gregory Szorc
hg: always create new localrepository instance...
r26240 c = cachedlocalrepo(repo)
Gregory Szorc
hg: establish a cache for localrepository instances...
r26219 c._state = self._state
c.mtime = self.mtime
return c