##// END OF EJS Templates
store: give name to lowerencode function...
store: give name to lowerencode function lambda function isn't easy to track in traceback.

File last commit:

r34133:0fa78132 default
r34210:96808804 default
Show More
hg.py
1064 lines | 37.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
from .i18n import _
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,
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,
merge as mergemod,
node,
phases,
repoview,
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))
Alexander Solovyov
expand paths to local repository or bundle in appropriate classes...
r11154 return (os.path.isfile(path) 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
if util.safehasattr(revs, 'first'):
timeless
cleanup: remove superfluous space after space after equals (python)
r27637 y = revs.first()
Pierre-Yves David
repair: use `first` instead of direct indexing...
r22818 elif revs:
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]
Sune Foldager
peer: introduce peer methods to prepare for peer classes...
r17191 branchmap = peer.branchmap()
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 = []
Jun Wu
dispatch: make request accept additional reposetups...
r32379 def _peerorrepo(ui, path, create=False, presetupfuncs=None):
Matt Mackall
hg: rearrange peer scheme lookup...
r14605 """return a repository object for the specified path"""
Sune Foldager
peer: introduce peer methods to prepare for peer classes...
r17191 obj = _peerlookup(path).instance(ui, path, create)
ui = getattr(obj, "ui", ui)
Jun Wu
dispatch: make request accept additional reposetups...
r32379 for f in presetupfuncs or []:
f(ui, obj)
FUJIWARA Katsunori
extensions: list up only enabled extensions, if "ui" is specified...
r19777 for name, module in extensions.extensions(ui):
Matt Mackall
hg: rearrange peer scheme lookup...
r14605 hook = getattr(module, 'reposetup', None)
if hook:
Sune Foldager
peer: introduce peer methods to prepare for peer classes...
r17191 hook(ui, obj)
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
Jun Wu
dispatch: make request accept additional reposetups...
r32379 def repository(ui, path='', create=False, presetupfuncs=None):
Sune Foldager
peer: introduce peer methods to prepare for peer classes...
r17191 """return a repository object for the specified path"""
Jun Wu
dispatch: make request accept additional reposetups...
r32379 peer = _peerorrepo(ui, path, create, presetupfuncs=presetupfuncs)
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
Idan Kamara
peer: change arg name to convey it can be a repo as well
r14839 def peer(uiorrepo, opts, path, create=False):
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)
Sune Foldager
peer: introduce peer methods to prepare for peer classes...
r17191 return _peerorrepo(rui, path, create).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
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
Matt Mackall
add helper function to create shared repos
r8800 if isinstance(source, str):
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 origsource = source = srcrepo.url()
checkout = None
sharedpath = srcrepo.sharedpath # if our source is already sharing
Pierre-Yves David
vfs: use 'vfs' module directly in 'mercurial.hg'...
r31218 destwvfs = vfsmod.vfs(dest, realpath=True)
destvfs = vfsmod.vfs(os.path.join(destwvfs.base, '.hg'), realpath=True)
Matt Mackall
add helper function to create shared repos
r8800
Chinmay Joshi
hg: update to use vfs functions in shared destination repository...
r21801 if destvfs.lexists():
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('destination already exists'))
Matt Mackall
add helper function to create shared repos
r8800
Chinmay Joshi
hg: use vfs functions in destination repository with share...
r21800 if not destwvfs.isdir():
destwvfs.mkdir()
Chinmay Joshi
hg: update to use vfs functions in shared destination repository...
r21801 destvfs.makedir()
Matt Mackall
add helper function to create shared repos
r8800
requirements = ''
try:
Angel Ezquerra
localrepo: remove all external users of localrepo.opener...
r23877 requirements = srcrepo.vfs.read('requires')
Gregory Szorc
global: mass rewrite to use modern exception syntax...
r25660 except IOError as inst:
Matt Mackall
add helper function to create shared repos
r8800 if inst.errno != errno.ENOENT:
raise
Dan Villiom Podlaski Christiansen
share: add --relative flag to store a relative path to the source...
r31133 if relative:
try:
sharedpath = os.path.relpath(sharedpath, destvfs.base)
requirements += 'relshared\n'
except IOError as e:
raise error.Abort(_('cannot calculate relative path'),
hint=str(e))
else:
requirements += 'shared\n'
Chinmay Joshi
hg: update util.writefile method to use write with vfs in share...
r21802 destvfs.write('requires', requirements)
destvfs.write('sharedpath', sharedpath)
Matt Mackall
add helper function to create shared repos
r8800
Chinmay Joshi
hg: use vfs functions in destination repository with share...
r21800 r = repository(ui, destwvfs.base)
Gregory Szorc
hg: set default path correctly when doing a clone+share (issue5378)...
r30041 postshare(srcrepo, r, bookmarks=bookmarks, defaultpath=defaultpath)
Gregory Szorc
hg: perform update after pulling during clone with share (issue5103)...
r28632 _postshareupdate(r, update, checkout=checkout)
Matt Mackall
add helper function to create shared repos
r8800
Gregory Szorc
hg: set default path correctly when doing a clone+share (issue5378)...
r30041 def postshare(sourcerepo, destrepo, bookmarks=True, 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:
fp = destrepo.vfs("hgrc", "w", text=True)
fp.write("[paths]\n")
fp.write("default = %s\n" % default)
fp.close()
Pierre-Yves David
shared: take wlock for writting the 'shared' file...
r29753 with destrepo.wlock():
if bookmarks:
fp = destrepo.vfs('shared', 'w')
fp.write(sharedbookmarks + '\n')
fp.close()
Ryan McElroy
share: add option to share bookmarks...
r23614
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
num = 0
Augie Fackler
clone: add progress support to hardlink clones (issue3059)
r24440 closetopic = [None]
def prog(topic, pos):
if pos is None:
closetopic[0] = topic
else:
ui.progress(topic, pos + num)
Matt Mackall
publishing: use new helper method
r25624 srcpublishing = srcrepo.publishing()
Pierre-Yves David
vfs: use 'vfs' module directly in 'mercurial.hg'...
r31218 srcvfs = vfsmod.vfs(srcrepo.sharedpath)
dstvfs = vfsmod.vfs(destpath)
Simon Heimberg
hg: extract copying the store out of clone
r15078 for f in srcrepo.store.copylist():
Pierre-Yves David
phases: on copy clone, do not copy phases data if repote is publishing
r15741 if srcpublishing and f.endswith('phaseroots'):
continue
FUJIWARA Katsunori
hg: rewrite "copystore()" with vfs...
r20089 dstbase = os.path.dirname(f)
if dstbase and not dstvfs.exists(dstbase):
dstvfs.mkdir(dstbase)
if srcvfs.exists(f):
if f.endswith('data'):
FUJIWARA Katsunori
hg: use "os.path.join()" to join path components which may be empty (issue4203)...
r20825 # 'dstbase' may be empty (e.g. revlog format 0)
lockfile = os.path.join(dstbase, "lock")
Simon Heimberg
hg: extract copying the store out of clone
r15078 # lock to avoid premature writing to the target
FUJIWARA Katsunori
hg: use "os.path.join()" to join path components which may be empty (issue4203)...
r20825 destlock = lock.lock(dstvfs, lockfile)
FUJIWARA Katsunori
hg: rewrite "copystore()" with vfs...
r20089 hardlink, n = util.copyfiles(srcvfs.join(f), dstvfs.join(f),
Augie Fackler
clone: add progress support to hardlink clones (issue3059)
r24440 hardlink, progress=prog)
Simon Heimberg
hg: extract copying the store out of clone
r15078 num += n
if hardlink:
ui.debug("linked %d files\n" % num)
Augie Fackler
clone: add progress support to hardlink clones (issue3059)
r24440 if closetopic[0]:
ui.progress(closetopic[0], None)
Simon Heimberg
hg: extract copying the store out of clone
r15078 else:
ui.debug("copied %d files\n" % num)
Augie Fackler
clone: add progress support to hardlink clones (issue3059)
r24440 if closetopic[0]:
ui.progress(closetopic[0], None)
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"))
revs = [srcpeer.lookup(r) for r in rev]
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,
rev=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)
Gregory Szorc
hg: set default path correctly when doing a clone+share (issue5378)...
r30041 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.
destrepo = repository(ui, path=dest)
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)
local-clone: extract the listing of caches to copy...
r32493 def _cachetocopy(srcrepo):
"""return the list of cache file valuable to copy during a clone"""
# In local clones we're copying all nodes, not just served
# ones. Therefore copy all branch caches over.
cachefiles = ['branch2']
local-clone: also copy revs-branch-cache files...
r32494 cachefiles += ['branch2-%s' % f for f in repoview.filtertable]
cachefiles += ['rbc-names-v1', 'rbc-revs-v1']
local-clone: also copy tags related caches...
r32495 cachefiles += ['tags2']
cachefiles += ['tags2-%s' % f for f in repoview.filtertable]
cachefiles += ['hgtagsfnodes1']
local-clone: extract the listing of caches to copy...
r32493 return cachefiles
Martin Geisler
hg: rename opts argument to peeropts in clone...
r14607 def clone(ui, peeropts, source, dest=None, pull=False, rev=None,
Gregory Szorc
hg: support for auto sharing stores when cloning...
r25761 update=True, stream=False, branch=None, shareopts=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
Vadim Gelfer
clone: move code into hg module. make doc better....
r2597 rev: revision to clone up to (implies pull=True)
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."
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)
Sune Foldager
add -b/--branch option to clone, bundle, incoming, outgoing, pull, push
r10379 source, branch = 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
Nicolas Dumazet
hg.clone: do not ignore branch argument when source is a repo object...
r11818 branch = (None, branch or [])
Sune Foldager
peer: introduce peer methods to prepare for peer classes...
r17191 origsource = source = srcpeer.url()
rev, checkout = addbranchrevs(srcpeer, srcpeer, branch, rev)
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: 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:
rootnode = srcpeer.lookup('0')
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(
sharepool, hashlib.sha1(source).hexdigest())
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
if sharepath:
return clonewithshare(ui, peeropts, sharepath, source, srcpeer,
dest, pull=pull, rev=rev, update=update,
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)):
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 copy = not pull and not rev
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:
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):
os.mkdir(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')
local-clone: extract the listing of caches to copy...
r32493 for cache in _cachetocopy(srcrepo):
_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:
Simon Heimberg
subrepo: more isolation, only use ui for hg.peer when there is no repo...
r17875 destpeer = peer(srcrepo or ui, peeropts, dest, create=True)
# only pass ui when no srcrepo
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
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 revs = None
if rev:
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"))
Sune Foldager
peer: introduce peer methods to prepare for peer classes...
r17191 revs = [srcpeer.lookup(r) for r in rev]
Brett Carter
clone: try updating to the actual changeset specified in options...
r8417 checkout = revs[0]
Augie Fackler
localrepo: remove clone method by hoisting into hg.py...
r27165 local = destpeer.local()
if local:
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,
streamclonerequested=stream)
Sune Foldager
peer: introduce peer methods to prepare for peer classes...
r17191 elif srcrepo:
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']
Yuya Nishihara
py3: use bytes IO to write sample hgrc...
r33650 fp = destrepo.vfs("hgrc", "wb")
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)
fp.write(util.tonativeeol(template % defaulturl))
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 fp.close()
Benoit Boissinot
clone: do not delete the target if only the update fails
r5185
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
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:
Augie Fackler
clone: don't fail with --update for non-local clones (issue3578)...
r17342 checkout = srcpeer.lookup(update)
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:
Alexis S. L. Carvalho
Merge with crew-stable
r5248 try:
Thomas Arendsen Hein
clone: make sure to use "@" as bookmark and "default" as branch (issue3677)...
r17867 uprev = destrepo.lookup(checkout)
Matt Mackall
Make distinct lookup error for localrepo.lookup...
r9423 except error.RepoLookupError:
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):
if quietempty and not any(stats):
return
Martin Geisler
hg: avoid combining translated strings...
r9454 repo.ui.status(_("%d files updated, %d files merged, "
"%d files removed, %d files unresolved\n") % stats)
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)"""
Augie Fackler
merge: have merge.update use a matcher instead of partial fn...
r27344 return mergemod.update(repo, node, False, 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)
Matt Mackall
merge: pull user messages out to hg.py...
r3316 if stats[3]:
Matt Mackall
resolve: new command...
r6518 repo.ui.status(_("use 'hg resolve' to retry unresolved file merges\n"))
Matt Mackall
merge: make return codes more sensible...
r5635 return stats[3] > 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)
Matt Mackall
merge: make return codes more sensible...
r5635 return stats[3] > 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:
Martin von Zweigbergk
update: add experimental config for default way of handling dirty wdir...
r31167 updatecheck = ui.config('experimental', 'updatecheck')
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
Simon Farnsworth
merge: add conflict labels to merge command...
r30062 def merge(repo, node, force=None, remind=True, mergeforce=False, labels=None):
Greg Ward
merge: document some internal return values.
r13162 """Branch merge with node, resolving changes. Return true if any
unresolved conflicts."""
Simon Farnsworth
merge: add conflict labels to merge command...
r30062 stats = mergemod.update(repo, node, True, force, mergeforce=mergeforce,
labels=labels)
Matt Mackall
merge: pull user messages out to hg.py...
r3316 _showstats(repo, stats)
if stats[3]:
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 "
Brodie Rao
merge: suggest 'hg up -C .' for discarding changes, not 'hg up -C'...
r12314 "or 'hg update -C .' to abandon\n"))
Matt Mackall
merge: pull user messages out to hg.py...
r3316 elif remind:
repo.ui.status(_("(branch merge, don't forget to commit)\n"))
Matt Mackall
merge: make return codes more sensible...
r5635 return stats[3] > 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')
Nicolas Dumazet
incoming: unify code for incoming and graphlog.incoming
r12730 displayer = cmdutil.show_changeset(ui, other, opts, buffered)
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):
limit = cmdutil.loglimit(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):
dest = ui.expandpath(dest or 'default-push', dest or 'default')
dest, branches = parseurl(dest, opts.get('branch'))
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:
Matt Harbison
outgoing: accept revset argument for --rev...
r17198 revs = [repo.lookup(rev) 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
Martin Geisler
outgoing: move code from commands to cmdutil...
r12271 limit = cmdutil.loglimit(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')
Martin Geisler
outgoing: move code from commands to cmdutil...
r12271 displayer = cmdutil.show_changeset(ui, repo, opts)
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:
FUJIWARA Katsunori
doc: omit useless _() invocation...
r29645 repo.ui.warn(('%s: %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)
state.append((st.st_mtime, st.st_size))
maxmtime = max(maxmtime, st.st_mtime)
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