##// END OF EJS Templates
strip: make repair.strip transactional to avoid repository corruption...
strip: make repair.strip transactional to avoid repository corruption Uses a transaction instance from the local repository to journal the truncation of revlog files, such that if a strip only partially completes, hg recover will be able to finish the truncate of all the files. The potential unbundling of changes that have been backed up to be restored later will, in case of an error, have to be unbundled manually. The difference is that it will be possible to recover the repository state so the unbundle can actually succeed.

File last commit:

r7935:39566bb9 default
r8073:e8a28556 default
Show More
hg.py
296 lines | 9.8 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 #
# This software may be used and distributed according to the terms
# of the GNU General Public License, incorporated herein by reference.
Matt Mackall
Simplify i18n imports
r3891 from i18n import _
Matt Mackall
Replace demandload with new demandimport
r3877 import localrepo, bundlerepo, httprepo, sshrepo, statichttprepo
Matt Mackall
error: move lock errors...
r7640 import errno, lock, os, shutil, util, extensions, error
Matt Mackall
Replace demandload with new demandimport
r3877 import merge as _merge
import verify as _verify
mpm@selenic.com
Add back links from file revisions to changeset revisions...
r0
Vadim Gelfer
clean up hg.py: move repo constructor code into each repo module
r2740 def _local(path):
Brendan Cully
Make hg.repository work with no path argument
r3195 return (os.path.isfile(util.drop_scheme('file', path)) and
Vadim Gelfer
allow None for path of hg.repository
r2768 bundlerepo or localrepo)
Vadim Gelfer
hg.repository: make protocol table driven....
r2469
Bryan O'Sullivan
parseurl: make revs optional
r6525 def parseurl(url, revs=[]):
Matt Mackall
move parseurl from cmdutil to hg
r5177 '''parse url#branch, returning url, branch + revs'''
if '#' not in url:
Dirkjan Ochtman
clone: honor -r even when pulling named branches
r7045 return url, (revs or None), revs and revs[-1] or None
Matt Mackall
move parseurl from cmdutil to hg
r5177
Dirkjan Ochtman
clone: honor -r even when pulling named branches
r7045 url, branch = url.split('#', 1)
checkout = revs and revs[-1] or branch
return url, revs + [branch], checkout
Matt Mackall
move parseurl from cmdutil to hg
r5177
Vadim Gelfer
make repo scheme table driven.
r2472 schemes = {
Vadim Gelfer
clean up hg.py: move repo constructor code into each repo module
r2740 'bundle': bundlerepo,
'file': _local,
'http': httprepo,
'https': httprepo,
'ssh': sshrepo,
'static-http': statichttprepo,
Thomas Arendsen Hein
Removed deprecated hg:// and old-http:// protocols (issue406)
r4853 }
Vadim Gelfer
hg.repository: make protocol table driven....
r2469
Vadim Gelfer
clean up hg.py: move repo constructor code into each repo module
r2740 def _lookup(path):
scheme = 'file'
if path:
c = path.find(':')
if c > 0:
scheme = path[:c]
thing = schemes.get(scheme) or schemes['file']
try:
return thing(path)
except TypeError:
return thing
Matt Mackall
Move merge code to its own module...
r2775
Vadim Gelfer
hg.py: add islocal() and defaultdest() functions, refactor...
r2719 def islocal(repo):
'''return true if repo or path is local'''
if isinstance(repo, str):
Vadim Gelfer
clean up hg.py: move repo constructor code into each repo module
r2740 try:
return _lookup(repo).islocal(repo)
except AttributeError:
return False
Vadim Gelfer
hg.py: add islocal() and defaultdest() functions, refactor...
r2719 return repo.local()
Brendan Cully
Make hg.repository work with no path argument
r3195 def repository(ui, path='', create=False):
Matt Mackall
Add a doc string
r2774 """return a repository object for the specified path"""
Vadim Gelfer
call reposetup functions of extension modules whenever repo created
r2847 repo = _lookup(path).instance(ui, path, create)
Alexis S. L. Carvalho
Try to pass repo.ui to reposetup hooks...
r4074 ui = getattr(repo, "ui", ui)
Alexis S. L. Carvalho
Move cmdtable and reposetup handling out of extensions.py...
r5192 for name, module in extensions.extensions():
hook = getattr(module, 'reposetup', None)
if hook:
hook(ui, repo)
Vadim Gelfer
call reposetup functions of extension modules whenever repo created
r2847 return repo
Vadim Gelfer
clone: move code into hg module. make doc better....
r2597
Vadim Gelfer
hg.py: add islocal() and defaultdest() functions, refactor...
r2719 def defaultdest(source):
'''return default destination of clone if none is given'''
return os.path.basename(os.path.normpath(source))
Matt Mackall
Add a doc string
r2774
Bryan O'Sullivan
Hoist localpath to the top level
r6524 def localpath(path):
if path.startswith('file://localhost/'):
return path[16:]
if path.startswith('file://'):
return path[7:]
if path.startswith('file:'):
return path[5:]
return path
Vadim Gelfer
clone: do not make streaming default. add --stream option instead.
r2613 def clone(ui, source, dest=None, pull=False, rev=None, update=True,
stream=False):
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
function. Returns a pair of repository objects, the source and
newly created destination.
The location of the source is added to the new repository's
.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)
pull: always pull from source repository, even in local case
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)
Vadim Gelfer
clone: move code into hg module. make doc better....
r2597 """
Matt Mackall
Add support for url#id syntax...
r4478
Vadim Gelfer
hg.py: add islocal() and defaultdest() functions, refactor...
r2719 if isinstance(source, str):
Alexis S. L. Carvalho
clone: make things work when source is a repo object
r6089 origsource = ui.expandpath(source)
source, rev, checkout = parseurl(origsource, rev)
Vadim Gelfer
hg.py: add islocal() and defaultdest() functions, refactor...
r2719 src_repo = repository(ui, source)
else:
src_repo = source
Alexis S. L. Carvalho
clone: make things work when source is a repo object
r6089 origsource = source = src_repo.url()
Dirkjan Ochtman
clone: honor -r even when pulling named branches
r7045 checkout = rev and rev[-1] or None
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)
Thomas Arendsen Hein
Show the destionation for clone if not specified manually.
r3841 ui.status(_("destination directory: %s\n") % dest)
Vadim Gelfer
hg.py: add islocal() and defaultdest() functions, refactor...
r2719
dest = localpath(dest)
source = localpath(source)
Vadim Gelfer
clone: move code into hg module. make doc better....
r2597
if os.path.exists(dest):
Steve Borho
allow clone into existing but empty directories
r7927 if not os.path.isdir(dest):
raise util.Abort(_("destination '%s' already exists") % dest)
elif os.listdir(dest):
raise util.Abort(_("destination '%s' is not empty") % dest)
Vadim Gelfer
clone: move code into hg module. make doc better....
r2597
class DirCleanup(object):
def __init__(self, dir_):
self.rmtree = shutil.rmtree
self.dir_ = dir_
def close(self):
self.dir_ = None
def __del__(self):
if self.dir_:
self.rmtree(self.dir_, True)
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 src_lock = dest_lock = dir_cleanup = None
try:
if islocal(dest):
dir_cleanup = DirCleanup(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 abspath = origsource
copy = False
Matt Mackall
clone: use cancopy
r6315 if src_repo.cancopy() and islocal(dest):
Alexis S. L. Carvalho
Merge with crew-stable
r5248 abspath = os.path.abspath(util.drop_scheme('file', origsource))
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
src_lock = src_repo.lock()
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:
Steve Borho
on clone failure, only remove directories we created...
r7935 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
dir_cleanup.dir_ = hgdir
Matt Mackall
clone: fix race with same target directory (issue716)...
r5569 try:
Steve Borho
on clone failure, only remove directories we created...
r7935 dest_path = hgdir
Matt Mackall
clone: fix race with same target directory (issue716)...
r5569 os.mkdir(dest_path)
except OSError, inst:
if inst.errno == errno.EEXIST:
dir_cleanup.close()
raise util.Abort(_("destination '%s' already exists")
% dest)
raise
Vadim Gelfer
clone: move code into hg module. make doc better....
r2597
Matt Mackall
clone: get a list of files to clone from store
r6903 for f in src_repo.store.copylist():
src = os.path.join(src_repo.path, f)
Benoit Boissinot
fix regression on empty repo cloning introduced by 0642d9d7ec80...
r6944 dst = os.path.join(dest_path, f)
dstbase = os.path.dirname(dst)
if dstbase and not os.path.exists(dstbase):
os.mkdir(dstbase)
Matt Mackall
clone: get a list of files to clone from store
r6903 if os.path.exists(src):
if dst.endswith('data'):
# lock to avoid premature writing to the target
dest_lock = lock.lock(os.path.join(dstbase, "lock"))
util.copyfiles(src, dst)
Vadim Gelfer
clone: move code into hg module. make doc better....
r2597
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
dest_repo = repository(ui, dest)
else:
Matt Mackall
clone: fix race with same target directory (issue716)...
r5569 try:
dest_repo = repository(ui, dest, create=True)
except OSError, inst:
if inst.errno == errno.EEXIST:
dir_cleanup.close()
raise util.Abort(_("destination '%s' already exists")
% 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:
if 'lookup' not in src_repo.capabilities:
raise util.Abort(_("src repository does not support revision "
"lookup and so doesn't support clone by "
"revision"))
revs = [src_repo.lookup(r) for r in rev]
Benoit Boissinot
don't use localrepo.__init__ to create the dest repo with clone+hardlinks
r3849
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 if dest_repo.local():
dest_repo.clone(src_repo, heads=revs, stream=stream)
elif src_repo.local():
src_repo.push(dest_repo, revs=revs)
else:
raise util.Abort(_("clone from remote to remote not supported"))
Vadim Gelfer
clone: move code into hg module. make doc better....
r2597
Benoit Boissinot
merge with -stable
r5186 if dir_cleanup:
dir_cleanup.close()
Vadim Gelfer
clone: move code into hg module. make doc better....
r2597
if dest_repo.local():
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 fp = dest_repo.opener("hgrc", "w", text=True)
fp.write("[paths]\n")
Benoit Boissinot
Escape '%' when writing to hgrc (issue1199)...
r7044 # percent needs to be escaped for ConfigParser
fp.write("default = %s\n" % abspath.replace('%', '%%'))
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
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 if update:
Adrian Buehlmann
clone: print "updating working directory" status message...
r6338 dest_repo.ui.status(_("updating working directory\n"))
Bryan O'Sullivan
repo: add rjoin method
r6526 if update is not True:
checkout = update
Dirkjan Ochtman
clone: honor -r even when pulling named branches
r7045 for test in (checkout, 'default', 'tip'):
Alexis S. L. Carvalho
Merge with crew-stable
r5248 try:
Dirkjan Ochtman
clone: honor -r even when pulling named branches
r7045 uprev = dest_repo.lookup(test)
break
Alexis S. L. Carvalho
Merge with crew-stable
r5248 except:
Dirkjan Ochtman
clone: honor -r even when pulling named branches
r7045 continue
_update(dest_repo, uprev)
Vadim Gelfer
clone: move code into hg module. make doc better....
r2597
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 return src_repo, dest_repo
finally:
del src_lock, dest_lock, dir_cleanup
Matt Mackall
Move merge code to its own module...
r2775
Matt Mackall
merge: pull user messages out to hg.py...
r3316 def _showstats(repo, stats):
stats = ((stats[0], _("updated")),
(stats[1], _("merged")),
(stats[2], _("removed")),
(stats[3], _("unresolved")))
note = ", ".join([_("%d files %s") % s for s in stats])
repo.ui.status("%s\n" % note)
Matt Mackall
Introduce update helper functions: update, merge, clean, and revert
r2808 def update(repo, node):
"""update the working directory to node, merging linear changes"""
Matt Mackall
Make repo locks recursive, eliminate all passing of lock/wlock
r4917 stats = _merge.update(repo, node, False, False, None)
Matt Mackall
merge: pull user messages out to hg.py...
r3316 _showstats(repo, stats)
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
Matt Mackall
Make repo locks recursive, eliminate all passing of lock/wlock
r4917 def clean(repo, node, show_stats=True):
Matt Mackall
Introduce update helper functions: update, merge, clean, and revert
r2808 """forcibly switch the working directory to node, clobbering changes"""
Matt Mackall
Make repo locks recursive, eliminate all passing of lock/wlock
r4917 stats = _merge.update(repo, node, False, True, None)
Matt Mackall
merge: pull user messages out to hg.py...
r3316 if show_stats: _showstats(repo, stats)
Matt Mackall
merge: make return codes more sensible...
r5635 return stats[3] > 0
Matt Mackall
Move merge code to its own module...
r2775
Matt Mackall
Make repo locks recursive, eliminate all passing of lock/wlock
r4917 def merge(repo, node, force=None, remind=True):
Matt Mackall
Introduce update helper functions: update, merge, clean, and revert
r2808 """branch merge with node, resolving changes"""
Matt Mackall
Make repo locks recursive, eliminate all passing of lock/wlock
r4917 stats = _merge.update(repo, node, True, force, False)
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 "
"or 'hg up --clean' 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
Matt Mackall
Make repo locks recursive, eliminate all passing of lock/wlock
r4917 def revert(repo, node, choose):
Matt Mackall
Introduce update helper functions: update, merge, clean, and revert
r2808 """revert changes to revision in node without updating dirstate"""
Matt Mackall
merge: make return codes more sensible...
r5635 return _merge.update(repo, node, False, True, choose)[3] > 0
Matt Mackall
Move repo.verify
r2778
def verify(repo):
"""verify the consistency of a repository"""
return _verify.verify(repo)