##// END OF EJS Templates
strip: rename test-mq-strip into test-strip...
strip: rename test-mq-strip into test-strip And makes it use the strip extension only (except for the part testing mq interaction)

File last commit:

r19778:55ef7903 default
r19827:8b9c73dd default
Show More
localrepo.py
2469 lines | 95.2 KiB | text/x-python | PythonLexer
mpm@selenic.com
Break apart hg.py...
r1089 # localrepo.py - read/write repository class for mercurial
#
Thomas Arendsen Hein
Updated copyright notices and add "and others" to "hg version"
r4635 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
mpm@selenic.com
Break apart hg.py...
r1089 #
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.
Pierre-Yves David
branchmap: extract read logic from repo
r18118 from node import hex, nullid, short
Matt Mackall
Simplify i18n imports
r3891 from i18n import _
Pierre-Yves David
clfilter: add actual repo filtering mechanism...
r18100 import peer, changegroup, subrepo, discovery, pushkey, obsolete, repoview
Pierre-Yves David
phases: basic I/O logic...
r15418 import changelog, dirstate, filelog, manifest, context, bookmarks, phases
Pierre-Yves David
obsolete: extract obsolescence marker pulling into a dedicated function...
r19054 import lock, transaction, store, encoding
Matt Mackall
localrepo: add set method to iterate over a given revset...
r14902 import scmutil, util, extensions, hook, error, revset
Benoit Boissinot
style: use consistent variable names (*mod) with imports which would shadow
r10651 import match as matchmod
import merge as mergemod
import tags as tagsmod
Ronny Pfannschmidt
switch lock releasing in the core from gc to explicit
r8109 from lock import release
Dirkjan Ochtman
move working dir/dirstate methods from localrepo to workingctx
r11303 import weakref, errno, os, time, inspect
Pierre-Yves David
branchmap: extract write logic from localrepo
r18117 import branchmap
Matt Mackall
localrepo: use propertycache
r8260 propertycache = util.propertycache
Idan Kamara
localrepo: decorate dirstate() with filecache...
r14930 filecache = scmutil.filecache
Ronny Pfannschmidt
switch lock releasing in the core from gc to explicit
r8109
Pierre-Yves David
clfilter: ensure that filecache on localrepo is unfiltered...
r18014 class repofilecache(filecache):
"""All filecache usage on repo are done for logic that should be unfiltered
"""
def __get__(self, repo, type=None):
return super(repofilecache, self).__get__(repo.unfiltered(), type)
def __set__(self, repo, value):
return super(repofilecache, self).__set__(repo.unfiltered(), value)
def __delete__(self, repo):
return super(repofilecache, self).__delete__(repo.unfiltered())
class storecache(repofilecache):
Idan Kamara
filecache: refactor path join logic to a function...
r16198 """filecache for files in the store"""
def join(self, obj, fname):
return obj.sjoin(fname)
Pierre-Yves David
clfilter: add a propertycache that must be unfiltered...
r18013 class unfilteredpropertycache(propertycache):
"""propertycache that apply to unfiltered repo only"""
def __get__(self, repo, type=None):
Wei, Elson
localrepo: get value from the unfiltered caches should check if the attribute existed....
r19635 if hasunfilteredcache(repo, self.name):
return getattr(repo.unfiltered(), self.name)
Pierre-Yves David
clfilter: add a propertycache that must be unfiltered...
r18013 return super(unfilteredpropertycache, self).__get__(repo.unfiltered())
class filteredpropertycache(propertycache):
"""propertycache that must take filtering in account"""
def cachevalue(self, obj, value):
object.__setattr__(obj, self.name, value)
def hasunfilteredcache(repo, name):
Mads Kiilerich
spelling: fix some minor issues found by spell checker
r18644 """check if a repo has an unfilteredpropertycache value for <name>"""
Pierre-Yves David
clfilter: add a propertycache that must be unfiltered...
r18013 return name in vars(repo.unfiltered())
Pierre-Yves David
clfilter: rename `unfilteredmeth` to `unfilteredmethod`...
r18016 def unfilteredmethod(orig):
Pierre-Yves David
clfilter: introduce an `unfilteredmethod` decorator...
r17994 """decorate method that always need to be run on unfiltered version"""
def wrapper(repo, *args, **kwargs):
return orig(repo.unfiltered(), *args, **kwargs)
return wrapper
Peter Arrenbrecht
peer: introduce real peer classes...
r17192 MODERNCAPS = set(('lookup', 'branchmap', 'pushkey', 'known', 'getbundle'))
LEGACYCAPS = MODERNCAPS.union(set(['changegroupsubset']))
class localpeer(peer.peerrepository):
'''peer for a local repo; reflects only the most recent API'''
def __init__(self, repo, caps=MODERNCAPS):
peer.peerrepository.__init__(self)
Kevin Bullock
filtering: rename filters to their antonyms...
r18382 self._repo = repo.filtered('served')
Peter Arrenbrecht
peer: introduce real peer classes...
r17192 self.ui = repo.ui
self._caps = repo._restrictcapabilities(caps)
self.requirements = repo.requirements
self.supportedformats = repo.supportedformats
def close(self):
self._repo.close()
def _capabilities(self):
return self._caps
def local(self):
return self._repo
Sune Foldager
peer: introduce canpush and improve error message
r17193 def canpush(self):
return True
Peter Arrenbrecht
peer: introduce real peer classes...
r17192 def url(self):
return self._repo.url()
def lookup(self, key):
return self._repo.lookup(key)
def branchmap(self):
Pierre-Yves David
clfilter: drop extra filtering in localpeer...
r18279 return self._repo.branchmap()
Peter Arrenbrecht
peer: introduce real peer classes...
r17192
def heads(self):
Pierre-Yves David
clfilter: drop extra filtering in localpeer...
r18279 return self._repo.heads()
Peter Arrenbrecht
peer: introduce real peer classes...
r17192
def known(self, nodes):
return self._repo.known(nodes)
Benoit Boissinot
bundle-ng: add bundlecaps argument to getbundle() command
r19201 def getbundle(self, source, heads=None, common=None, bundlecaps=None):
return self._repo.getbundle(source, heads=heads, common=common,
bundlecaps=None)
Peter Arrenbrecht
peer: introduce real peer classes...
r17192
# TODO We might want to move the next two calls into legacypeer and add
# unbundle instead.
def lock(self):
return self._repo.lock()
def addchangegroup(self, cg, source, url):
return self._repo.addchangegroup(cg, source, url)
def pushkey(self, namespace, key, old, new):
return self._repo.pushkey(namespace, key, old, new)
def listkeys(self, namespace):
return self._repo.listkeys(namespace)
def debugwireargs(self, one, two, three=None, four=None, five=None):
'''used to test argument passing over the wire'''
return "%s %s %s %s %s" % (one, two, three, four, five)
class locallegacypeer(localpeer):
'''peer extension which implements legacy methods too; used for tests with
restricted capabilities'''
def __init__(self, repo):
localpeer.__init__(self, repo, caps=LEGACYCAPS)
def branches(self, nodes):
return self._repo.branches(nodes)
def between(self, pairs):
return self._repo.between(pairs)
def changegroup(self, basenodes, source):
return self._repo.changegroup(basenodes, source)
def changegroupsubset(self, bases, heads, source):
return self._repo.changegroupsubset(bases, heads, source)
class localrepository(object):
Sune Foldager
revlog: support writing generaldelta revlogs...
r14270 supportedformats = set(('revlogv1', 'generaldelta'))
FUJIWARA Katsunori
localrepo: make supported features manageable in each repositories individually...
r19778 _basesupported = supportedformats | set(('store', 'fncache', 'shared',
'dotencode'))
Bryan O'Sullivan
localrepo: make requirements and openerreqs mutable by subclasses...
r17137 openerreqs = set(('revlogv1', 'generaldelta'))
requirements = ['revlogv1']
Pierre-Yves David
clfilter: ensure unfiltered repo have a filtername attribute too...
r18186 filtername = None
Bryan O'Sullivan
localrepo: make requirements and openerreqs mutable by subclasses...
r17137
FUJIWARA Katsunori
localrepo: make supported features manageable in each repositories individually...
r19778 featuresetupfuncs = set()
Bryan O'Sullivan
localrepo: make requirements and openerreqs mutable by subclasses...
r17137 def _baserequirements(self, create):
return self.requirements[:]
Vadim Gelfer
extend network protocol to stop clients from locking servers...
r2439
Martin Geisler
localrepo, sshrepo: use Boolean create argument in __init__
r14363 def __init__(self, baseui, path=None, create=False):
FUJIWARA Katsunori
vfs: split "expand" into "realpath"/"expandpath" to apply each separately...
r18945 self.wvfs = scmutil.vfs(path, expandpath=True, realpath=True)
FUJIWARA Katsunori
localrepo: use "vfs" constructor instead of "opener" one...
r17650 self.wopener = self.wvfs
FUJIWARA Katsunori
localrepo: use path expansion API via vfs...
r17157 self.root = self.wvfs.base
FUJIWARA Katsunori
localrepo: use "self.wvfs.join()" instead of "os.path.join()"...
r17158 self.path = self.wvfs.join(".hg")
Benoit Boissinot
move code around
r3850 self.origroot = path
Adrian Buehlmann
rename path_auditor to pathauditor...
r14220 self.auditor = scmutil.pathauditor(self.root, self._checknested)
FUJIWARA Katsunori
localrepo: use "vfs" constructor instead of "opener" one...
r17650 self.vfs = scmutil.vfs(self.path)
self.opener = self.vfs
Matt Mackall
repo: set up ui and extensions earlier
r8797 self.baseui = baseui
self.ui = baseui.copy()
Pierre-Yves David
phases: mechanism to allow extension to alter initial computation of phase...
r15922 # A list of callback to shape the phase if no data were found.
# Callback are in the form: func(repo, roots) --> processed root.
# This list it to be filled by extension during repo setup
self._phasedefaults = []
Matt Mackall
repo: set up ui and extensions earlier
r8797 try:
self.ui.readconfig(self.join("hgrc"), self.root)
extensions.loadall(self.ui)
except IOError:
pass
mpm@selenic.com
Break apart hg.py...
r1089
FUJIWARA Katsunori
localrepo: make supported features manageable in each repositories individually...
r19778 if self.featuresetupfuncs:
self.supported = set(self._basesupported) # use private copy
for setupfunc in self.featuresetupfuncs:
setupfunc(self.ui, self.supported)
else:
self.supported = self._basesupported
FUJIWARA Katsunori
localrepo: use file API via vfs while ensuring repository directory...
r17161 if not self.vfs.isdir():
Benoit Boissinot
localrepo: move the repo creation code, fail if the repo exists
r3035 if create:
FUJIWARA Katsunori
localrepo: use file API via vfs while ensuring repository directory...
r17161 if not self.wvfs.exists():
self.wvfs.makedirs()
self.vfs.makedir(notindexed=True)
Bryan O'Sullivan
localrepo: make requirements and openerreqs mutable by subclasses...
r17137 requirements = self._baserequirements(create)
Matt Mackall
repo: set up ui and extensions earlier
r8797 if self.ui.configbool('format', 'usestore', True):
FUJIWARA Katsunori
localrepo: use file API via vfs while ensuring repository directory...
r17161 self.vfs.mkdir("store")
Alexis S. L. Carvalho
small fixes for the parent patch...
r4166 requirements.append("store")
Matt Mackall
repo: set up ui and extensions earlier
r8797 if self.ui.configbool('format', 'usefncache', True):
Adrian Buehlmann
add format.usefncache config option (default is true)...
r7234 requirements.append("fncache")
Adrian Buehlmann
store: encode first period or space in filenames (issue1713)...
r12687 if self.ui.configbool('format', 'dotencode', True):
requirements.append('dotencode')
Alexis S. L. Carvalho
small fixes for the parent patch...
r4166 # create an invalid changelog
FUJIWARA Katsunori
localrepo: use "vfs" intead of "opener" while ensuring repository directory...
r17160 self.vfs.append(
Dan Villiom Podlaski Christiansen
prevent transient leaks of file handle by using new helper functions...
r14168 "00changelog.i",
Alexis S. L. Carvalho
small fixes for the parent patch...
r4166 '\0\0\0\2' # represents revlogv2
' dummy changelog to prevent using the old repo layout'
)
Sune Foldager
revlog: support writing generaldelta revlogs...
r14270 if self.ui.configbool('format', 'generaldelta', False):
requirements.append("generaldelta")
Andrew Pritchard
localrepo: make requirements attribute of newly-created repos contain a set...
r14905 requirements = set(requirements)
Benoit Boissinot
localrepo: move the repo creation code, fail if the repo exists
r3035 else:
Matt Mackall
error: move repo errors...
r7637 raise error.RepoError(_("repository %s not found") % path)
Benoit Boissinot
localrepo: move the repo creation code, fail if the repo exists
r3035 elif create:
Matt Mackall
error: move repo errors...
r7637 raise error.RepoError(_("repository %s already exists") % path)
Benoit Boissinot
add "requires" file to the repo, specifying the requirements
r3851 else:
try:
FUJIWARA Katsunori
localrepo: use "vfs" intead of "opener" while ensuring repository directory...
r17160 requirements = scmutil.readrequires(self.vfs, self.supported)
Benoit Boissinot
add "requires" file to the repo, specifying the requirements
r3851 except IOError, inst:
if inst.errno != errno.ENOENT:
raise
Adrian Buehlmann
introduce new function scmutil.readrequires...
r14482 requirements = set()
mpm@selenic.com
Break apart hg.py...
r1089
Matt Mackall
repo: add internal support for sharing store directories...
r8799 self.sharedpath = self.path
try:
FUJIWARA Katsunori
localrepo: use vfs instead of "os.path.*" in sharedpath checking...
r18946 vfs = scmutil.vfs(self.vfs.read("sharedpath").rstrip('\n'),
realpath=True)
s = vfs.base
if not vfs.exists():
Matt Mackall
repo: add internal support for sharing store directories...
r8799 raise error.RepoError(
Dongsheng Song
Fix warning: Seen unexpected token "%"
r8908 _('.hg/sharedpath points to nonexistent directory %s') % s)
Matt Mackall
repo: add internal support for sharing store directories...
r8799 self.sharedpath = s
except IOError, inst:
if inst.errno != errno.ENOENT:
raise
FUJIWARA Katsunori
localrepo: use "vfs" constructor/field for initialization around "store"
r17654 self.store = store.store(requirements, self.sharedpath, scmutil.vfs)
Adrian Buehlmann
introduce store classes...
r6840 self.spath = self.store.path
FUJIWARA Katsunori
localrepo: use "vfs" constructor/field for initialization around "store"
r17654 self.svfs = self.store.vfs
self.sopener = self.svfs
Adrian Buehlmann
introduce store classes...
r6840 self.sjoin = self.store.join
FUJIWARA Katsunori
localrepo: use "vfs" constructor/field for initialization around "store"
r17654 self.vfs.createmode = self.store.createmode
Sune Foldager
localrepo: factor out requirement application and write
r12295 self._applyrequirements(requirements)
if create:
self._writerequirements()
Benoit Boissinot
move code around
r3850
Greg Ward
localrepo: rename in-memory tag cache instance attributes (issue548)....
r9146
Pierre-Yves David
branchmap: enable caching for filtered version too...
r18189 self._branchcaches = {}
Matt Mackall
unify encode/decode filter routines
r4004 self.filterpats = {}
Patrick Mezard
Register data filters in a localrepo instead of util...
r5966 self._datafilters = {}
Matt Mackall
Use a weakref for recursive transactions
r4916 self._transref = self._lockref = self._wlockref = None
mpm@selenic.com
Break apart hg.py...
r1089
Idan Kamara
localrepo: add a cache with stat info for files under .hg/
r14929 # A cache for various files under .hg/ that tracks file changes,
# (used by the filecache decorator)
#
# Maps a property name to its util.filecacheentry
self._filecache = {}
Pierre-Yves David
clfilter: add a cache on repo for set of revision to filter for a given set....
r18101 # hold sets of revision to be filtered
# should be cleared when something might have changed the filter value:
# - new changesets,
# - phase change,
# - new obsolescence marker,
# - working directory parent change,
# - bookmark changes
self.filteredrevcache = {}
Peter Arrenbrecht
peer: introduce real peer classes...
r17192 def close(self):
pass
def _restrictcapabilities(self, caps):
return caps
Sune Foldager
localrepo: factor out requirement application and write
r12295 def _applyrequirements(self, requirements):
self.requirements = requirements
Sune Foldager
revlog: get rid of defversion...
r14333 self.sopener.options = dict((r, 1) for r in requirements
Bryan O'Sullivan
localrepo: make requirements and openerreqs mutable by subclasses...
r17137 if r in self.openerreqs)
Sune Foldager
localrepo: factor out requirement application and write
r12295
def _writerequirements(self):
reqfile = self.opener("requires", "w")
Mads Kiilerich
localrepo: store requirements sorted
r18356 for r in sorted(self.requirements):
Sune Foldager
localrepo: factor out requirement application and write
r12295 reqfile.write("%s\n" % r)
reqfile.close()
Martin Geisler
localrepo: add auditor attribute which knows about subrepos
r12162 def _checknested(self, path):
"""Determine if path is a legal nested repository."""
if not path.startswith(self.root):
return False
subpath = path[len(self.root) + 1:]
FUJIWARA Katsunori
windows: use normalized path to check repository nesting...
r15722 normsubpath = util.pconvert(subpath)
Martin Geisler
localrepo: add auditor attribute which knows about subrepos
r12162
# XXX: Checking against the current working copy is wrong in
# the sense that it can reject things like
#
# $ hg cat -r 10 sub/x.txt
#
# if sub/ is no longer a subrepository in the working copy
# parent revision.
#
# However, it can of course also allow things that would have
# been rejected before, such as the above cat command if sub/
# is a subrepository now, but was a normal directory before.
# The old path auditor would have rejected by mistake since it
# panics when it sees sub/.hg/.
#
Martin Geisler
localrepo: check nested repos against working directory...
r12174 # All in all, checking against the working copy seems sensible
# since we want to prevent access to nested repositories on
# the filesystem *now*.
ctx = self[None]
Martin Geisler
localrepo: add auditor attribute which knows about subrepos
r12162 parts = util.splitpath(subpath)
while parts:
FUJIWARA Katsunori
windows: use normalized path to check repository nesting...
r15722 prefix = '/'.join(parts)
Martin Geisler
localrepo: add auditor attribute which knows about subrepos
r12162 if prefix in ctx.substate:
FUJIWARA Katsunori
windows: use normalized path to check repository nesting...
r15722 if prefix == normsubpath:
Martin Geisler
localrepo: add auditor attribute which knows about subrepos
r12162 return True
else:
sub = ctx.sub(prefix)
return sub.checknested(subpath[len(prefix) + 1:])
else:
parts.pop()
return False
Peter Arrenbrecht
peer: introduce real peer classes...
r17192 def peer(self):
return localpeer(self) # not cached to avoid reference cycle
Pierre-Yves David
clfilter: introduce an "unfiltered" method on localrepo...
r17993 def unfiltered(self):
"""Return unfiltered version of the repository
Mads Kiilerich
spelling: fix some minor issues found by spell checker
r18644 Intended to be overwritten by filtered repo."""
Pierre-Yves David
clfilter: introduce an "unfiltered" method on localrepo...
r17993 return self
Pierre-Yves David
clfilter: add actual repo filtering mechanism...
r18100 def filtered(self, name):
"""Return a filtered version of a repository"""
# build a new class with the mixin and the current class
Mads Kiilerich
spelling: fix some minor issues found by spell checker
r18644 # (possibly subclass of the repo)
Pierre-Yves David
clfilter: add actual repo filtering mechanism...
r18100 class proxycls(repoview.repoview, self.unfiltered().__class__):
pass
return proxycls(self, name)
Pierre-Yves David
clfilter: ensure that filecache on localrepo is unfiltered...
r18014 @repofilecache('bookmarks')
Matt Mackall
bookmarks: move property methods into localrepo
r13355 def _bookmarks(self):
Augie Fackler
bookmarks: introduce a bmstore to manage bookmark persistence...
r17922 return bookmarks.bmstore(self)
Matt Mackall
bookmarks: move property methods into localrepo
r13355
Pierre-Yves David
clfilter: ensure that filecache on localrepo is unfiltered...
r18014 @repofilecache('bookmarks.current')
Matt Mackall
bookmarks: move property methods into localrepo
r13355 def _bookmarkcurrent(self):
return bookmarks.readcurrent(self)
Martin Geisler
localrepo: add auditor attribute which knows about subrepos
r12162
David Soria Parra
localrepo: introduce bookmarkheads...
r16707 def bookmarkheads(self, bookmark):
name = bookmark.split('@', 1)[0]
heads = []
for mark, n in self._bookmarks.iteritems():
if mark.split('@', 1)[0] == name:
heads.append(n)
return heads
Pierre-Yves David
phases: basic I/O logic...
r15418
Idan Kamara
filecache: refactor path join logic to a function...
r16198 @storecache('phaseroots')
Patrick Mezard
phases: introduce phasecache...
r16657 def _phasecache(self):
return phases.phasecache(self, self._phasedefaults)
Pierre-Yves David
phases: add a cache allowing to know in which phase a changeset is
r15420
Pierre-Yves.David@ens-lyon.org
obsolete: introduction of obsolete markers...
r17070 @storecache('obsstore')
def obsstore(self):
Pierre-Yves David
obsolete: move obsolete markers read/write logic to obsstore object...
r17124 store = obsolete.obsstore(self.sopener)
Pierre-Yves David
obsolete: warns if markers exist in a repo where the feature is not enabled...
r17297 if store and not obsolete._enabled:
Thomas Arendsen Hein
obsolete: fix typos in comments introduced by 6955d69a52a4
r17306 # message is rare enough to not be translated
Pierre-Yves David
obsolete: warns if markers exist in a repo where the feature is not enabled...
r17297 msg = 'obsolete feature not enabled but %i markers found!\n'
self.ui.warn(msg % len(list(store)))
Pierre-Yves.David@ens-lyon.org
obsolete: introduction of obsolete markers...
r17070 return store
Idan Kamara
filecache: refactor path join logic to a function...
r16198 @storecache('00changelog.i')
Matt Mackall
localrepo: use propertycache
r8260 def changelog(self):
c = changelog.changelog(self.sopener)
if 'HG_PENDING' in os.environ:
p = os.environ['HG_PENDING']
if p.startswith(self.root):
c.readpending('00changelog.i.a')
return c
Idan Kamara
filecache: refactor path join logic to a function...
r16198 @storecache('00manifest.i')
Matt Mackall
localrepo: use propertycache
r8260 def manifest(self):
return manifest.manifest(self.sopener)
Pierre-Yves David
clfilter: ensure that filecache on localrepo is unfiltered...
r18014 @repofilecache('dirstate')
Matt Mackall
localrepo: use propertycache
r8260 def dirstate(self):
Matt Mackall
dirstate: warn on invalid parents rather than aborting...
r13032 warned = [0]
def validate(node):
try:
Alexander Solovyov
remove unused imports and variables
r14064 self.changelog.rev(node)
Matt Mackall
dirstate: warn on invalid parents rather than aborting...
r13032 return node
except error.LookupError:
if not warned[0]:
warned[0] = True
self.ui.warn(_("warning: ignoring unknown"
Martin Geisler
localrepo: move string formatting out of gettext call
r13037 " working parent %s!\n") % short(node))
Matt Mackall
dirstate: warn on invalid parents rather than aborting...
r13032 return nullid
return dirstate.dirstate(self.opener, self.ui, self.root, validate)
Vadim Gelfer
support hooks written in python....
r2155
Matt Mackall
use repo[changeid] to get a changectx
r6747 def __getitem__(self, changeid):
Martin Geisler
use 'x is None' instead of 'x == None'...
r8527 if changeid is None:
Matt Mackall
use repo[changeid] to get a changectx
r6747 return context.workingctx(self)
return context.changectx(self, changeid)
Alexander Solovyov
localrepo: support 'rev in repo' syntax
r9924 def __contains__(self, changeid):
try:
return bool(self.lookup(changeid))
except error.RepoLookupError:
return False
Matt Mackall
add __len__ and __iter__ methods to repo and revlog
r6750 def __nonzero__(self):
return True
def __len__(self):
return len(self.changelog)
def __iter__(self):
Pierre-Yves David
clfilter: remove usage of `range` in favor of iteration over changelog...
r17675 return iter(self.changelog)
Vadim Gelfer
support hooks written in python....
r2155
Matt Mackall
localrepo: add revs helper method
r15403 def revs(self, expr, *args):
'''Return a list of revisions matching the given revset'''
expr = revset.formatspec(expr, *args)
m = revset.match(None, expr)
Pierre-Yves David
clfilter: remove usage of `range` in favor of iteration over changelog...
r17675 return [r for r in m(self, list(self))]
Matt Mackall
localrepo: add revs helper method
r15403
Matt Mackall
localrepo: add set method to iterate over a given revset...
r14902 def set(self, expr, *args):
'''
Yield a context for each matching revision, after doing arg
Matt Mackall
localrepo: fix comment on set
r14904 replacement via revset.formatspec
Matt Mackall
localrepo: add set method to iterate over a given revset...
r14902 '''
Matt Mackall
localrepo: add revs helper method
r15403 for r in self.revs(expr, *args):
Matt Mackall
localrepo: add set method to iterate over a given revset...
r14902 yield self[r]
Vadim Gelfer
hooks: add url to changegroup, incoming, prechangegroup, pretxnchangegroup hooks...
r2673 def url(self):
return 'file:' + self.root
Vadim Gelfer
make hook code nicer....
r1718 def hook(self, name, throw=False, **args):
Matt Mackall
hooks: separate hook code into a separate module
r4622 return hook.hook(self.ui, self, name, throw, **args)
mpm@selenic.com
Break apart hg.py...
r1089
Pierre-Yves David
clfilter: rename `unfilteredmeth` to `unfilteredmethod`...
r18016 @unfilteredmethod
Matt Mackall
tag: drop unused use_dirstate and parent from _tag()
r8402 def _tag(self, names, node, message, local, user, date, extra={}):
John Coomes
tag: allow multiple tags to be added or removed...
r6321 if isinstance(names, str):
names = (names,)
Brendan Cully
Break core of repo.tag into dirstate/hook-free repo._tag for convert-repo
r4118
Nicolas Dumazet
tag: warn users about tag/branch possible name conflicts...
r11063 branches = self.branchmap()
John Coomes
tag: allow multiple tags to be added or removed...
r6321 for name in names:
self.hook('pretag', throw=True, node=hex(node), tag=name,
local=local)
Nicolas Dumazet
tag: warn users about tag/branch possible name conflicts...
r11063 if name in branches:
self.ui.warn(_("warning: tag %s conflicts with existing"
" branch name\n") % name)
Brendan Cully
Break core of repo.tag into dirstate/hook-free repo._tag for convert-repo
r4118
John Coomes
tag: allow multiple tags to be added or removed...
r6321 def writetags(fp, names, munge, prevtags):
Alexis S. L. Carvalho
localrepo._tag: add a seek before writing the new tag...
r5985 fp.seek(0, 2)
Bryan O'Sullivan
tag: handle .hgtags and .hg/localtags with missing final newline (issue 601)...
r4932 if prevtags and prevtags[-1] != '\n':
fp.write('\n')
John Coomes
tag: allow multiple tags to be added or removed...
r6321 for name in names:
Matt Mackall
tag: record tag we're superseding, if any (issue 1102)
r6671 m = munge and munge(name) or name
Brodie Rao
cleanup: eradicate long lines
r16683 if (self._tagscache.tagtypes and
name in self._tagscache.tagtypes):
Idan Kamara
localrepo: unify tag related info into a tagscache class
r14936 old = self.tags().get(name, nullid)
Matt Mackall
tag: record tag we're superseding, if any (issue 1102)
r6671 fp.write('%s %s\n' % (hex(old), m))
fp.write('%s %s\n' % (hex(node), m))
Bryan O'Sullivan
tag: handle .hgtags and .hg/localtags with missing final newline (issue 601)...
r4932 fp.close()
Thomas Arendsen Hein
Remove trailing spaces
r5081
Bryan O'Sullivan
tag: handle .hgtags and .hg/localtags with missing final newline (issue 601)...
r4932 prevtags = ''
Brendan Cully
Break core of repo.tag into dirstate/hook-free repo._tag for convert-repo
r4118 if local:
Bryan O'Sullivan
tag: handle .hgtags and .hg/localtags with missing final newline (issue 601)...
r4932 try:
fp = self.opener('localtags', 'r+')
Peter Arrenbrecht
cleanup: drop unused assignments
r7875 except IOError:
Bryan O'Sullivan
tag: handle .hgtags and .hg/localtags with missing final newline (issue 601)...
r4932 fp = self.opener('localtags', 'a')
else:
prevtags = fp.read()
Brendan Cully
Break core of repo.tag into dirstate/hook-free repo._tag for convert-repo
r4118 # local tags are stored in the current charset
John Coomes
tag: allow multiple tags to be added or removed...
r6321 writetags(fp, names, None, prevtags)
for name in names:
self.hook('tag', node=hex(node), tag=name, local=local)
Brendan Cully
Break core of repo.tag into dirstate/hook-free repo._tag for convert-repo
r4118 return
Matt Mackall
tag: drop unused use_dirstate and parent from _tag()
r8402 try:
fp = self.wfile('.hgtags', 'rb+')
Idan Kamara
localrepo: don't attempt to open .hgtags twice if the error isn't ENOENT
r14646 except IOError, e:
if e.errno != errno.ENOENT:
raise
Matt Mackall
tag: drop unused use_dirstate and parent from _tag()
r8402 fp = self.wfile('.hgtags', 'ab')
Bryan O'Sullivan
tag: handle .hgtags and .hg/localtags with missing final newline (issue 601)...
r4932 else:
Matt Mackall
tag: drop unused use_dirstate and parent from _tag()
r8402 prevtags = fp.read()
Bryan O'Sullivan
tag: handle .hgtags and .hg/localtags with missing final newline (issue 601)...
r4932
Brendan Cully
Break core of repo.tag into dirstate/hook-free repo._tag for convert-repo
r4118 # committed tags are stored in UTF-8
Matt Mackall
move encoding bits from util to encoding...
r7948 writetags(fp, names, encoding.fromlocal, prevtags)
Bryan O'Sullivan
tag: handle .hgtags and .hg/localtags with missing final newline (issue 601)...
r4932
Dan Villiom Podlaski Christiansen
explicitly close files...
r13400 fp.close()
Mads Kiilerich
tag: invalidate tag cache immediately after adding new tag (issue3210)...
r15929 self.invalidatecaches()
Matt Mackall
tag: drop unused use_dirstate and parent from _tag()
r8402 if '.hgtags' not in self.dirstate:
Dirkjan Ochtman
move working dir/dirstate methods from localrepo to workingctx
r11303 self[None].add(['.hgtags'])
Brendan Cully
Break core of repo.tag into dirstate/hook-free repo._tag for convert-repo
r4118
Benoit Boissinot
style: use consistent variable names (*mod) with imports which would shadow
r10651 m = matchmod.exact(self.root, '', ['.hgtags'])
Matt Mackall
commit: drop the now-unused files parameter
r8706 tagnode = self.commit(message, user, date, extra=extra, match=m)
Brendan Cully
Break core of repo.tag into dirstate/hook-free repo._tag for convert-repo
r4118
John Coomes
tag: allow multiple tags to be added or removed...
r6321 for name in names:
self.hook('tag', node=hex(node), tag=name, local=local)
Brendan Cully
Break core of repo.tag into dirstate/hook-free repo._tag for convert-repo
r4118
return tagnode
John Coomes
tag: allow multiple tags to be added or removed...
r6321 def tag(self, names, node, message, local, user, date):
'''tag a revision with one or more symbolic names.
Vadim Gelfer
move most of tag code to localrepository class.
r2601
John Coomes
tag: allow multiple tags to be added or removed...
r6321 names is a list of strings or, when adding a single tag, names may be a
string.
Thomas Arendsen Hein
tab/space cleanup
r6334
John Coomes
tag: allow multiple tags to be added or removed...
r6321 if local is True, the tags are stored in a per-repository file.
otherwise, they are stored in the .hgtags file, and a new
Vadim Gelfer
move most of tag code to localrepository class.
r2601 changeset is committed with the change.
keyword arguments:
John Coomes
tag: allow multiple tags to be added or removed...
r6321 local: whether to store tags in non-version-controlled file
Vadim Gelfer
move most of tag code to localrepository class.
r2601 (default False)
message: commit message to use if committing
user: name of user to use if committing
date: date tuple to use if committing'''
Kevin Bullock
tag: don't check .hgtags status if --local passed...
r13133 if not local:
for x in self.status()[:5]:
if '.hgtags' in x:
raise util.Abort(_('working copy of .hgtags is changed '
'(please commit .hgtags manually)'))
Vadim Gelfer
move most of tag code to localrepository class.
r2601
Matt Mackall
tag: force load of tag cache
r7814 self.tags() # instantiate the cache
John Coomes
tag: allow multiple tags to be added or removed...
r6321 self._tag(names, node, message, local, user, date)
Vadim Gelfer
move most of tag code to localrepository class.
r2601
Pierre-Yves David
clfilter: add a propertycache that must be unfiltered...
r18013 @filteredpropertycache
Idan Kamara
localrepo: unify tag related info into a tagscache class
r14936 def _tagscache(self):
Brodie Rao
cleanup: eradicate long lines
r16683 '''Returns a tagscache object that contains various tags related
caches.'''
Idan Kamara
localrepo: unify tag related info into a tagscache class
r14936
# This simplifies its cache management by having one decorated
# function (this one) and the rest simply fetch things from it.
class tagscache(object):
def __init__(self):
# These two define the set of tags for this repository. tags
# maps tag name to node; tagtypes maps tag name to 'global' or
# 'local'. (Global tags are defined by .hgtags across all
# heads, and local tags are defined in .hg/localtags.)
# They constitute the in-memory cache of tags.
self.tags = self.tagtypes = None
self.nodetagscache = self.tagslist = None
cache = tagscache()
cache.tags, cache.tagtypes = self._findtags()
return cache
mpm@selenic.com
Break apart hg.py...
r1089 def tags(self):
'''return a mapping of tag to node'''
Matt Mackall
tags: defer tag validation until repo.tags() is called...
r16371 t = {}
Pierre-Yves David
clfilter: do not use tags cache if there are filtered changesets...
r17715 if self.changelog.filteredrevs:
tags, tt = self._findtags()
else:
tags = self._tagscache.tags
for k, v in tags.iteritems():
Matt Mackall
tags: defer tag validation until repo.tags() is called...
r16371 try:
# ignore tags to unknown nodes
self.changelog.rev(v)
t[k] = v
Bryan O'Sullivan
parsers: strictly check for 20-byte hashes where they're required
r16679 except (error.LookupError, ValueError):
Matt Mackall
tags: defer tag validation until repo.tags() is called...
r16371 pass
return t
Matt Mackall
Refactor tags code to prepare for improving the algorithm
r4210
Greg Ward
localrepo: factor _findtags() out of tags() (issue548)....
r9145 def _findtags(self):
'''Do the hard work of finding tags. Return a pair of dicts
(tags, tagtypes) where tags maps tag name to node, and tagtypes
maps tag name to a string like \'global\' or \'local\'.
Subclasses or extensions are free to add their own tags, but
should be aware that the returned dicts will be retained for the
duration of the localrepo object.'''
# XXX what tagtype should subclasses/extensions use? Currently
# mq and bookmarks add tags, but do not set the tagtype at all.
# Should each extension invent its own tag type? Should there
# be one tagtype for all such "virtual" tags? Or is the status
# quo fine?
Matt Mackall
Refactor tags code to prepare for improving the algorithm
r4210
Greg Ward
localrepo: factor updatetags() out of readtags() (issue548).
r9148 alltags = {} # map tag name to (node, hist)
Osku Salerma
Properly check tag's existence as a local/global tag when removing it.
r5657 tagtypes = {}
mpm@selenic.com
Break apart hg.py...
r1089
Benoit Boissinot
style: use consistent variable names (*mod) with imports which would shadow
r10651 tagsmod.findglobaltags(self.ui, self, alltags, tagtypes)
tagsmod.readlocaltags(self.ui, self, alltags, tagtypes)
Osku Salerma
Properly check tag's existence as a local/global tag when removing it.
r5657
Greg Ward
tags: support 'instant' tag retrieval (issue548)...
r9152 # Build the return dicts. Have to re-encode tag names because
# the tags module always uses UTF-8 (in order not to lose info
# writing to the cache), but the rest of Mercurial wants them in
# local encoding.
Greg Ward
localrepo: factor _findtags() out of tags() (issue548)....
r9145 tags = {}
Greg Ward
localrepo: improve readability of _findtags(), readtags() (issue548)....
r9147 for (name, (node, hist)) in alltags.iteritems():
if node != nullid:
Matt Mackall
tags: defer tag validation until repo.tags() is called...
r16371 tags[encoding.tolocal(name)] = node
Greg Ward
localrepo: factor _findtags() out of tags() (issue548)....
r9145 tags['tip'] = self.changelog.tip()
Greg Ward
tags: support 'instant' tag retrieval (issue548)...
r9152 tagtypes = dict([(encoding.tolocal(name), value)
for (name, value) in tagtypes.iteritems()])
Greg Ward
localrepo: factor _findtags() out of tags() (issue548)....
r9145 return (tags, tagtypes)
mpm@selenic.com
Break apart hg.py...
r1089
Osku Salerma
Properly check tag's existence as a local/global tag when removing it.
r5657 def tagtype(self, tagname):
'''
return the type of the given tag. result can be:
'local' : a local tag
'global' : a global tag
None : tag does not exist
'''
Idan Kamara
localrepo: unify tag related info into a tagscache class
r14936 return self._tagscache.tagtypes.get(tagname)
Osku Salerma
Properly check tag's existence as a local/global tag when removing it.
r5657
mpm@selenic.com
Break apart hg.py...
r1089 def tagslist(self):
'''return a list of tags ordered by revision'''
Idan Kamara
localrepo: unify tag related info into a tagscache class
r14936 if not self._tagscache.tagslist:
l = []
for t, n in self.tags().iteritems():
r = self.changelog.rev(n)
l.append((r, t, n))
self._tagscache.tagslist = [(t, n) for r, t, n in sorted(l)]
return self._tagscache.tagslist
mpm@selenic.com
Break apart hg.py...
r1089
def nodetags(self, node):
'''return the tags associated with a node'''
Idan Kamara
localrepo: unify tag related info into a tagscache class
r14936 if not self._tagscache.nodetagscache:
nodetagscache = {}
Matt Mackall
tags: defer tag validation until repo.tags() is called...
r16371 for t, n in self._tagscache.tags.iteritems():
Idan Kamara
localrepo: unify tag related info into a tagscache class
r14936 nodetagscache.setdefault(n, []).append(t)
for tags in nodetagscache.itervalues():
Eric Eisner
tags: return tags in sorted order...
r11047 tags.sort()
Idan Kamara
localrepo: unify tag related info into a tagscache class
r14936 self._tagscache.nodetagscache = nodetagscache
return self._tagscache.nodetagscache.get(node, [])
mpm@selenic.com
Break apart hg.py...
r1089
David Soria Parra
context: add method to return all bookmarks pointing to a node
r13384 def nodebookmarks(self, node):
marks = []
for bookmark, n in self._bookmarks.iteritems():
if n == node:
marks.append(bookmark)
return sorted(marks)
Georg Brandl
localrepo: introduce method for explicit branch cache update...
r12066 def branchmap(self):
'''returns a dictionary {branch: [branchheads]}'''
Pierre-Yves David
branchmap: enable caching for filtered version too...
r18189 branchmap.updatecache(self)
return self._branchcaches[self.filtername]
Pierre-Yves David
clfilter: do not use branchmap cache if there are filtered changesets...
r17714
John Mulligan
store all heads of a branch in the branch cache...
r7654
Brodie Rao
localrepo: add branchtip() method for faster single-branch lookups...
r16719 def _branchtip(self, heads):
'''return the tipmost branch head in heads'''
tip = heads[-1]
for h in reversed(heads):
Brodie Rao
context: add changectx.closesbranch() method...
r16720 if not self[h].closesbranch():
Brodie Rao
localrepo: add branchtip() method for faster single-branch lookups...
r16719 tip = h
break
return tip
def branchtip(self, branch):
'''return the tip node for a given branch'''
if branch not in self.branchmap():
raise error.RepoLookupError(_("unknown branch '%s'") % branch)
return self._branchtip(self.branchmap()[branch])
John Mulligan
store all heads of a branch in the branch cache...
r7654 def branchtags(self):
'''return a dict where branch names map to the tipmost head of
John Mulligan
branch closing: referencing open and closed branches/heads...
r7656 the branch, open heads come before closed'''
bt = {}
Benoit Boissinot
localrepo/branchcache: remove lbranchmap(), convert users to use utf-8 names...
r9675 for bn, heads in self.branchmap().iteritems():
Brodie Rao
localrepo: add branchtip() method for faster single-branch lookups...
r16719 bt[bn] = self._branchtip(heads)
John Mulligan
branch closing: referencing open and closed branches/heads...
r7656 return bt
mpm@selenic.com
Break apart hg.py...
r1089 def lookup(self, key):
Matt Mackall
localrepo: lookup now goes through context
r16378 return self[key].node()
mpm@selenic.com
Break apart hg.py...
r1089
Steve Losh
commands: add more robust support for 'hg log -b' (issue2078)...
r10960 def lookupbranch(self, key, remote=None):
repo = remote or self
if key in repo.branchmap():
return key
repo = (remote and remote.local()) and remote or self
return repo[key].branch()
Peter Arrenbrecht
wireproto: add known([id]) function...
r13723 def known(self, nodes):
nm = self.changelog.nodemap
Patrick Mezard
phases: introduce phasecache...
r16657 pc = self._phasecache
Pierre-Yves David
phases: make secret changeset undiscoverable in all case...
r15889 result = []
for n in nodes:
r = nm.get(n)
Patrick Mezard
phases: introduce phasecache...
r16657 resp = not (r is None or pc.phase(self, r) >= phases.secret)
Pierre-Yves David
phases: make secret changeset undiscoverable in all case...
r15889 result.append(resp)
return result
Peter Arrenbrecht
wireproto: add known([id]) function...
r13723
mpm@selenic.com
Break apart hg.py...
r1089 def local(self):
Matt Mackall
localrepo: local() returns self...
r14603 return self
mpm@selenic.com
Break apart hg.py...
r1089
Peter Arrenbrecht
peer: introduce real peer classes...
r17192 def cancopy(self):
return self.local() # so statichttprepo's override of local() works
mpm@selenic.com
Break apart hg.py...
r1089 def join(self, f):
return os.path.join(self.path, f)
def wjoin(self, f):
return os.path.join(self.root, f)
def file(self, f):
Thomas Arendsen Hein
Cleanup of indentation, spacing, newlines, strings and line length
r1615 if f[0] == '/':
f = f[1:]
Matt Mackall
revlog: simplify revlog version handling...
r4258 return filelog.filelog(self.sopener, f)
mpm@selenic.com
Break apart hg.py...
r1089
Matt Mackall
context: avoid using None for working parent
r6739 def changectx(self, changeid):
Matt Mackall
use repo[changeid] to get a changectx
r6747 return self[changeid]
Matt Mackall
merge: use new working context object in update
r3218
Matt Mackall
Add localrepo.parents to get parent changectxs.
r3163 def parents(self, changeid=None):
Matt Mackall
context: clean up parents()
r6742 '''get list of changectxs for parents of changeid'''
Matt Mackall
use repo[changeid] to get a changectx
r6747 return self[changeid].parents()
Matt Mackall
Add localrepo.parents to get parent changectxs.
r3163
Patrick Mezard
localrepo: add setparents() to adjust dirstate copies (issue3407)...
r16551 def setparents(self, p1, p2=nullid):
copies = self.dirstate.setparents(p1, p2)
Matt Mackall
setparents: drop copies from dropped p2 (issue3843)
r18739 pctx = self[p1]
Patrick Mezard
localrepo: add setparents() to adjust dirstate copies (issue3407)...
r16551 if copies:
# Adjust copy records, the dirstate cannot do it, it
# requires access to parents manifests. Preserve them
# only for entries added to first parent.
for f in copies:
if f not in pctx and copies[f] in pctx:
self.dirstate.copy(copies[f], f)
Matt Mackall
setparents: drop copies from dropped p2 (issue3843)
r18739 if p2 == nullid:
for f, s in sorted(self.dirstate.copies().items()):
if f not in pctx and s not in pctx:
self.dirstate.copy(None, f)
Patrick Mezard
localrepo: add setparents() to adjust dirstate copies (issue3407)...
r16551
Matt Mackall
Add context helper functions to localrepo
r2564 def filectx(self, path, changeid=None, fileid=None):
"""changeid can be a changeset revision, node, or tag.
fileid can be a file revision or node."""
return context.filectx(self, path, changeid, fileid)
mpm@selenic.com
Break apart hg.py...
r1089 def getcwd(self):
return self.dirstate.getcwd()
Alexis S. L. Carvalho
Add dirstate.pathto and localrepo.pathto....
r4525 def pathto(self, f, cwd=None):
return self.dirstate.pathto(f, cwd)
mpm@selenic.com
Break apart hg.py...
r1089 def wfile(self, f, mode='r'):
return self.wopener(f, mode)
Alexis S. L. Carvalho
use os.path.islink instead of util.is_link; remove util.is_link
r4275 def _link(self, f):
FUJIWARA Katsunori
localrepo: use "vfs.islink()" instead of "os.path.islink()"
r18949 return self.wvfs.islink(f)
Alexis S. L. Carvalho
use os.path.islink instead of util.is_link; remove util.is_link
r4275
Nicolas Dumazet
localrepo: refactor filter computation...
r11698 def _loadfilter(self, filter):
Matt Mackall
unify encode/decode filter routines
r4004 if filter not in self.filterpats:
mpm@selenic.com
Add file encoding/decoding support
r1258 l = []
Matt Mackall
unify encode/decode filter routines
r4004 for pat, cmd in self.ui.configitems(filter):
Mads Kiilerich
Make it possible to disable filtering for a pattern....
r7226 if cmd == '!':
continue
Benoit Boissinot
style: use consistent variable names (*mod) with imports which would shadow
r10651 mf = matchmod.match(self.root, '', [pat])
Patrick Mezard
Register data filters in a localrepo instead of util...
r5966 fn = None
Jesse Glick
Strip filter name from command before passing to filter function....
r6066 params = cmd
Patrick Mezard
Register data filters in a localrepo instead of util...
r5966 for name, filterfn in self._datafilters.iteritems():
Thomas Arendsen Hein
Removed trailing spaces from everything except test output
r6210 if cmd.startswith(name):
Patrick Mezard
Register data filters in a localrepo instead of util...
r5966 fn = filterfn
Jesse Glick
Strip filter name from command before passing to filter function....
r6066 params = cmd[len(name):].lstrip()
Patrick Mezard
Register data filters in a localrepo instead of util...
r5966 break
if not fn:
Jesse Glick
Provide better context for custom Python encode/decode filters....
r5967 fn = lambda s, c, **kwargs: util.filter(s, c)
# Wrap old filters not supporting keyword arguments
if not inspect.getargspec(fn)[2]:
oldfn = fn
fn = lambda s, c, **kwargs: oldfn(s, c)
Jesse Glick
Strip filter name from command before passing to filter function....
r6066 l.append((mf, fn, params))
Matt Mackall
unify encode/decode filter routines
r4004 self.filterpats[filter] = l
Nicolas Dumazet
localrepo: have _loadfilter return the loaded filter patterns
r12706 return self.filterpats[filter]
mpm@selenic.com
Add file encoding/decoding support
r1258
Nicolas Dumazet
localrepo: load filter patterns outside of _filter
r12707 def _filter(self, filterpats, filename, data):
for mf, fn, cmd in filterpats:
mpm@selenic.com
Add file encoding/decoding support
r1258 if mf(filename):
Martin Geisler
do not attempt to translate ui.debug output
r9467 self.ui.debug("filtering %s through %s\n" % (filename, cmd))
Jesse Glick
Provide better context for custom Python encode/decode filters....
r5967 data = fn(data, cmd, ui=self.ui, repo=self, filename=filename)
mpm@selenic.com
Add file encoding/decoding support
r1258 break
return data
mpm@selenic.com
Break apart hg.py...
r1089
Pierre-Yves David
clfilter: add a propertycache that must be unfiltered...
r18013 @unfilteredpropertycache
Nicolas Dumazet
localrepo: use propertycaches to access encode/decode filters
r12708 def _encodefilterpats(self):
return self._loadfilter('encode')
Pierre-Yves David
clfilter: add a propertycache that must be unfiltered...
r18013 @unfilteredpropertycache
Nicolas Dumazet
localrepo: use propertycaches to access encode/decode filters
r12708 def _decodefilterpats(self):
return self._loadfilter('decode')
Patrick Mezard
Register data filters in a localrepo instead of util...
r5966 def adddatafilter(self, name, filter):
self._datafilters[name] = filter
Matt Mackall
unify encode/decode filter routines
r4004 def wread(self, filename):
if self._link(filename):
FUJIWARA Katsunori
localrepo: use "vfs.readlink()" instead of "os.readlink()"
r18950 data = self.wvfs.readlink(filename)
Matt Mackall
unify encode/decode filter routines
r4004 else:
Dan Villiom Podlaski Christiansen
prevent transient leaks of file handle by using new helper functions...
r14168 data = self.wopener.read(filename)
Nicolas Dumazet
localrepo: use propertycaches to access encode/decode filters
r12708 return self._filter(self._encodefilterpats, filename, data)
mpm@selenic.com
Add file encoding/decoding support
r1258
Matt Mackall
symlinks: add flags param to wwrite...
r4006 def wwrite(self, filename, data, flags):
Nicolas Dumazet
localrepo: use propertycaches to access encode/decode filters
r12708 data = self._filter(self._decodefilterpats, filename, data)
Matt Mackall
util: set_flags shouldn't know about repo flag formats
r6877 if 'l' in flags:
self.wopener.symlink(data, filename)
else:
Sune Foldager
fix errors reported by pyflakes test
r14184 self.wopener.write(filename, data)
Matt Mackall
util: set_flags shouldn't know about repo flag formats
r6877 if 'x' in flags:
FUJIWARA Katsunori
localrepo: use "vfs.setflags()" instead of "util.setflags()"
r18951 self.wvfs.setflags(filename, False, True)
mpm@selenic.com
Add file encoding/decoding support
r1258
Matt Mackall
replace filehandle version of wwrite with wwritedata
r4005 def wwritedata(self, filename, data):
Nicolas Dumazet
localrepo: use propertycaches to access encode/decode filters
r12708 return self._filter(self._decodefilterpats, filename, data)
mpm@selenic.com
Break apart hg.py...
r1089
Steve Borho
localrepo: add desc parameter to transaction...
r10881 def transaction(self, desc):
Henrik Stuart
transaction: support multiple, separate transactions...
r8072 tr = self._transref and self._transref() or None
if tr and tr.running():
return tr.nest()
mason@suse.com
Automatic nesting into running transactions in the same repository....
r1806
Matt Mackall
transactions: don't show a backtrace when journal exists...
r5865 # abort here if the journal already exists
FUJIWARA Katsunori
localrepo: use "vfs.exists()" instead of "os.path.exists()"
r18947 if self.svfs.exists("journal"):
Matt Mackall
many, many trivial check-code fixups
r10282 raise error.RepoError(
_("abandoned transaction found - run hg recover"))
Matt Mackall
transactions: don't show a backtrace when journal exists...
r5865
Idan Kamara
localrepo: refactor retrieving of journal/undo files paths...
r16236 self._writejournal(desc)
FUJIWARA Katsunori
localrepo: use "vfs.rename()" instead of "util.rename()"...
r18952 renames = [(vfs, x, undoname(x)) for vfs, x in self._journalfiles()]
Alexander Solovyov
fix bookmarks rollback behavior...
r14266
tr = transaction.transaction(self.ui.warn, self.sopener,
self.sjoin("journal"),
aftertrans(renames),
self.store.createmode)
self._transref = weakref.ref(tr)
return tr
Idan Kamara
localrepo: refactor retrieving of journal/undo files paths...
r16236 def _journalfiles(self):
FUJIWARA Katsunori
localrepo: use "vfs.rename()" instead of "util.rename()"...
r18952 return ((self.svfs, 'journal'),
(self.vfs, 'journal.dirstate'),
(self.vfs, 'journal.branch'),
(self.vfs, 'journal.desc'),
(self.vfs, 'journal.bookmarks'),
(self.svfs, 'journal.phaseroots'))
Idan Kamara
localrepo: refactor retrieving of journal/undo files paths...
r16236
def undofiles(self):
FUJIWARA Katsunori
localrepo: use "vfs.rename()" instead of "util.rename()"...
r18952 return [vfs.join(undoname(x)) for vfs, x in self._journalfiles()]
Idan Kamara
localrepo: refactor retrieving of journal/undo files paths...
r16236
Alexander Solovyov
fix bookmarks rollback behavior...
r14266 def _writejournal(self, desc):
Matt Mackall
journal: use tryread helper to backup files (issue3375)
r16456 self.opener.write("journal.dirstate",
self.opener.tryread("dirstate"))
Dan Villiom Podlaski Christiansen
prevent transient leaks of file handle by using new helper functions...
r14168 self.opener.write("journal.branch",
encoding.fromlocal(self.dirstate.branch()))
self.opener.write("journal.desc",
"%d\n%s\n" % (len(self), desc))
Matt Mackall
journal: use tryread helper to backup files (issue3375)
r16456 self.opener.write("journal.bookmarks",
self.opener.tryread("bookmarks"))
self.sopener.write("journal.phaseroots",
self.sopener.tryread("phaseroots"))
Alexander Solovyov
fix bookmarks rollback behavior...
r14266
mpm@selenic.com
Break apart hg.py...
r1089 def recover(self):
Ronny Pfannschmidt
switch lock releasing in the core from gc to explicit
r8109 lock = self.lock()
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 try:
FUJIWARA Katsunori
localrepo: use "vfs.exists()" instead of "os.path.exists()"
r18947 if self.svfs.exists("journal"):
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 self.ui.status(_("rolling back interrupted transaction\n"))
Matt Mackall
many, many trivial check-code fixups
r10282 transaction.rollback(self.sopener, self.sjoin("journal"),
self.ui.warn)
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 self.invalidate()
return True
else:
self.ui.warn(_("no interrupted transaction available\n"))
return False
finally:
Ronny Pfannschmidt
switch lock releasing in the core from gc to explicit
r8109 lock.release()
mpm@selenic.com
Break apart hg.py...
r1089
Greg Ward
rollback: avoid unsafe rollback when not at tip (issue2998)...
r15183 def rollback(self, dryrun=False, force=False):
Matt Mackall
Make repo locks recursive, eliminate all passing of lock/wlock
r4917 wlock = lock = None
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 try:
mason@suse.com
Allow callers to pass in the dirstate lock in most localrepo.py funcs....
r1712 wlock = self.wlock()
Eric Hopper
Fix hg import --exact bug that hangs hg on failure.
r4438 lock = self.lock()
FUJIWARA Katsunori
localrepo: use "vfs.exists()" instead of "os.path.exists()"
r18947 if self.svfs.exists("undo"):
Greg Ward
rollback: avoid unsafe rollback when not at tip (issue2998)...
r15183 return self._rollback(dryrun, force)
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 else:
self.ui.warn(_("no rollback information available\n"))
Matt Mackall
commands: initial audit of exit codes...
r11177 return 1
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 finally:
Ronny Pfannschmidt
switch lock releasing in the core from gc to explicit
r8109 release(lock, wlock)
mpm@selenic.com
Break apart hg.py...
r1089
Pierre-Yves David
clfilter: rename `unfilteredmeth` to `unfilteredmethod`...
r18016 @unfilteredmethod # Until we get smarter cache management
Greg Ward
rollback: avoid unsafe rollback when not at tip (issue2998)...
r15183 def _rollback(self, dryrun, force):
Greg Ward
rollback: refactor for readability; cosmetics....
r15130 ui = self.ui
Greg Ward
rollback: improve readability; clarify that the return value is an int.
r15097 try:
Greg Ward
rollback: refactor for readability; cosmetics....
r15130 args = self.opener.read('undo.desc').splitlines()
(oldlen, desc, detail) = (int(args[0]), args[1], None)
if len(args) >= 3:
detail = args[2]
oldtip = oldlen - 1
if detail and ui.verbose:
msg = (_('repository tip rolled back to revision %s'
' (undo %s: %s)\n')
% (oldtip, desc, detail))
else:
msg = (_('repository tip rolled back to revision %s'
' (undo %s)\n')
% (oldtip, desc))
Greg Ward
rollback: improve readability; clarify that the return value is an int.
r15097 except IOError:
Greg Ward
rollback: refactor for readability; cosmetics....
r15130 msg = _('rolling back unknown transaction\n')
Greg Ward
rollback: avoid unsafe rollback when not at tip (issue2998)...
r15183 desc = None
if not force and self['.'] != self['tip'] and desc == 'commit':
raise util.Abort(
_('rollback of last commit while not checked out '
Matt Mackall
rollback: use a hint for force
r15187 'may lose data'), hint=_('use -f to force'))
Greg Ward
rollback: avoid unsafe rollback when not at tip (issue2998)...
r15183
Greg Ward
rollback: refactor for readability; cosmetics....
r15130 ui.status(msg)
Greg Ward
rollback: improve readability; clarify that the return value is an int.
r15097 if dryrun:
return 0
Greg Ward
rollback: only restore dirstate and branch when appropriate....
r15131
parents = self.dirstate.parents()
Idan Kamara
localrepo: introduce destroying function
r18310 self.destroying()
Greg Ward
rollback: refactor for readability; cosmetics....
r15130 transaction.rollback(self.sopener, self.sjoin('undo'), ui.warn)
FUJIWARA Katsunori
localrepo: use "vfs.exists()" instead of "os.path.exists()"
r18947 if self.vfs.exists('undo.bookmarks'):
FUJIWARA Katsunori
localrepo: use "vfs.rename()" instead of "util.rename()"
r18948 self.vfs.rename('undo.bookmarks', 'bookmarks')
FUJIWARA Katsunori
localrepo: use "vfs.exists()" instead of "os.path.exists()"
r18947 if self.svfs.exists('undo.phaseroots'):
FUJIWARA Katsunori
localrepo: use "vfs.rename()" instead of "util.rename()"
r18948 self.svfs.rename('undo.phaseroots', 'phaseroots')
Greg Ward
rollback: improve readability; clarify that the return value is an int.
r15097 self.invalidate()
Greg Ward
rollback: only restore dirstate and branch when appropriate....
r15131
parentgone = (parents[0] not in self.changelog.nodemap or
parents[1] not in self.changelog.nodemap)
if parentgone:
FUJIWARA Katsunori
localrepo: use "vfs.rename()" instead of "util.rename()"
r18948 self.vfs.rename('undo.dirstate', 'dirstate')
Greg Ward
rollback: only restore dirstate and branch when appropriate....
r15131 try:
branch = self.opener.read('undo.branch')
Sune Foldager
rollback: write dirstate branch with correct encoding
r17360 self.dirstate.setbranch(encoding.tolocal(branch))
Greg Ward
rollback: only restore dirstate and branch when appropriate....
r15131 except IOError:
ui.warn(_('named branch could not be reset: '
'current branch is still \'%s\'\n')
% self.dirstate.branch())
self.dirstate.invalidate()
parents = tuple([p.rev() for p in self.parents()])
if len(parents) > 1:
ui.status(_('working directory now based on '
'revisions %d and %d\n') % parents)
else:
ui.status(_('working directory now based on '
'revision %d\n') % parents)
Joshua Redstone
strip: incrementally update the branchheads cache after a strip...
r17013 # TODO: if we know which new heads may result from this rollback, pass
# them to destroy(), which will prevent the branchhead cache from being
# invalidated.
Greg Ward
rollback: always call destroyed() (regression from 1.9)...
r15604 self.destroyed()
Greg Ward
rollback: improve readability; clarify that the return value is an int.
r15097 return 0
Benoit Boissinot
strip: invalidate all caches after stripping (fixes issue1951)...
r10547 def invalidatecaches(self):
Idan Kamara
localrepo: delete _phaserev when invalidating caches
r15988
Pierre-Yves David
clfilter: add a propertycache that must be unfiltered...
r18013 if '_tagscache' in vars(self):
# can't use delattr on proxy
del self.__dict__['_tagscache']
Idan Kamara
localrepo: unify tag related info into a tagscache class
r14936
Pierre-Yves David
branchmap: enable caching for filtered version too...
r18189 self.unfiltered()._branchcaches.clear()
Pierre-Yves David
cache: group obscache and revsfiltercache invalidation in a single function...
r18105 self.invalidatevolatilesets()
def invalidatevolatilesets(self):
self.filteredrevcache.clear()
Pierre-Yves David
obsolete: introduce caches for all meaningful sets...
r17469 obsolete.clearobscaches(self)
Benoit Boissinot
revalidate revlog data after locking the repo (issue132)
r1784
Idan Kamara
localrepo: decorate dirstate() with filecache...
r14930 def invalidatedirstate(self):
'''Invalidates the dirstate, causing the next call to dirstate
to check if it was modified since the last time it was read,
rereading it if it has.
This is different to dirstate.invalidate() that it doesn't always
rereads the dirstate. Use dirstate.invalidate() if you want to
explicitly read the dirstate again (i.e. restoring it to a previous
known good state).'''
Pierre-Yves David
clfilter: add a propertycache that must be unfiltered...
r18013 if hasunfilteredcache(self, 'dirstate'):
Idan Kamara
dirstate: add filecache support
r16200 for k in self.dirstate._filecache:
try:
delattr(self.dirstate, k)
except AttributeError:
pass
Pierre-Yves David
clfilter: ensure cache invalidation is done on the main unfiltered repo...
r17997 delattr(self.unfiltered(), 'dirstate')
Idan Kamara
localrepo: decorate dirstate() with filecache...
r14930
Benoit Boissinot
strip: invalidate all caches after stripping (fixes issue1951)...
r10547 def invalidate(self):
Mads Kiilerich
spelling: fix some minor issues found by spell checker
r18644 unfiltered = self.unfiltered() # all file caches are stored unfiltered
Idan Kamara
localrepo: make invalidate() walk _filecache
r14935 for k in self._filecache:
# dirstate is invalidated separately in invalidatedirstate()
if k == 'dirstate':
continue
try:
Pierre-Yves David
clfilter: ensure cache invalidation is done on the main unfiltered repo...
r17997 delattr(unfiltered, k)
Idan Kamara
localrepo: make invalidate() walk _filecache
r14935 except AttributeError:
pass
Benoit Boissinot
strip: invalidate all caches after stripping (fixes issue1951)...
r10547 self.invalidatecaches()
Matt Mackall
rename and simplify do_lock
r4913 def _lock(self, lockname, wait, releasefn, acquirefn, desc):
mpm@selenic.com
Break apart hg.py...
r1089 try:
Matt Mackall
localrepo: add separate methods for manipulating repository data...
r3457 l = lock.lock(lockname, 0, releasefn, desc=desc)
Matt Mackall
error: move lock errors...
r7640 except error.LockHeld, inst:
Benoit Boissinot
add localrepo.wlock for protecting the dirstate...
r1531 if not wait:
Vadim Gelfer
fix backtrace printed when cannot get lock....
r2016 raise
Thomas Arendsen Hein
Corrected "waiting for lock on repository FOO held by BAR" message....
r3688 self.ui.warn(_("waiting for lock on %s held by %r\n") %
(desc, inst.locker))
Vadim Gelfer
fix backtrace printed when cannot get lock....
r2016 # default to 600 seconds timeout
Matt Mackall
localrepo: add separate methods for manipulating repository data...
r3457 l = lock.lock(lockname, int(self.ui.config("ui", "timeout", "600")),
Vadim Gelfer
fix backtrace printed when cannot get lock....
r2016 releasefn, desc=desc)
Benoit Boissinot
localrepo: refactor the locking functions
r1751 if acquirefn:
acquirefn()
return l
Matt Mackall
localrepo: rename _postrelease to _afterlock
r15587 def _afterlock(self, callback):
Pierre-Yves David
lock: add mechanism to register post release callback
r15583 """add a callback to the current repository lock.
The callback will be executed on lock release."""
l = self._lockref and self._lockref()
Matt Mackall
localrepo: remove asserts in _afterlock
r15588 if l:
Matt Mackall
lock: change name of release chain
r15589 l.postrelease.append(callback)
Mads Kiilerich
tag: run commit hook when lock is released (issue3344)
r16680 else:
callback()
Pierre-Yves David
lock: add mechanism to register post release callback
r15583
Matt Mackall
repo locks: use True/False
r4914 def lock(self, wait=True):
Greg Ward
localrepo: document the locking scheme a little better...
r9309 '''Lock the repository store (.hg/store) and return a weak reference
to the lock. Use this before modifying the store (e.g. committing or
stripping). If you are opening a transaction, get a lock as well.)'''
Ronny Pfannschmidt
made repo locks recursive and deprecate refcounting based lock releasing...
r8108 l = self._lockref and self._lockref()
if l is not None and l.held:
l.lock()
return l
Matt Mackall
Make repo locks recursive, eliminate all passing of lock/wlock
r4917
Idan Kamara
localrepo: refresh filecache entries after releasing a repo.lock()
r14931 def unlock():
self.store.write()
Pierre-Yves David
clfilter: add a propertycache that must be unfiltered...
r18013 if hasunfilteredcache(self, '_phasecache'):
Patrick Mezard
phases: introduce phasecache...
r16657 self._phasecache.write()
Idan Kamara
localrepo: refresh filecache entries after releasing a repo.lock()
r14931 for k, ce in self._filecache.items():
Idan Kamara
localrepo: don't refresh filecache entries that aren't in __dict__...
r18309 if k == 'dirstate' or k not in self.__dict__:
Idan Kamara
localrepo: refresh filecache entries after releasing a repo.lock()
r14931 continue
ce.refresh()
l = self._lock(self.sjoin("lock"), wait, unlock,
Adrian Buehlmann
fncachestore: defer updating the fncache file to a single file open...
r13391 self.invalidate, _('repository %s') % self.origroot)
Matt Mackall
Make repo locks recursive, eliminate all passing of lock/wlock
r4917 self._lockref = weakref.ref(l)
return l
Benoit Boissinot
localrepo: refactor the locking functions
r1751
Matt Mackall
repo locks: use True/False
r4914 def wlock(self, wait=True):
Greg Ward
localrepo: document the locking scheme a little better...
r9309 '''Lock the non-store parts of the repository (everything under
.hg except .hg/store) and return a weak reference to the lock.
Use this before modifying files in .hg.'''
Ronny Pfannschmidt
made repo locks recursive and deprecate refcounting based lock releasing...
r8108 l = self._wlockref and self._wlockref()
if l is not None and l.held:
l.lock()
return l
Benoit Boissinot
add localrepo.wlock for protecting the dirstate...
r1531
Idan Kamara
localrepo: decorate dirstate() with filecache...
r14930 def unlock():
self.dirstate.write()
Idan Kamara
localrepo: drop unnecessary check on wlock unlock...
r18318 self._filecache['dirstate'].refresh()
Idan Kamara
localrepo: decorate dirstate() with filecache...
r14930
l = self._lock(self.join("wlock"), wait, unlock,
self.invalidatedirstate, _('working directory of %s') %
Matt Mackall
Make repo locks recursive, eliminate all passing of lock/wlock
r4917 self.origroot)
self._wlockref = weakref.ref(l)
return l
Benoit Boissinot
add localrepo.wlock for protecting the dirstate...
r1531
Matt Mackall
filecommit: swallow some bits from _commitctx, add _
r8401 def _filecommit(self, fctx, manifest1, manifest2, linkrev, tr, changelist):
Matt Mackall
merge: remember rename copies and parents properly on commit...
r3292 """
Matt Mackall
commit: unify file-level commit code
r3294 commit an individual file as part of a larger transaction
"""
Matt Mackall
merge: remember rename copies and parents properly on commit...
r3292
Martijn Pieters
localrepo: Refactor var names in filecommit to improve readability.
r8244 fname = fctx.path()
text = fctx.data()
flog = self.file(fname)
fparent1 = manifest1.get(fname, nullid)
Matt Mackall
filecommit: swallow some bits from _commitctx, add _
r8401 fparent2 = fparent2o = manifest2.get(fname, nullid)
Matt Mackall
Refactor excessive merge detection, add test
r1716
Matt Mackall
merge: remember rename copies and parents properly on commit...
r3292 meta = {}
Martijn Pieters
localrepo: Refactor var names in filecommit to improve readability.
r8244 copy = fctx.renamed()
if copy and copy[0] != fname:
Alexis S. L. Carvalho
filecommit: don't forget the local parent on a merge with a local rename
r4058 # Mark the new revision of this file as a copy of another
Thomas Arendsen Hein
Removed trailing whitespace and tabs from python files
r4516 # file. This copy data will effectively act as a parent
# of this new revision. If this is a merge, the first
Alexis S. L. Carvalho
filecommit: don't forget the local parent on a merge with a local rename
r4058 # parent will be the nullid (meaning "look up the copy data")
# and the second one will be the other parent. For example:
#
# 0 --- 1 --- 3 rev1 changes file foo
# \ / rev2 renames foo to bar and changes it
# \- 2 -/ rev3 should have bar with all changes and
# should record that bar descends from
# bar in rev2 and foo in rev1
#
# this allows this merge to succeed:
#
# 0 --- 1 --- 3 rev4 reverts the content change from rev2
# \ / merging rev3 and rev4 should use bar@rev2
# \- 2 --- 4 as the merge base
#
Matt Mackall
commit: simplify file copy logic
r6874
Martijn Pieters
localrepo: Refactor var names in filecommit to improve readability.
r8244 cfname = copy[0]
crev = manifest1.get(cfname)
newfparent = fparent2
Matt Mackall
commit: simplify file copy logic
r6874
if manifest2: # branch merge
Martijn Pieters
localrepo: Refactor var names in filecommit to improve readability.
r8244 if fparent2 == nullid or crev is None: # copied on remote side
if cfname in manifest2:
crev = manifest2[cfname]
newfparent = fparent1
Matt Mackall
commit: simplify file copy logic
r6874
Matt Mackall
add a fix for issue 1175...
r6875 # find source in nearest ancestor if we've lost track
Martijn Pieters
localrepo: Refactor var names in filecommit to improve readability.
r8244 if not crev:
Martin Geisler
do not attempt to translate ui.debug output
r9467 self.ui.debug(" %s: searching for copy revision for %s\n" %
Martijn Pieters
localrepo: Refactor var names in filecommit to improve readability.
r8244 (fname, cfname))
Matt Mackall
commit: search both parents for missing copy revision (issue2484)...
r13000 for ancestor in self[None].ancestors():
Martijn Pieters
localrepo: Refactor var names in filecommit to improve readability.
r8244 if cfname in ancestor:
crev = ancestor[cfname].filenode()
Matt Mackall
Merge with stable...
r6876 break
Matt Mackall
add a fix for issue 1175...
r6875
Matt Mackall
commit: search both parents for missing copy revision (issue2484)...
r13000 if crev:
self.ui.debug(" %s: copy %s:%s\n" % (fname, cfname, hex(crev)))
meta["copy"] = cfname
meta["copyrev"] = hex(crev)
fparent1, fparent2 = nullid, newfparent
else:
self.ui.warn(_("warning: can't find ancestor for '%s' "
"copied from '%s'!\n") % (fname, cfname))
Martijn Pieters
localrepo: Refactor var names in filecommit to improve readability.
r8244 elif fparent2 != nullid:
Matt Mackall
Refactor excessive merge detection, add test
r1716 # is one parent an ancestor of the other?
Martijn Pieters
localrepo: Refactor var names in filecommit to improve readability.
r8244 fparentancestor = flog.ancestor(fparent1, fparent2)
if fparentancestor == fparent1:
fparent1, fparent2 = fparent2, nullid
elif fparentancestor == fparent2:
fparent2 = nullid
Matt Mackall
Refactor excessive merge detection, add test
r1716
Matt Mackall
filecommit: swallow some bits from _commitctx, add _
r8401 # is the file changed?
if fparent2 != nullid or flog.cmp(fparent1, text) or meta:
changelist.append(fname)
return flog.add(text, meta, tr, linkrev, fparent1, fparent2)
Matt Mackall
Refactor excessive merge detection, add test
r1716
Matt Mackall
filecommit: swallow some bits from _commitctx, add _
r8401 # are just the flags changed during merge?
Henri Wiechers
localrepo: minor formatting - remove double space
r10320 if fparent1 != fparent2o and manifest1.flags(fname) != fctx.flags():
Matt Mackall
filecommit: swallow some bits from _commitctx, add _
r8401 changelist.append(fname)
return fparent1
Matt Mackall
Refactor excessive merge detection, add test
r1716
Pierre-Yves David
clfilter: rename `unfilteredmeth` to `unfilteredmethod`...
r18016 @unfilteredmethod
Matt Mackall
commit: drop the now-unused files parameter
r8706 def commit(self, text="", user=None, date=None, match=None, force=False,
editor=False, extra={}):
Benoit Boissinot
localrepo: update commit*() docstrings
r8515 """Add a new revision to current repository.
Matt Mackall
commit: drop the now-unused files parameter
r8706 Revision information is gathered from the working directory,
match can be used to filter the committed files. If editor is
supplied, it is called to get a commit message.
Benoit Boissinot
localrepo: update commit*() docstrings
r8515 """
Matt Mackall
commit: move explicit file checking into repo.commit
r8709
Matt Mackall
commit: move some setup outside the lock
r8715 def fail(f, msg):
raise util.Abort('%s: %s' % (f, msg))
if not match:
Benoit Boissinot
style: use consistent variable names (*mod) with imports which would shadow
r10651 match = matchmod.always(self.root, '')
Matt Mackall
commit: move some setup outside the lock
r8715
if not force:
vdirs = []
Siddharth Agarwal
localrepo.commit: hook into match.explicitdir
r19138 match.explicitdir = vdirs.append
Matt Mackall
commit: move some setup outside the lock
r8715 match.bad = fail
Matt Mackall
commit: push repo lock down into _commitctx
r8405 wlock = self.wlock()
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 try:
Matt Mackall
commit: recurse into subrepositories
r8813 wctx = self[None]
Benoit Boissinot
localrepo.commit: use explicit variables, avoid creating new contexts
r10970 merge = len(wctx.parents()) > 1
mpm@selenic.com
Break apart hg.py...
r1089
Benoit Boissinot
localrepo.commit: use explicit variables, avoid creating new contexts
r10970 if (not force and merge and match and
Matt Mackall
commit: some tidying...
r8501 (match.files() or match.anypats())):
Matt Mackall
remove deprecated rawcommit
r8397 raise util.Abort(_('cannot partially commit a merge '
'(do not specify files or patterns)'))
Patrick Mezard
localrepo: replace dirstate by workingfilectx in filecommit()
r6706
Matt Mackall
commit: drop the now-unused files parameter
r8706 changes = self.status(match=match, clean=force)
if force:
changes[0].extend(changes[6]) # mq may commit unchanged files
Benoit Boissinot
localrepo: factor commit and rawcommit...
r3621
Matt Mackall
commit: recurse into subrepositories
r8813 # check subrepos
subs = []
Matt Mackall
subrepo: rewrite handling of subrepo state at commit (issue2403)...
r16073 commitsubs = set()
newstate = wctx.substate.copy()
# only manage subrepos and .hgsubstate if .hgsub is present
Matt Mackall
subrepo: be more careful with deletions of .hgsub and .hgsubstate (issue2844)...
r14536 if '.hgsub' in wctx:
Matt Mackall
subrepo: rewrite handling of subrepo state at commit (issue2403)...
r16073 # we'll decide whether to track this ourselves, thanks
if '.hgsubstate' in changes[0]:
changes[0].remove('.hgsubstate')
if '.hgsubstate' in changes[2]:
changes[2].remove('.hgsubstate')
# compare current state to last committed state
# build new substate based on last committed state
oldstate = wctx.p1().substate
for s in sorted(newstate.keys()):
if not match(s):
# ignore working copy, use old state if present
if s in oldstate:
newstate[s] = oldstate[s]
continue
if not force:
raise util.Abort(
_("commit with new subrepo %s excluded") % s)
if wctx.sub(s).dirty(True):
if not self.ui.configbool('ui', 'commitsubrepos'):
raise util.Abort(
_("uncommitted changes in subrepo %s") % s,
hint=_("use --subrepos for recursive commit"))
subs.append(s)
commitsubs.add(s)
else:
bs = wctx.sub(s).basestate()
newstate[s] = (newstate[s][0], bs, newstate[s][2])
if oldstate.get(s, (None, None, None))[1] != bs:
subs.append(s)
# check for removed subrepos
Matt Mackall
subrepo: be more careful with deletions of .hgsub and .hgsubstate (issue2844)...
r14536 for p in wctx.parents():
Matt Mackall
subrepo: rewrite handling of subrepo state at commit (issue2403)...
r16073 r = [s for s in p.substate if s not in newstate]
subs += [s for s in r if match(s)]
if subs:
Matt Mackall
subrepo: be more careful with deletions of .hgsub and .hgsubstate (issue2844)...
r14536 if (not match('.hgsub') and
'.hgsub' in (wctx.modified() + wctx.added())):
raise util.Abort(
_("can't commit subrepos without .hgsub"))
Matt Mackall
subrepo: rewrite handling of subrepo state at commit (issue2403)...
r16073 changes[0].insert(0, '.hgsubstate')
Matt Mackall
subrepo: be more careful with deletions of .hgsub and .hgsubstate (issue2844)...
r14536 elif '.hgsub' in changes[2]:
# clean up .hgsubstate when .hgsub is removed
if ('.hgsubstate' in wctx and
'.hgsubstate' not in changes[0] + changes[1] + changes[2]):
changes[2].insert(0, '.hgsubstate')
Matt Mackall
commit: recurse into subrepositories
r8813
Matt Mackall
commit: move explicit file checking into repo.commit
r8709 # make sure all explicit patterns are matched
if not force and match.files():
Matt Mackall
commit: trade O(n^2) file checks for O(n^2) dir checks
r8710 matched = set(changes[0] + changes[1] + changes[2])
Matt Mackall
commit: move explicit file checking into repo.commit
r8709
for f in match.files():
Matt Mackall
commit: normalize filenames when checking explicit files (issue3576)
r17378 f = self.dirstate.normalize(f)
Matt Mackall
commit: recurse into subrepositories
r8813 if f == '.' or f in matched or f in wctx.substate:
Matt Mackall
commit: move explicit file checking into repo.commit
r8709 continue
if f in changes[3]: # missing
fail(f, _('file not found!'))
if f in vdirs: # visited directory
d = f + '/'
Matt Mackall
commit: trade O(n^2) file checks for O(n^2) dir checks
r8710 for mf in matched:
if mf.startswith(d):
break
else:
Matt Mackall
commit: move explicit file checking into repo.commit
r8709 fail(f, _("no match under directory!"))
elif f not in self.dirstate:
fail(f, _("file not tracked!"))
David Schleimer
localrepo: create context used for actual commit earlier...
r18659 cctx = context.workingctx(self, text, user, date, extra, changes)
Benoit Boissinot
localrepo.commit: use explicit variables, avoid creating new contexts
r10970 if (not force and not extra.get("close") and not merge
David Schleimer
localrepo: use workingctx for validation in commit...
r18660 and not cctx.files()
Benoit Boissinot
localrepo.commit: use explicit variables, avoid creating new contexts
r10970 and wctx.branch() == wctx.p1().branch()):
Matt Mackall
commit: move 'nothing changed' test into commit()
r8404 return None
David Schleimer
localrepo: use workingctx for validation in commit...
r18660 if merge and cctx.deleted():
Patrick Mezard
commit: abort on merge with missing files...
r16536 raise util.Abort(_("cannot commit merge with missing files"))
Benoit Boissinot
style: use consistent variable names (*mod) with imports which would shadow
r10651 ms = mergemod.mergestate(self)
Stefano Tortarolo
make commit fail when committing unresolved files
r6888 for f in changes[0]:
if f in ms and ms[f] == 'u':
raise util.Abort(_("unresolved merge conflicts "
Patrick Mezard
Improve unresolved merge conflicts warning (issue2681)...
r13541 "(see hg help resolve)"))
Matt Mackall
commit: move editor outside transaction...
r8496
if editor:
Matt Mackall
commit: report modified subrepos in commit editor
r8994 cctx._text = editor(self, cctx, subs)
Greg Ward
commit: if relevant, tell user their commit message was saved....
r9935 edited = (text != cctx._text)
Matt Mackall
commit: recurse into subrepositories
r8813
Matt Mackall
subrepo: rewrite handling of subrepo state at commit (issue2403)...
r16073 # commit subs and write new state
if subs:
for s in sorted(commitsubs):
Edouard Gomez
subrepo: print paths relative to upper repo root for push/pull/commit...
r11112 sub = wctx.sub(s)
self.ui.status(_('committing subrepository %s\n') %
Mads Kiilerich
subrepo: rename relpath to subrelpath and introduce reporelpath
r12752 subrepo.subrelpath(sub))
Edouard Gomez
subrepo: print paths relative to upper repo root for push/pull/commit...
r11112 sr = sub.commit(cctx._text, user, date)
Matt Mackall
subrepo: rewrite handling of subrepo state at commit (issue2403)...
r16073 newstate[s] = (newstate[s][0], sr)
subrepo.writestate(self, newstate)
Matt Mackall
commit: recurse into subrepositories
r8813
Greg Ward
commit: save commit message so it's not destroyed by rollback....
r9934 # Save commit message in case this transaction gets rolled back
Greg Ward
commit: write last-message.txt with no content modifications....
r9949 # (e.g. by a pretxncommit hook). Leave the content alone on
# the assumption that the user will use the same editor again.
Patrick Mezard
localrepo: add savecommitmessage() to write last-message.txt
r14529 msgfn = self.savecommitmessage(cctx._text)
Greg Ward
commit: save commit message so it's not destroyed by rollback....
r9934
Benoit Boissinot
localrepo.commit: use explicit variables, avoid creating new contexts
r10970 p1, p2 = self.dirstate.parents()
hookp1, hookp2 = hex(p1), (p2 != nullid and hex(p2) or '')
Greg Ward
commit: if relevant, tell user their commit message was saved....
r9935 try:
Brodie Rao
cleanup: eradicate long lines
r16683 self.hook("precommit", throw=True, parent1=hookp1,
parent2=hookp2)
Greg Ward
commit: if relevant, tell user their commit message was saved....
r9935 ret = self.commitctx(cctx, True)
Brodie Rao
check-code: ignore naked excepts with a "re-raise" comment...
r16705 except: # re-raises
Greg Ward
commit: if relevant, tell user their commit message was saved....
r9935 if edited:
self.ui.write(
_('note: commit message saved in %s\n') % msgfn)
raise
Matt Mackall
commit: move editor outside transaction...
r8496
Matt Mackall
bookmarks: move commit action into core
r13357 # update bookmarks, dirstate and mergestate
David Soria Parra
bookmarks: delete divergent bookmarks on merge
r16706 bookmarks.update(self, [p1, p2], ret)
David Schleimer
commit: factor out post-commit cleanup into workingctx...
r18661 cctx.markcommitted(ret)
Matt Mackall
commit: tidy up mergestate slightly
r8503 ms.reset()
Patrick Mezard
localrepo: extract _commitctx() from commit()...
r6710 finally:
Matt Mackall
commit: push repo lock down into _commitctx
r8405 wlock.release()
Patrick Mezard
localrepo: extract _commitctx() from commit()...
r6710
Mads Kiilerich
tag: run commit hook when lock is released (issue3344)
r16680 def commithook(node=hex(ret), parent1=hookp1, parent2=hookp2):
self.hook("commit", node=node, parent1=parent1, parent2=parent2)
self._afterlock(commithook)
Sune Foldager
run commit and update hooks after command completion (issue1827)...
r10492 return ret
Pierre-Yves David
clfilter: rename `unfilteredmeth` to `unfilteredmethod`...
r18016 @unfilteredmethod
Matt Mackall
commit: move editor outside transaction...
r8496 def commitctx(self, ctx, error=False):
Patrick Mezard
context: improve memctx documentation
r7077 """Add a new revision to current repository.
Matt Mackall
commit: combine _commitctx and commitctx, drop unused force argument
r8410 Revision information is passed via the context argument.
Patrick Mezard
context: improve memctx documentation
r7077 """
Patrick Mezard
context: add memctx for memory commits
r6715
Matt Mackall
commitctx: eliminate some variables
r8412 tr = lock = None
Patrick Mezard
localrepo: do not modify ctx.remove() list in-place
r12899 removed = list(ctx.removed())
Matt Mackall
commitctx: use contexts more fully
r8414 p1, p2 = ctx.p1(), ctx.p2()
Matt Mackall
commitctx: eliminate some variables
r8412 user = ctx.user()
mpm@selenic.com
Break apart hg.py...
r1089
Matt Mackall
commit: move lots of commitctx outside of the repo lock
r8411 lock = self.lock()
try:
Steve Borho
localrepo: add desc parameter to transaction...
r10881 tr = self.transaction("commit")
Matt Mackall
transactions: avoid late tear-down (issue641)...
r4970 trp = weakref.proxy(tr)
mpm@selenic.com
Break apart hg.py...
r1089
Peter Arrenbrecht
localrepo: reuse parent manifest in commitctx if no files have changed...
r14162 if ctx.files():
m1 = p1.manifest().copy()
m2 = p2.manifest()
# check in files
new = {}
changed = []
linkrev = len(self)
for f in sorted(ctx.modified() + ctx.added()):
self.ui.note(f + "\n")
try:
fctx = ctx[f]
new[f] = self._filecommit(fctx, m1, m2, linkrev, trp,
changed)
m1.set(f, fctx.flags())
except OSError, inst:
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 self.ui.warn(_("trouble committing %s!\n") % f)
raise
Peter Arrenbrecht
localrepo: reuse parent manifest in commitctx if no files have changed...
r14162 except IOError, inst:
errcode = getattr(inst, 'errno', errno.ENOENT)
if error or errcode and errcode != errno.ENOENT:
self.ui.warn(_("trouble committing %s!\n") % f)
raise
else:
removed.append(f)
mpm@selenic.com
Break apart hg.py...
r1089
Peter Arrenbrecht
localrepo: reuse parent manifest in commitctx if no files have changed...
r14162 # update manifest
m1.update(new)
removed = [f for f in sorted(removed) if f in m1 or f in m2]
drop = [f for f in removed if f in m1]
for f in drop:
del m1[f]
mn = self.manifest.add(m1, trp, linkrev, p1.manifestnode(),
p2.manifestnode(), (new, drop))
files = changed + removed
else:
mn = p1.manifestnode()
files = []
mpm@selenic.com
Break apart hg.py...
r1089
Matt Mackall
commit: move description trimming into changelog
r8499 # update changelog
Matt Mackall
Introduce HG_PREPEND to solve pretxn races...
r7787 self.changelog.delayupdate()
Peter Arrenbrecht
localrepo: reuse parent manifest in commitctx if no files have changed...
r14162 n = self.changelog.add(mn, files, ctx.description(),
Matt Mackall
commit: move description trimming into changelog
r8499 trp, p1.node(), p2.node(),
Matt Mackall
commitctx: eliminate some variables
r8412 user, ctx.date(), ctx.extra().copy())
Matt Mackall
Introduce HG_PREPEND to solve pretxn races...
r7787 p = lambda: self.changelog.writepending() and self.root or ""
Sune Foldager
run commit and update hooks after command completion (issue1827)...
r10492 xp1, xp2 = p1.hex(), p2 and p2.hex() or ''
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 self.hook('pretxncommit', throw=True, node=hex(n), parent1=xp1,
Matt Mackall
Introduce HG_PREPEND to solve pretxn races...
r7787 parent2=xp2, pending=p)
self.changelog.finalize(trp)
Pierre-Yves David
Add a phases.new-commit option to control minimal phase of new commit...
r15706 # set the new commit is proper phase
Pierre-Yves David
phases: allow phase name in phases.new-commit settings...
r16030 targetphase = phases.newcommitphase(self.ui)
Pierre-Yves David
Add a phases.new-commit option to control minimal phase of new commit...
r15706 if targetphase:
# retract boundary do not alter parent changeset.
# if a parent have higher the resulting phase will
# be compliant anyway
#
# if minimal phase was 0 we don't need to retract anything
phases.retractboundary(self, targetphase, [n])
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 tr.close()
Pierre-Yves David
branchmap: update cache of 'unserved' filter on new changesets...
r18394 branchmap.updatecache(self.filtered('served'))
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 return n
finally:
Ronny Pfannschmidt
make transactions work on non-refcounted python implementations
r11230 if tr:
tr.release()
Matt Mackall
commit: push repo lock down into _commitctx
r8405 lock.release()
mpm@selenic.com
Break apart hg.py...
r1089
Pierre-Yves David
clfilter: rename `unfilteredmeth` to `unfilteredmethod`...
r18016 @unfilteredmethod
Idan Kamara
localrepo: introduce destroying function
r18310 def destroying(self):
'''Inform the repository that nodes are about to be destroyed.
Intended for use by strip and rollback, so there's a common
place for anything that has to be done before destroying history.
This is mostly useful for saving state that is in memory and waiting
to be flushed when the current lock is released. Because a call to
destroyed is imminent, the repo will be invalidated causing those
changes to stay in memory (waiting for the next unlock), or vanish
completely.
'''
Idan Kamara
localrepo: write the phasecache when destroying nodes
r18312 # When using the same lock to commit and strip, the phasecache is left
# dirty after committing. Then when we strip, the repo is invalidated,
# causing those changes to disappear.
if '_phasecache' in vars(self):
self._phasecache.write()
Idan Kamara
localrepo: introduce destroying function
r18310 @unfilteredmethod
Pierre-Yves David
destroyed: drop complex branchcache rebuilt logic...
r18395 def destroyed(self):
Greg Ward
localrepo: add destroyed() method for strip/rollback to use (issue548).
r9150 '''Inform the repository that nodes have been destroyed.
Intended for use by strip and rollback, so there's a common
Joshua Redstone
strip: incrementally update the branchheads cache after a strip...
r17013 place for anything that has to be done after destroying history.
'''
Idan Kamara
localrepo: filter unknown nodes from the phasecache on destroyed...
r18221 # When one tries to:
# 1) destroy nodes thus calling this method (e.g. strip)
# 2) use phasecache somewhere (e.g. commit)
#
# then 2) will fail because the phasecache contains nodes that were
# removed. We can either remove phasecache from the filecache,
# causing it to reload next time it is accessed, or simply filter
# the removed nodes now and write the updated cache.
Idan Kamara
localrepo: always write the filtered phasecache when nodes are destroyed (issue3827)...
r18757 self._phasecache.filterunknown(self)
self._phasecache.write()
Idan Kamara
localrepo: filter unknown nodes from the phasecache on destroyed...
r18221
Pierre-Yves David
destroyed: update `unserved` branchcache instead...
r18396 # update the 'served' branch cache to help read only server process
Mads Kiilerich
spelling: fix some minor issues found by spell checker
r18644 # Thanks to branchcache collaboration this is done from the nearest
Pierre-Yves David
destroyed: update `unserved` branchcache instead...
r18396 # filtered subset and it is expected to be fast.
branchmap.updatecache(self.filtered('served'))
Pierre-Yves David
destroyed: filter unknown before computing branchcache...
r18223
Greg Ward
tags: implement persistent tag caching (issue548)....
r9151 # Ensure the persistent tag cache is updated. Doing it now
# means that the tag cache only has to worry about destroyed
# heads immediately after a strip/rollback. That in turn
# guarantees that "cachetip == currenttip" (comparing both rev
# and node) always means no nodes have been added or destroyed.
# XXX this is suboptimal when qrefresh'ing: we strip the current
# head, refresh the tag cache, then immediately add a new head.
# But I think doing it this way is necessary for the "instant
# tag cache retrieval" case to work.
Idan Kamara
destroyed: keep the filecache in sync with __dict__ (issue3335) (issue3693) (issue3743)...
r18313 self.invalidate()
Idan Kamara
localrepo: clear the filecache on _rollback() and destroyed()...
r17324
Matt Mackall
walk: remove cmdutil.walk
r6585 def walk(self, match, node=None):
Matt Mackall
improve walk docstrings
r3532 '''
walk recursively through the directory tree or a given
changeset, finding all files matched by the match
function
'''
Matt Mackall
context: add walk method
r6764 return self[node].walk(match)
Matt Mackall
improve walk docstrings
r3532
Matt Mackall
status: use contexts
r6769 def status(self, node1='.', node2=None, match=None,
Martin Geisler
status: recurse into subrepositories with --subrepos/-S flag
r12166 ignored=False, clean=False, unknown=False,
listsubrepos=False):
Brodie Rao
cleanup: eradicate long lines
r16683 """return status of files between two nodes or node and working
directory.
Thomas Arendsen Hein
Cleaned up localrepo.changes()
r1616
If node1 is None, use the first dirstate parent instead.
If node2 is None, compare node1 with working directory.
"""
mpm@selenic.com
Break apart hg.py...
r1089
Matt Mackall
status: use contexts
r6769 def mfmatches(ctx):
mf = ctx.manifest().copy()
Jesse Glick
localrepo: optimize internode status calls using match.always...
r16645 if match.always():
return mf
mpm@selenic.com
Break apart hg.py...
r1089 for fn in mf.keys():
if not match(fn):
del mf[fn]
return mf
Sean Farley
localrepo: remove unnecessary check of instance...
r19569 ctx1 = self[node1]
ctx2 = self[node2]
Matt Mackall
diff: pass contexts to status...
r7090
Dirkjan Ochtman
bundlerepo doesn't really have a dirstate, throw AttributeError if requested
r7435 working = ctx2.rev() is None
Matt Mackall
status: use contexts
r6769 parentworking = working and ctx1 == self['.']
Benoit Boissinot
style: use consistent variable names (*mod) with imports which would shadow
r10651 match = match or matchmod.always(self.root, self.getcwd())
Matt Mackall
repo.status: eliminate list_
r6753 listignored, listclean, listunknown = ignored, clean, unknown
Chris Mason
Fix cold cache diff performance...
r2474
Matt Mackall
diff: pass contexts to status...
r7090 # load earliest manifest first for caching reasons
if not working and ctx2.rev() < ctx1.rev():
ctx2.manifest()
Matt Mackall
status: don't warn about missing files present in base revision (issue1323)
r7067 if not parentworking:
def bad(f, msg):
FUJIWARA Katsunori
localrepository: use 'changectx.dirs()' in 'status()' for directory patterns...
r16144 # 'f' may be a directory pattern from 'match.files()',
# so 'f not in ctx1' is not enough
if f not in ctx1 and f not in ctx1.dirs():
Matt Mackall
status: don't warn about missing files present in base revision (issue1323)
r7067 self.ui.warn('%s: %s\n' % (self.dirstate.pathto(f), msg))
match.bad = bad
Matt Mackall
status: various cleanups...
r6770 if working: # we need to scan the working dir
Matt Mackall
status: avoid performance regression when no .hgsub is present...
r11227 subrepos = []
if '.hgsub' in self.dirstate:
Mads Kiilerich
subrepos: process subrepos in sorted order...
r18364 subrepos = sorted(ctx2.substate)
Augie Fackler
dirstate: don't check state of subrepo directories
r10176 s = self.dirstate.status(match, subrepos, listignored,
listclean, listunknown)
Matt Mackall
status: various cleanups...
r6770 cmp, modified, added, removed, deleted, unknown, ignored, clean = s
mpm@selenic.com
Break apart hg.py...
r1089
Matt Mackall
status: various cleanups...
r6770 # check for any possibly clean files
if parentworking and cmp:
fixup = []
# do a full compare of any files that might have changed
Matt Mackall
status: check cmp list in order
r8395 for f in sorted(cmp):
Matt Mackall
status: various cleanups...
r6770 if (f not in ctx1 or ctx2.flags(f) != ctx1.flags(f)
Nicolas Dumazet
filectx: use cmp(self, fctx) instead of cmp(self, text)...
r11702 or ctx1[f].cmp(ctx2[f])):
Matt Mackall
status: various cleanups...
r6770 modified.append(f)
else:
fixup.append(f)
# update dirstate for files that are actually clean
if fixup:
Nicolas Dumazet
localrepo.status: move fixup concatenation inside if block for clarity...
r11669 if listclean:
clean += fixup
Matt Mackall
status: various cleanups...
r6770 try:
Adrian Buehlmann
localrepo: move comment
r8647 # updating the dirstate is optional
# so we don't wait on the lock
Simon Heimberg
localrepo: use lock.release for single lock
r8646 wlock = self.wlock(False)
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 try:
Matt Mackall
status: various cleanups...
r6770 for f in fixup:
self.dirstate.normal(f)
Simon Heimberg
localrepo: use lock.release for single lock
r8646 finally:
wlock.release()
except error.LockError:
pass
Vadim Gelfer
status: add -c (clean) and -A (all files) options...
r2661
Matt Mackall
status: use contexts
r6769 if not parentworking:
mf1 = mfmatches(ctx1)
Matt Mackall
status: various cleanups...
r6770 if working:
Thomas Arendsen Hein
Cleaned up localrepo.changes()
r1616 # we are comparing working dir against non-parent
# generate a pseudo-manifest for the working dir
Matt Mackall
status: use contexts
r6769 mf2 = mfmatches(self['.'])
Matt Mackall
status: various cleanups...
r6770 for f in cmp + modified + added:
Matt Mackall
status: use contexts
r6769 mf2[f] = None
Matt Mackall
minor status fixups
r6817 mf2.set(f, ctx2.flags(f))
Thomas Arendsen Hein
Make localrepo.changes() internally distinguish between removed and deleted.
r1617 for f in removed:
Thomas Arendsen Hein
Cleaned up localrepo.changes()
r1616 if f in mf2:
del mf2[f]
Matt Mackall
status: various cleanups...
r6770 else:
# we are comparing two revisions
deleted, unknown, ignored = [], [], []
mf2 = mfmatches(ctx2)
Bryan O'Sullivan
localrepository.status: only acquire wlock if actually needed....
r4372
Vadim Gelfer
status: add -c (clean) and -A (all files) options...
r2661 modified, added, clean = [], [], []
Jesse Glick
localrepo: optimize internode status calls using withflags...
r16646 withflags = mf1.withflags() | mf2.withflags()
Bryan O'Sullivan
localrepo: iterate over manifest key/value pairs in status...
r18714 for fn, mf2node in mf2.iteritems():
Christian Ebert
Prefer i in d over d.has_key(i)
r5915 if fn in mf1:
Idan Kamara
localrepo: don't add deleted files to list of modified/added files (issue2761)...
r14500 if (fn not in deleted and
Jesse Glick
localrepo: optimize internode status calls using withflags...
r16646 ((fn in withflags and mf1.flags(fn) != mf2.flags(fn)) or
Bryan O'Sullivan
localrepo: iterate over manifest key/value pairs in status...
r18714 (mf1[fn] != mf2node and
(mf2node or ctx1[fn].cmp(ctx2[fn]))))):
Thomas Arendsen Hein
Cleaned up localrepo.changes()
r1616 modified.append(fn)
Matt Mackall
repo.status: eliminate list_
r6753 elif listclean:
Vadim Gelfer
status: add -c (clean) and -A (all files) options...
r2661 clean.append(fn)
Thomas Arendsen Hein
Cleaned up localrepo.changes()
r1616 del mf1[fn]
Idan Kamara
localrepo: don't add deleted files to list of modified/added files (issue2761)...
r14500 elif fn not in deleted:
Thomas Arendsen Hein
Cleaned up localrepo.changes()
r1616 added.append(fn)
Thomas Arendsen Hein
Make localrepo.changes() internally distinguish between removed and deleted.
r1617 removed = mf1.keys()
Matt Mackall
windows: sanity-check symlink placeholders...
r15348 if working and modified and not self.dirstate._checklink:
# Symlink placeholders may get non-symlink-like contents
# via user error or dereferencing by NFS or Samba servers,
# so we filter out any placeholders that don't look like a
# symlink
sane = []
for f in modified:
if ctx2.flags(f) == 'l':
d = ctx2[f].data()
Siddharth Agarwal
localrepo.status: ignore empty symlink placeholders...
r19650 if d == '' or len(d) >= 1024 or '\n' in d or util.binary(d):
Matt Mackall
windows: sanity-check symlink placeholders...
r15348 self.ui.debug('ignoring suspect symlink placeholder'
' "%s"\n' % f)
continue
sane.append(f)
modified = sane
Matt Mackall
dirstate.walk: push sorting up
r6827 r = modified, added, removed, deleted, unknown, ignored, clean
Martin Geisler
status: recurse into subrepositories with --subrepos/-S flag
r12166
if listsubrepos:
Martin Geisler
subrepos: add function for iterating over ctx subrepos
r12176 for subpath, sub in subrepo.itersubrepos(ctx1, ctx2):
Martin Geisler
status: recurse into subrepositories with --subrepos/-S flag
r12166 if working:
rev2 = None
else:
rev2 = ctx2.substate[subpath][1]
try:
submatch = matchmod.narrowmatcher(subpath, match)
s = sub.status(rev2, match=submatch, ignored=listignored,
clean=listclean, unknown=listunknown,
listsubrepos=True)
for rfiles, sfiles in zip(r, s):
rfiles.extend("%s/%s" % (subpath, f) for f in sfiles)
except error.LookupError:
self.ui.status(_("skipping missing subrepository: %s\n")
% subpath)
Martin Geisler
remove unnecessary list comprehensions...
r13412 for l in r:
l.sort()
Matt Mackall
dirstate.walk: push sorting up
r6827 return r
Vadim Gelfer
status: add -c (clean) and -A (all files) options...
r2661
John Mulligan
localrepo: remove 'closed' argument to heads(...) function...
r8796 def heads(self, start=None):
Benoit Boissinot
add a -r/--rev option to heads to show only heads descendant from rev
r1550 heads = self.changelog.heads(start)
# sort the output in rev descending order
Thomas Arendsen Hein
coding style: fix gratuitous whitespace after Python keywords
r13075 return sorted(heads, key=self.changelog.rev, reverse=True)
mpm@selenic.com
Break apart hg.py...
r1089
John Mulligan
localrepo: set heads and branchheads to be closed=False by default...
r8694 def branchheads(self, branch=None, start=None, closed=False):
Sune Foldager
localrepo: fix bugs in branchheads and add docstring...
r9475 '''return a (possibly filtered) list of heads for the given branch
Heads are returned in topological order, from newest to oldest.
If branch is None, use the dirstate branch.
If start is not None, return only heads reachable from start.
If closed is True, return heads that are marked as closed as well.
'''
Matt Mackall
use repo[changeid] to get a changectx
r6747 if branch is None:
branch = self[None].branch()
Benoit Boissinot
localrepo/branchcache: remove lbranchmap(), convert users to use utf-8 names...
r9675 branches = self.branchmap()
Eric Hopper
Add option to heads to show only heads for current branch.
r4648 if branch not in branches:
return []
John Mulligan
store all heads of a branch in the branch cache...
r7654 # the cache returns heads ordered lowest to highest
Sune Foldager
localrepo: fix bugs in branchheads and add docstring...
r9475 bheads = list(reversed(branches[branch]))
Eric Hopper
Add option to heads to show only heads for current branch.
r4648 if start is not None:
John Mulligan
store all heads of a branch in the branch cache...
r7654 # filter out the heads that cannot be reached from startrev
Sune Foldager
localrepo: fix bugs in branchheads and add docstring...
r9475 fbheads = set(self.changelog.nodesbetween([start], bheads)[2])
bheads = [h for h in bheads if h in fbheads]
John Mulligan
branch closing: referencing open and closed branches/heads...
r7656 if not closed:
Brodie Rao
context: add changectx.closesbranch() method...
r16720 bheads = [h for h in bheads if not self[h].closesbranch()]
John Mulligan
store all heads of a branch in the branch cache...
r7654 return bheads
Eric Hopper
Add option to heads to show only heads for current branch.
r4648
mpm@selenic.com
Break apart hg.py...
r1089 def branches(self, nodes):
Thomas Arendsen Hein
Cleanup of indentation, spacing, newlines, strings and line length
r1615 if not nodes:
nodes = [self.changelog.tip()]
mpm@selenic.com
Break apart hg.py...
r1089 b = []
for n in nodes:
t = n
Martin Geisler
check-code: flag 0/1 used as constant Boolean expression
r14494 while True:
mpm@selenic.com
Break apart hg.py...
r1089 p = self.changelog.parents(n)
if p[1] != nullid or p[0] == nullid:
b.append((t, n, p[0], p[1]))
break
n = p[0]
return b
def between(self, pairs):
r = []
for top, bottom in pairs:
n, l, i = top, [], 0
f = 1
Matt Mackall
wire protocol: avoid infinite loop (issue1483)
r7708 while n != bottom and n != nullid:
mpm@selenic.com
Break apart hg.py...
r1089 p = self.changelog.parents(n)[0]
if i == f:
l.append(n)
f = f * 2
n = p
i += 1
r.append(l)
return r
Matt Mackall
Make repo locks recursive, eliminate all passing of lock/wlock
r4917 def pull(self, remote, heads=None, force=False):
FUJIWARA Katsunori
localrepo: make supported features manageable in each repositories individually...
r19778 if remote.local():
missing = set(remote.requirements) - self.supported
if missing:
msg = _("required features are not"
" supported in the destination:"
" %s") % (', '.join(sorted(missing)))
raise util.Abort(msg)
Pierre-Yves David
obsolete: write obsolete marker inside a transaction...
r17126 # don't open transaction for nothing or you break future useful
# rollback call
tr = None
trname = 'pull\n' + util.hidepassword(remote.url())
Matt Mackall
Make repo locks recursive, eliminate all passing of lock/wlock
r4917 lock = self.lock()
Vadim Gelfer
fetch: hold lock and wlock across all operations
r2827 try:
Dirkjan Ochtman
move discovery methods from localrepo into new discovery module
r11301 tmp = discovery.findcommonincoming(self, remote, heads=heads,
force=force)
common, fetch, rheads = tmp
Vadim Gelfer
fetch: hold lock and wlock across all operations
r2827 if not fetch:
self.ui.status(_("no changes found\n"))
Pierre-Yves David
phases: exchange phase boundaries on pull...
r15650 added = []
Matt Mackall
bookmarks: merge low-level push/pull support into core
r13364 result = 0
else:
Pierre-Yves David
obsolete: write obsolete marker inside a transaction...
r17126 tr = self.transaction(trname)
Peter Arrenbrecht
discovery: avoid discovery when local graph is a subset of remote...
r13742 if heads is None and list(common) == [nullid]:
Matt Mackall
bookmarks: merge low-level push/pull support into core
r13364 self.ui.status(_("requesting all changes\n"))
elif heads is None and remote.capable('changegroupsubset'):
# issue1320, avoid a race if remote changed after discovery
heads = rheads
Benoit Boissinot
protocol: use changegroupsubset() if possible (issue1389)...
r7415
Peter Arrenbrecht
discovery: drop findoutgoing and simplify findcommonincoming's api...
r14073 if remote.capable('getbundle'):
Benoit Boissinot
bundle-ng: add bundlecaps argument to getbundle() command
r19201 # TODO: get bundlecaps from remote
Peter Arrenbrecht
discovery: avoid discovery when local graph is a subset of remote...
r13742 cg = remote.getbundle('pull', common=common,
heads=heads or rheads)
elif heads is None:
Matt Mackall
bookmarks: merge low-level push/pull support into core
r13364 cg = remote.changegroup(fetch, 'pull')
elif not remote.capable('changegroupsubset'):
Martin Geisler
Lowercase error messages
r12067 raise util.Abort(_("partial pull cannot be done because "
Matt Mackall
bookmarks: merge low-level push/pull support into core
r13364 "other repository doesn't support "
"changegroupsubset."))
else:
cg = remote.changegroupsubset(fetch, heads, 'pull')
Pierre-Yves David
pull: fix crash when pulling changeset that get hidden locally (issue3788)...
r18498 # we use unfiltered changelog here because hidden revision must
# be taken in account for phase synchronization. They may
# becomes public and becomes visible again.
cl = self.unfiltered().changelog
clstart = len(cl)
Pierre-Yves David
addchangegroup: remove the lock argument on the addchangegroup methods...
r15585 result = self.addchangegroup(cg, 'pull', remote.url())
Pierre-Yves David
pull: fix crash when pulling changeset that get hidden locally (issue3788)...
r18498 clend = len(cl)
added = [cl.node(r) for r in xrange(clstart, clend)]
Pierre-Yves David
phases: exchange phase boundaries on pull...
r15650
Pierre-Yves David
push: prevent moving phases outside of the pushed subset
r15956 # compute target subset
if heads is None:
# We pulled every thing possible
# sync on everything common
subset = common + added
else:
# We pulled a specific subset
# sync on this subset
subset = heads
Pierre-Yves David
phases: exchange phase boundaries on pull...
r15650
# Get remote phases data from remote
remotephases = remote.listkeys('phases')
publishing = bool(remotephases.get('publishing', False))
if remotephases and not publishing:
# remote is new and unpublishing
Pierre-Yves David
phases: simplify phase exchange and movement over pushkey...
r15892 pheads, _dr = phases.analyzeremotephases(self, subset,
remotephases)
phases.advanceboundary(self, phases.public, pheads)
Pierre-Yves David
push: prevent moving phases outside of the pushed subset
r15956 phases.advanceboundary(self, phases.draft, subset)
Pierre-Yves David
phases: exchange phase boundaries on pull...
r15650 else:
# Remote is old or publishing all common changesets
# should be seen as public
Pierre-Yves David
push: prevent moving phases outside of the pushed subset
r15956 phases.advanceboundary(self, phases.public, subset)
Pierre-Yves.David@ens-lyon.org
obsolete: exchange obsolete marker over pushkey...
r17075
Pierre-Yves David
obsolete: extract obsolescence marker pulling into a dedicated function...
r19054 def gettransaction():
if tr is None:
return self.transaction(trname)
return tr
obstr = obsolete.syncpull(self, remote, gettransaction)
if obstr is not None:
tr = obstr
Pierre-Yves David
obsolete: write obsolete marker inside a transaction...
r17126 if tr is not None:
tr.close()
Vadim Gelfer
fetch: hold lock and wlock across all operations
r2827 finally:
Pierre-Yves David
obsolete: write obsolete marker inside a transaction...
r17126 if tr is not None:
tr.release()
Ronny Pfannschmidt
switch lock releasing in the core from gc to explicit
r8109 lock.release()
mpm@selenic.com
Break apart hg.py...
r1089
Matt Mackall
bookmarks: merge low-level push/pull support into core
r13364 return result
Patrick Mezard
mq: factor out push conditions checks...
r13327 def checkpush(self, force, revs):
"""Extensions can override this function if additional checks have
to be performed before pushing, or call it if they override push
command.
"""
pass
Sune Foldager
push: add --new-branch option to allow intial push of new branches...
r11211 def push(self, remote, force=False, revs=None, newbranch=False):
Greg Ward
push: document return values between various repo methods....
r11153 '''Push outgoing changesets (limited by revs) from the current
repository to remote. Return an integer:
Matt Mackall
push: return 1 if no changes found (issue3228)...
r16023 - None means nothing to push
- 0 means HTTP error
Greg Ward
push: document return values between various repo methods....
r11153 - 1 means we pushed and remote head count is unchanged *or*
we have outgoing changesets but refused to push
- other values as described by addchangegroup()
'''
FUJIWARA Katsunori
localrepo: make supported features manageable in each repositories individually...
r19778 if remote.local():
missing = set(self.requirements) - remote.local().supported
if missing:
msg = _("required features are not"
" supported in the destination:"
" %s") % (', '.join(sorted(missing)))
raise util.Abort(msg)
Vadim Gelfer
extend network protocol to stop clients from locking servers...
r2439 # there are two ways to push to remote repo:
#
# addchangegroup assumes local user can lock remote
# repo (local filesystem, old ssh servers).
#
# unbundle assumes local user cannot lock remote repo (new ssh
# servers, http servers).
mpm@selenic.com
Break apart hg.py...
r1089
Sune Foldager
peer: introduce canpush and improve error message
r17193 if not remote.canpush():
raise util.Abort(_("destination does not support push"))
Kevin Bullock
push: reunite comment with the line of code it describes
r18044 unfi = self.unfiltered()
Pierre-Yves David
push: factorise phase movement in a simple closure...
r19096 def localphasemove(nodes, phase=phases.public):
"""move <nodes> to <phase> in the local source repo"""
Pierre-Yves David
push: make locking of source optional (issue3684)...
r19097 if locallock is not None:
phases.advanceboundary(self, phase, nodes)
else:
# repo is not locked, do not change any phases!
# Informs the user that phases should have been moved when
# applicable.
actualmoves = [n for n in nodes if phase < self[n].phase()]
phasestr = phases.phasenames[phase]
if actualmoves:
self.ui.status(_('cannot lock source repo, skipping local'
' %s phase update\n') % phasestr)
Pierre-Yves David
mq-safety: don't apply safety on non-outgoing changeset...
r15952 # get local lock as we might write phase data
Pierre-Yves David
push: make locking of source optional (issue3684)...
r19097 locallock = None
try:
locallock = self.lock()
except IOError, err:
if err.errno != errno.EACCES:
raise
# source repo cannot be locked.
# We do not abort the push, but just disable the local phase
# synchronisation.
msg = 'cannot lock source repository: %s\n' % err
self.ui.debug(msg)
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 try:
Pierre-Yves David
mq-safety: don't apply safety on non-outgoing changeset...
r15952 self.checkpush(force, revs)
lock = None
unbundle = remote.capable('unbundle')
if not unbundle:
lock = remote.lock()
Pierre-Yves David
phases: mark content pushed as public in local repo on push
r15485 try:
Pierre-Yves David
discovery: diet discovery.prepush from non-discovery code...
r15932 # discovery
fci = discovery.findcommonincoming
Pierre-Yves David
clfilter: unfilter some parts of the push logic...
r18007 commoninc = fci(unfi, remote, force=force)
Pierre-Yves David
discovery: diet discovery.prepush from non-discovery code...
r15932 common, inc, remoteheads = commoninc
fco = discovery.findcommonoutgoing
Pierre-Yves David
clfilter: unfilter some parts of the push logic...
r18007 outgoing = fco(unfi, remote, onlyheads=revs,
Pierre-Yves David
discovery: diet discovery.prepush from non-discovery code...
r15932 commoninc=commoninc, force=force)
if not outgoing.missing:
# nothing to push
Pierre-Yves David
clfilter: unfilter some parts of the push logic...
r18007 scmutil.nochangesfound(unfi.ui, unfi, outgoing.excluded)
Matt Mackall
push: return 1 if no changes found (issue3228)...
r16023 ret = None
Pierre-Yves David
discovery: diet discovery.prepush from non-discovery code...
r15932 else:
# something to push
if not force:
Pierre-Yves David
push: refuse to push obsolete changesets...
r17169 # if self.obsstore == False --> no obsolete
# then, save the iteration
Pierre-Yves David
clfilter: unfilter some parts of the push logic...
r18007 if unfi.obsstore:
Pierre-Yves David
push: refuse to push obsolete changesets...
r17169 # this message are here for 80 char limit reason
push includes an xxx changeset: yyyyyyyyyy
obsolete: simplify push abort message...
r17833 mso = _("push includes obsolete changeset: %s!")
Pierre-Yves David
obsolete: factorise troubles detection during push...
r18162 mst = "push includes %s changeset: %s!"
# plain versions for i18n tool to detect them
_("push includes unstable changeset: %s!")
_("push includes bumped changeset: %s!")
_("push includes divergent changeset: %s!")
Pierre-Yves David
push: refuse to push unstable changesets without force...
r17172 # If we are to push if there is at least one
# obsolete or unstable changeset in missing, at
# least one of the missinghead will be obsolete or
# unstable. So checking heads only is ok
for node in outgoing.missingheads:
Pierre-Yves David
clfilter: unfilter some parts of the push logic...
r18007 ctx = unfi[node]
Pierre-Yves David
push: refuse to push obsolete changesets...
r17169 if ctx.obsolete():
Thomas Arendsen Hein
localrepo: translate "push includes X changeset" only once...
r17855 raise util.Abort(mso % ctx)
Pierre-Yves David
obsolete: factorise troubles detection during push...
r18162 elif ctx.troubled():
raise util.Abort(_(mst)
% (ctx.troubles()[0],
ctx))
Pierre-Yves David
clfilter: unfilter some parts of the push logic...
r18007 discovery.checkheads(unfi, remote, outgoing,
Pierre-Yves David
discovery: fix regression when checking heads for pre 1.4 client (issue3218)...
r15986 remoteheads, newbranch,
bool(inc))
Pierre-Yves David
discovery: diet discovery.prepush from non-discovery code...
r15932
Benoit Boissinot
bundle-ng: add bundlecaps argument to getbundle() command
r19201 # TODO: get bundlecaps from remote
bundlecaps = None
Pierre-Yves David
discovery: diet discovery.prepush from non-discovery code...
r15932 # create a changegroup from local
if revs is None and not outgoing.excluded:
# push everything,
# use the fast path, no race possible on push
Sune Foldager
bundle-ng: move gengroup into bundler, pass repo object to bundler...
r19202 bundler = changegroup.bundle10(self, bundlecaps)
Benoit Boissinot
bundle-ng: unify _changegroup and _changegroupsubset...
r19203 cg = self._changegroupsubset(outgoing,
bundler,
'push',
fastpath=True)
Pierre-Yves David
discovery: diet discovery.prepush from non-discovery code...
r15932 else:
Benoit Boissinot
bundle-ng: add bundlecaps argument to getbundle() command
r19201 cg = self.getlocalbundle('push', outgoing, bundlecaps)
Pierre-Yves David
discovery: diet discovery.prepush from non-discovery code...
r15932
# apply changegroup to remote
Pierre-Yves David
phases: mark content pushed as public in local repo on push
r15485 if unbundle:
# local repo finds heads on server, finds out what
# revs it must push. once revs transferred, if server
# finds it has different heads (someone else won
# commit/push race), server aborts.
if force:
Pierre-Yves David
discovery: diet discovery.prepush from non-discovery code...
r15932 remoteheads = ['force']
Pierre-Yves David
phases: mark content pushed as public in local repo on push
r15485 # ssh: return remote's addchangegroup()
# http: return remote's addchangegroup() or 0 for error
Pierre-Yves David
discovery: diet discovery.prepush from non-discovery code...
r15932 ret = remote.unbundle(cg, remoteheads, 'push')
Pierre-Yves David
phases: mark content pushed as public in local repo on push
r15485 else:
Brodie Rao
cleanup: eradicate long lines
r16683 # we return an integer indicating remote head count
# change
Pierre-Yves David
addchangegroup: remove the lock argument on the addchangegroup methods...
r15585 ret = remote.addchangegroup(cg, 'push', self.url())
Pierre-Yves David
phases: exchange phase boundaries on push...
r15651
Pierre-Yves David
phases: only synchronize on common changeset when push fails...
r15933 if ret:
timeless@mozdev.org
spelling: synchronize
r17521 # push succeed, synchronize target of the push
Pierre-Yves David
push: prevent moving phases outside of the pushed subset
r15956 cheads = outgoing.missingheads
elif revs is None:
# All out push fails. synchronize all common
cheads = outgoing.commonheads
else:
# I want cheads = heads(::missingheads and ::commonheads)
# (missingheads is revs with secret changeset filtered out)
#
# This can be expressed as:
# cheads = ( (missingheads and ::commonheads)
# + (commonheads and ::missingheads))"
# )
#
# while trying to push we already computed the following:
# common = (::commonheads)
# missing = ((commonheads::missingheads) - commonheads)
#
# We can pick:
Mads Kiilerich
fix trivial spelling errors
r17424 # * missingheads part of common (::commonheads)
Pierre-Yves David
push: prevent moving phases outside of the pushed subset
r15956 common = set(outgoing.common)
Matt Mackall
push: fix coding errors in unused branch...
r16020 cheads = [node for node in revs if node in common]
redstone
localrepo: cleanup var names and comments...
r16628 # and
Pierre-Yves David
push: prevent moving phases outside of the pushed subset
r15956 # * commonheads parents on missing
Pierre-Yves David
clfilter: unfilter some parts of the push logic...
r18007 revset = unfi.set('%ln and parents(roots(%ln))',
Matt Mackall
push: fix coding errors in unused branch...
r16020 outgoing.commonheads,
outgoing.missing)
cheads.extend(c.node() for c in revset)
Pierre-Yves David
phases: exchange phase boundaries on push...
r15651 # even when we don't push, exchanging phase data is useful
remotephases = remote.listkeys('phases')
Pierre-Yves David
subrepo: allows to drop courtesy phase sync (issue3781)...
r18520 if (self.ui.configbool('ui', '_usedassubrepo', False)
and remotephases # server supports phases
and ret is None # nothing was pushed
and remotephases.get('publishing', False)):
# When:
# - this is a subrepo push
# - and remote support phase
# - and no changeset was pushed
# - and remote is publishing
# We may be in issue 3871 case!
# We drop the possible phase synchronisation done by
# courtesy to publish changesets possibly locally draft
# on the remote.
remotephases = {'publishing': 'True'}
Pierre-Yves David
phases: exchange phase boundaries on push...
r15651 if not remotephases: # old server or public only repo
Pierre-Yves David
push: factorise phase movement in a simple closure...
r19096 localphasemove(cheads)
Pierre-Yves David
phases: exchange phase boundaries on push...
r15651 # don't push any phase data as there is nothing to push
Matt Mackall
bookmarks: merge low-level push/pull support into core
r13364 else:
Pierre-Yves David
phases: only synchronize on common changeset when push fails...
r15933 ana = phases.analyzeremotephases(self, cheads, remotephases)
Pierre-Yves David
phases: simplify phase exchange and movement over pushkey...
r15892 pheads, droots = ana
Pierre-Yves David
phases: exchange phase boundaries on push...
r15651 ### Apply remote phase on local
if remotephases.get('publishing', False):
Pierre-Yves David
push: factorise phase movement in a simple closure...
r19096 localphasemove(cheads)
Pierre-Yves David
phases: exchange phase boundaries on push...
r15651 else: # publish = False
Pierre-Yves David
push: factorise phase movement in a simple closure...
r19096 localphasemove(pheads)
localphasemove(cheads, phases.draft)
Pierre-Yves David
phases: exchange phase boundaries on push...
r15651 ### Apply local phase on remote
Pierre-Yves David
phases: fix phase synchronization on push...
r15820
Pierre-Yves David
phases: simplify phase exchange and movement over pushkey...
r15892 # Get the list of all revs draft on remote by public here.
# XXX Beware that revset break if droots is not strictly
# XXX root we may want to ensure it is but it is costly
Pierre-Yves David
clfilter: unfilter some parts of the push logic...
r18007 outdated = unfi.set('heads((%ln::%ln) and public())',
Pierre-Yves David
phases: only synchronize on common changeset when push fails...
r15933 droots, cheads)
Pierre-Yves David
phases: simplify phase exchange and movement over pushkey...
r15892 for newremotehead in outdated:
Pierre-Yves David
phases: fix phase synchronization on push...
r15820 r = remote.pushkey('phases',
newremotehead.hex(),
Pierre-Yves David
phases: simplify phase exchange and movement over pushkey...
r15892 str(phases.draft),
str(phases.public))
Pierre-Yves David
phases: fix phase synchronization on push...
r15820 if not r:
Pierre-Yves David
phases: simplify phase exchange and movement over pushkey...
r15892 self.ui.warn(_('updating %s to public failed!\n')
% newremotehead)
Pierre-Yves David
obsolete: add debug output regarding obsolete marker exchange.
r17294 self.ui.debug('try to push obsolete markers to remote\n')
Pierre-Yves David
obsolete: extract obsolescence marker pushing into a dedicated function...
r19053 obsolete.syncpush(self, remote)
Pierre-Yves David
phases: mark content pushed as public in local repo on push
r15485 finally:
Pierre-Yves David
mq-safety: don't apply safety on non-outgoing changeset...
r15952 if lock is not None:
lock.release()
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 finally:
Pierre-Yves David
push: make locking of source optional (issue3684)...
r19097 if locallock is not None:
locallock.release()
mpm@selenic.com
Break apart hg.py...
r1089
Matt Mackall
bookmarks: merge low-level push/pull support into core
r13364 self.ui.debug("checking for updated bookmarks\n")
rb = remote.listkeys('bookmarks')
Wojciech Lopata
bookmarks: update only proper bookmarks on push -r/-B (issue 3973)...
r19515 revnums = map(unfi.changelog.rev, revs or [])
ancestors = [
a for a in unfi.changelog.ancestors(revnums, inclusive=True)]
Matt Mackall
bookmarks: merge low-level push/pull support into core
r13364 for k in rb.keys():
Pierre-Yves David
clfilter: use unfiltered repo for bookmark push logic...
r18009 if k in unfi._bookmarks:
Matt Mackall
bookmarks: merge low-level push/pull support into core
r13364 nr, nl = rb[k], hex(self._bookmarks[k])
Pierre-Yves David
clfilter: use unfiltered repo for bookmark push logic...
r18009 if nr in unfi:
cr = unfi[nr]
cl = unfi[nl]
if bookmarks.validdest(unfi, cr, cl):
Wojciech Lopata
bookmarks: update only proper bookmarks on push -r/-B (issue 3973)...
r19515 if ancestors and cl.rev() not in ancestors:
continue
Matt Mackall
bookmarks: merge low-level push/pull support into core
r13364 r = remote.pushkey('bookmarks', k, nr, nl)
if r:
self.ui.status(_("updating bookmark %s\n") % k)
else:
self.ui.warn(_('updating bookmark %s'
' failed!\n') % k)
return ret
Thomas Arendsen Hein
Show number of changesets written to bundle files by default (issue569)...
r5763 def changegroupinfo(self, nodes, source):
if self.ui.verbose or source == 'bundle':
self.ui.status(_("%d changesets found\n") % len(nodes))
Thomas Arendsen Hein
Show number (-v) and list (--debug) of changesets with bundle/pull/push etc.
r3513 if self.ui.debugflag:
Martin Geisler
do not attempt to translate ui.debug output
r9467 self.ui.debug("list of changesets:\n")
Thomas Arendsen Hein
Show number (-v) and list (--debug) of changesets with bundle/pull/push etc.
r3513 for node in nodes:
self.ui.debug("%s\n" % hex(node))
Benoit Boissinot
changegroupsubset: extranodes are no longer needed
r13703 def changegroupsubset(self, bases, heads, source):
Greg Ward
Improve some docstrings relating to changegroups and prepush().
r9437 """Compute a changegroup consisting of all the nodes that are
Matt Mackall
check-code: catch misspellings of descendant...
r14549 descendants of any of the bases and ancestors of any of the heads.
Greg Ward
Improve some docstrings relating to changegroups and prepush().
r9437 Return a chunkbuffer object whose read() method will return
successive changegroup chunks.
Eric Hopper
Added a lot of comments to changegroupsubset.
r1466
It is fairly complex as determining which filenodes and which
manifest nodes need to be included for the changeset to be complete
is non-trivial.
Another wrinkle is doing the reverse, figuring out which changeset in
Alexis S. L. Carvalho
changegroupsubset: accept list of per-revlog nodes to include...
r5908 the changegroup a particular filenode or manifestnode belongs to.
"""
Peter Arrenbrecht
bundle: don't send too many changesets (Issue1704)...
r9820 cl = self.changelog
if not bases:
bases = [nullid]
Benoit Boissinot
bundle-ng: unify _changegroup and _changegroupsubset...
r19203 # TODO: remove call to nodesbetween.
Peter Arrenbrecht
wireproto: add getbundle() function...
r13741 csets, bases, heads = cl.nodesbetween(bases, heads)
Benoit Boissinot
bundle-ng: unify _changegroup and _changegroupsubset...
r19203 bases = [p for n in bases for p in cl.parents(n) if p != nullid]
outgoing = discovery.outgoing(cl, bases, heads)
Sune Foldager
bundle-ng: move gengroup into bundler, pass repo object to bundler...
r19202 bundler = changegroup.bundle10(self)
Benoit Boissinot
bundle-ng: unify _changegroup and _changegroupsubset...
r19203 return self._changegroupsubset(outgoing, bundler, source)
Peter Arrenbrecht
wireproto: add getbundle() function...
r13741
Benoit Boissinot
bundle-ng: add bundlecaps argument to getbundle() command
r19201 def getlocalbundle(self, source, outgoing, bundlecaps=None):
Pierre-Yves David
discovery: introduce outgoing object for result of findcommonoutgoing...
r15837 """Like getbundle, but taking a discovery.outgoing as an argument.
This is only implemented for local repos and reuses potentially
precomputed sets in outgoing."""
if not outgoing.missing:
return None
Sune Foldager
bundle-ng: move gengroup into bundler, pass repo object to bundler...
r19202 bundler = changegroup.bundle10(self, bundlecaps)
Benoit Boissinot
bundle-ng: unify _changegroup and _changegroupsubset...
r19203 return self._changegroupsubset(outgoing, bundler, source)
Pierre-Yves David
discovery: introduce outgoing object for result of findcommonoutgoing...
r15837
Benoit Boissinot
bundle-ng: add bundlecaps argument to getbundle() command
r19201 def getbundle(self, source, heads=None, common=None, bundlecaps=None):
Peter Arrenbrecht
wireproto: add getbundle() function...
r13741 """Like changegroupsubset, but returns the set difference between the
ancestors of heads and the ancestors common.
If heads is None, use the local heads. If common is None, use [nullid].
Peter Arrenbrecht
bundle: don't send too many changesets (Issue1704)...
r9820
Peter Arrenbrecht
wireproto: add getbundle() function...
r13741 The nodes in common might not all be known locally due to the way the
current discovery protocol works.
"""
cl = self.changelog
if common:
Pierre-Yves David
clfilter: fix `nodemap` usage in `getbundle`...
r18086 hasnode = cl.hasnode
common = [n for n in common if hasnode(n)]
Peter Arrenbrecht
wireproto: add getbundle() function...
r13741 else:
common = [nullid]
if not heads:
heads = cl.heads()
Pierre-Yves David
discovery: introduce outgoing object for result of findcommonoutgoing...
r15837 return self.getlocalbundle(source,
Benoit Boissinot
bundle-ng: add bundlecaps argument to getbundle() command
r19201 discovery.outgoing(cl, common, heads),
bundlecaps=bundlecaps)
Peter Arrenbrecht
wireproto: add getbundle() function...
r13741
Pierre-Yves David
clfilter: rename `unfilteredmeth` to `unfilteredmethod`...
r18016 @unfilteredmethod
Benoit Boissinot
bundle-ng: unify _changegroup and _changegroupsubset...
r19203 def _changegroupsubset(self, outgoing, bundler, source,
fastpath=False):
commonrevs = outgoing.common
csets = outgoing.missing
heads = outgoing.missingheads
# We go through the fast path if we get told to, or if all (unfiltered
# heads have been requested (since we then know there all linkrevs will
# be pulled by the client).
Benoit Boissinot
changegroupsubset: extranodes are no longer needed
r13703 heads.sort()
Benoit Boissinot
bundle-ng: unify _changegroup and _changegroupsubset...
r19203 fastpathlinkrev = fastpath or (
self.filtername is None and heads == sorted(self.heads()))
Benoit Boissinot
fix pull racing with push/commit (issue1320)...
r7233
Vadim Gelfer
add preoutgoing and outgoing hooks....
r1736 self.hook('preoutgoing', throw=True, source=source)
Matt Mackall
changegroupsubset: minor cleanups...
r13706 self.changegroupinfo(csets, source)
Benoit Boissinot
bundle-ng: move bundle generation to changegroup.py
r19204 gengroup = bundler.generate(commonrevs, csets, fastpathlinkrev, source)
Sune Foldager
bundle-ng: move gengroup into bundler, pass repo object to bundler...
r19202 return changegroup.unbundle10(util.chunkbuffer(gengroup), 'UN')
Eric Hopper
This changes the revlog.group and re-implements the localrepo.changeroup...
r1458
Vadim Gelfer
add preoutgoing and outgoing hooks....
r1736 def changegroup(self, basenodes, source):
Benoit Boissinot
fix pull racing with push/commit (issue1320)...
r7233 # to avoid a race we use changegroupsubset() (issue1320)
return self.changegroupsubset(basenodes, self.heads(), source)
Pierre-Yves David
clfilter: rename `unfilteredmeth` to `unfilteredmethod`...
r18016 @unfilteredmethod
Pierre-Yves David
addchangegroup: remove the lock argument on the addchangegroup methods...
r15585 def addchangegroup(self, source, srctype, url, emptyok=False):
Greg Ward
push: document return values between various repo methods....
r11153 """Add the changegroup returned by source.read() to this repo.
srctype is a string like 'push', 'pull', or 'unbundle'. url is
the URL of the repo where this changegroup is coming from.
mpm@selenic.com
Break apart hg.py...
r1089
Greg Ward
push: document return values between various repo methods....
r11153 Return an integer summarizing the change to this repo:
Thomas Arendsen Hein
Don't report an error when closing heads during local push (issue387)
r3803 - nothing changed or no source: 0
- more heads than before: 1+added heads (2..n)
Greg Ward
push: document return values between various repo methods....
r11153 - fewer heads than before: -1-removed heads (-2..-n)
Thomas Arendsen Hein
Don't report an error when closing heads during local push (issue387)
r3803 - number of heads stays the same: 1
"""
mpm@selenic.com
Break apart hg.py...
r1089 def csmap(x):
Martin Geisler
do not attempt to translate ui.debug output
r9467 self.ui.debug("add changeset %s\n" % short(x))
Matt Mackall
add __len__ and __iter__ methods to repo and revlog
r6750 return len(cl)
mpm@selenic.com
Break apart hg.py...
r1089
def revmap(x):
Vadim Gelfer
fix race in localrepo.addchangegroup....
r1998 return cl.rev(x)
mpm@selenic.com
Break apart hg.py...
r1089
Thomas Arendsen Hein
Cleanup of indentation, spacing, newlines, strings and line length
r1615 if not source:
Vadim Gelfer
add merge command. means same thing as "update -m"....
r2019 return 0
Vadim Gelfer
add prechangegroup and pretxnchangegroup hooks....
r1730
Vadim Gelfer
hooks: add url to changegroup, incoming, prechangegroup, pretxnchangegroup hooks...
r2673 self.hook('prechangegroup', throw=True, source=srctype, url=url)
Vadim Gelfer
add prechangegroup and pretxnchangegroup hooks....
r1730
mpm@selenic.com
Break apart hg.py...
r1089 changesets = files = revisions = 0
Matt Mackall
progress: show approximate progress info for pull
r10888 efiles = set()
mpm@selenic.com
Break apart hg.py...
r1089
Benoit Boissinot
remove appendfile for the manifest when adding a changegroup...
r2395 # write changelog data to temp files so concurrent readers will not see
# inconsistent view
Matt Mackall
restructure changelog file appending...
r4261 cl = self.changelog
cl.delayupdate()
Adrian Buehlmann
changegroup: do not count closed new heads (issue2697)...
r14036 oldheads = cl.heads()
Vadim Gelfer
fix race in localrepo.addchangegroup....
r1998
Brodie Rao
url: move URL parsing functions into util to improve startup time...
r14076 tr = self.transaction("\n".join([srctype, util.hidepassword(url)]))
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 try:
Matt Mackall
transactions: avoid late tear-down (issue641)...
r4970 trp = weakref.proxy(tr)
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 # pull off the changeset group
self.ui.status(_("adding changesets\n"))
Peter Arrenbrecht
localrepo: use more direct vars in addchangegroup
r8393 clstart = len(cl)
Augie Fackler
localrepo: show indeterminate progress for incoming data...
r10430 class prog(object):
Martin Geisler
progress: mark strings for translation
r10496 step = _('changesets')
Augie Fackler
localrepo: show indeterminate progress for incoming data...
r10430 count = 1
ui = self.ui
Matt Mackall
progress: show approximate progress info for pull
r10888 total = None
Augie Fackler
localrepo: show indeterminate progress for incoming data...
r10430 def __call__(self):
Matt Mackall
progress: show approximate progress info for pull
r10888 self.ui.progress(self.step, self.count, unit=_('chunks'),
total=self.total)
Augie Fackler
localrepo: show indeterminate progress for incoming data...
r10430 self.count += 1
pr = prog()
Matt Mackall
bundle: refactor progress callback...
r12334 source.callback = pr
Benoit Boissinot
unbundler: separate delta and header parsing...
r14144 source.changelogheader()
Pierre-Yves David
revlog: make addgroup returns a list of node contained in the added source...
r15890 srccontent = cl.addgroup(source, csmap, trp)
if not (srccontent or emptyok):
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 raise util.Abort(_("received changelog group is empty"))
Peter Arrenbrecht
localrepo: use more direct vars in addchangegroup
r8393 clend = len(cl)
changesets = clend - clstart
Matt Mackall
progress: show approximate progress info for pull
r10888 for c in xrange(clstart, clend):
efiles.update(self[c].files())
efiles = len(efiles)
Martin Geisler
progress: mark strings for translation
r10496 self.ui.progress(_('changesets'), None)
mpm@selenic.com
Break apart hg.py...
r1089
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 # pull off the manifest group
self.ui.status(_("adding manifests\n"))
Martin Geisler
progress: mark strings for translation
r10496 pr.step = _('manifests')
Augie Fackler
localrepo: show indeterminate progress for incoming data...
r10430 pr.count = 1
Matt Mackall
progress: show approximate progress info for pull
r10888 pr.total = changesets # manifests <= changesets
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 # no need to check for empty manifest group here:
# if the result of the merge of 1 and 2 is the same in 3 and 4,
# no new manifest will be created and the manifest group will
# be empty during the pull
Benoit Boissinot
unbundler: separate delta and header parsing...
r14144 source.manifestheader()
Matt Mackall
bundle: get rid of chunkiter
r12335 self.manifest.addgroup(source, revmap, trp)
Martin Geisler
progress: mark strings for translation
r10496 self.ui.progress(_('manifests'), None)
mpm@selenic.com
Break apart hg.py...
r1089
Augie Fackler
localrepo: add optional validation (defaults to off) for incoming changes...
r10418 needfiles = {}
if self.ui.configbool('server', 'validate', default=False):
# validate incoming csets have their manifests
for cset in xrange(clstart, clend):
mfest = self.changelog.read(self.changelog.node(cset))[0]
mfest = self.manifest.readdelta(mfest)
# store file nodes we must see
for f, n in mfest.iteritems():
needfiles.setdefault(f, set()).add(n)
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 # process the files
self.ui.status(_("adding file changes\n"))
Wagner Bruna
localrepo: mark progress step for translation
r14756 pr.step = _('files')
Augie Fackler
localrepo: show indeterminate progress for incoming data...
r10430 pr.count = 1
Matt Mackall
progress: show approximate progress info for pull
r10888 pr.total = efiles
Matt Mackall
bundle: refactor progress callback...
r12334 source.callback = None
Durham Goode
changegroup: move changegroup file adding to a separate function...
r19291 newrevs, newfiles = self.addchangegroupfiles(source, revmap, trp,
pr, needfiles)
revisions += newrevs
files += newfiles
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915
Adrian Buehlmann
changegroup: do not count closed new heads (issue2697)...
r14036 dh = 0
if oldheads:
heads = cl.heads()
dh = len(heads) - len(oldheads)
for h in heads:
Brodie Rao
context: add changectx.closesbranch() method...
r16720 if h not in oldheads and self[h].closesbranch():
Adrian Buehlmann
changegroup: do not count closed new heads (issue2697)...
r14036 dh -= 1
htext = ""
if dh:
htext = _(" (%+d heads)") % dh
Vadim Gelfer
fix race in localrepo.addchangegroup....
r1998
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 self.ui.status(_("added %d changesets"
" with %d changes to %d files%s\n")
Adrian Buehlmann
changegroup: do not count closed new heads (issue2697)...
r14036 % (changesets, revisions, files, htext))
Pierre-Yves David
cache: group obscache and revsfiltercache invalidation in a single function...
r18105 self.invalidatevolatilesets()
mpm@selenic.com
Break apart hg.py...
r1089
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 if changesets > 0:
Peter Arrenbrecht
localrepo: use cl throughout in addchangegroup
r8392 p = lambda: cl.writepending() and self.root or ""
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 self.hook('pretxnchangegroup', throw=True,
Peter Arrenbrecht
localrepo: use more direct vars in addchangegroup
r8393 node=hex(cl.node(clstart)), source=srctype,
Matt Mackall
Introduce HG_PREPEND to solve pretxn races...
r7787 url=url, pending=p)
Pierre-Yves David
phases: marked content of a changegroup as published
r15484 added = [cl.node(r) for r in xrange(clstart, clend)]
Pierre-Yves David
phases: change publish behavior to only alter behavior when server....
r15659 publishing = self.ui.configbool('phases', 'publish', True)
Pierre-Yves David
phases: move phase according what was pushed not only what was added added...
r15891 if srctype == 'push':
Pierre-Yves David
phases: change publish behavior to only alter behavior when server....
r15659 # Old server can not push the boundary themself.
Pierre-Yves David
phases: move phase according what was pushed not only what was added added...
r15891 # New server won't push the boundary if changeset already
# existed locally as secrete
#
# We should not use added here but the list of all change in
# the bundle
if publishing:
phases.advanceboundary(self, phases.public, srccontent)
else:
phases.advanceboundary(self, phases.draft, srccontent)
phases.retractboundary(self, phases.draft, added)
elif srctype != 'strip':
# publishing only alter behavior during push
#
# strip should not touch boundary at all
Pierre-Yves David
phases: store phase values in constant instead of using raw integer...
r15818 phases.retractboundary(self, phases.draft, added)
Pierre-Yves David
phases: add a phases.publish option...
r15646
Matt Mackall
Introduce HG_PREPEND to solve pretxn races...
r7787 # make changelog see real files again
cl.finalize(trp)
mpm@selenic.com
Break apart hg.py...
r1089
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 tr.close()
Pierre-Yves David
addchangegroup: use a postrelease callback to call changegroup hook...
r15584
Matt Mackall
addchangegroup: ony queue hooks when we have changesets
r15586 if changesets > 0:
Pierre-Yves David
strip: do not update branchcache during strip (issue3745)...
r18137 if srctype != 'strip':
# During strip, branchcache is invalid but coming call to
# `destroyed` will repair it.
# In other case we can safely update cache on disk.
Pierre-Yves David
branchmap: update cache of 'unserved' filter on new changesets...
r18394 branchmap.updatecache(self.filtered('served'))
Matt Mackall
addchangegroup: ony queue hooks when we have changesets
r15586 def runhooks():
Pierre-Yves David
addchangegroup: use a postrelease callback to call changegroup hook...
r15584 # forcefully update the on-disk branch cache
self.ui.debug("updating the branch cache\n")
self.hook("changegroup", node=hex(cl.node(clstart)),
source=srctype, url=url)
for n in added:
self.hook("incoming", node=hex(n), source=srctype,
url=url)
Durham Goode
blackbox: log incoming changes via ui.log()...
r18672
Durham Goode
blackbox: only show new heads on incoming...
r18677 newheads = [h for h in self.heads() if h not in oldheads]
Durham Goode
blackbox: log incoming changes via ui.log()...
r18672 self.ui.log("incoming",
Durham Goode
blackbox: do not translate the log messages...
r18691 "%s incoming changes - new heads: %s\n",
Durham Goode
blackbox: log incoming changes via ui.log()...
r18672 len(added),
Durham Goode
blackbox: only show new heads on incoming...
r18677 ', '.join([hex(c[:6]) for c in newheads]))
Matt Mackall
localrepo: rename _postrelease to _afterlock
r15587 self._afterlock(runhooks)
Pierre-Yves David
addchangegroup: use a postrelease callback to call changegroup hook...
r15584
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 finally:
Ronny Pfannschmidt
make transactions work on non-refcounted python implementations
r11230 tr.release()
Thomas Arendsen Hein
Don't report an error when closing heads during local push (issue387)
r3803 # never return 0 here:
Adrian Buehlmann
changegroup: do not count closed new heads (issue2697)...
r14036 if dh < 0:
return dh - 1
Thomas Arendsen Hein
Don't report an error when closing heads during local push (issue387)
r3803 else:
Adrian Buehlmann
changegroup: do not count closed new heads (issue2697)...
r14036 return dh + 1
mpm@selenic.com
Break apart hg.py...
r1089
Durham Goode
changegroup: move changegroup file adding to a separate function...
r19291 def addchangegroupfiles(self, source, revmap, trp, pr, needfiles):
revisions = 0
files = 0
while True:
chunkdata = source.filelogheader()
if not chunkdata:
break
f = chunkdata["filename"]
self.ui.debug("adding %s revisions\n" % f)
pr()
fl = self.file(f)
o = len(fl)
if not fl.addgroup(source, revmap, trp):
raise util.Abort(_("received file revlog group is empty"))
revisions += len(fl) - o
files += 1
if f in needfiles:
needs = needfiles[f]
for new in xrange(o, len(fl)):
n = fl.node(new)
if n in needs:
needs.remove(n)
else:
raise util.Abort(
_("received spurious file revlog entry"))
if not needs:
del needfiles[f]
self.ui.progress(_('files'), None)
for f, needs in needfiles.iteritems():
fl = self.file(f)
for n in needs:
try:
fl.rev(n)
except error.LookupError:
raise util.Abort(
_('missing file data for %s:%s - run hg verify') %
(f, hex(n)))
return revisions, files
Sune Foldager
clone: only use stream when we understand the revlog format...
r12296 def stream_in(self, remote, requirements):
Adrian Buehlmann
localrepo: acquire lock on stream_in
r13390 lock = self.lock()
Thomas Arendsen Hein
New UnexpectedOutput exception to catch server errors in localrepo.stream_in...
r3564 try:
Tomasz Kleczek
branchcache: fetch source branchcache during clone (issue3378)...
r17740 # Save remote branchmap. We will use it later
# to speed up branchcache creation
rbranchmap = None
if remote.capable("branchmap"):
rbranchmap = remote.branchmap()
Adrian Buehlmann
localrepo: acquire lock on stream_in
r13390 fp = remote.stream_out()
Thomas Arendsen Hein
New UnexpectedOutput exception to catch server errors in localrepo.stream_in...
r3564 l = fp.readline()
try:
Adrian Buehlmann
localrepo: acquire lock on stream_in
r13390 resp = int(l)
except ValueError:
raise error.ResponseError(
Martin Geisler
localrepo: lowercase "unexpected response" message
r16941 _('unexpected response from remote server:'), l)
Adrian Buehlmann
localrepo: acquire lock on stream_in
r13390 if resp == 1:
raise util.Abort(_('operation forbidden by server'))
elif resp == 2:
raise util.Abort(_('locking the remote repository failed'))
elif resp != 0:
raise util.Abort(_('the server sent an unknown error code'))
self.ui.status(_('streaming all changes\n'))
l = fp.readline()
try:
total_files, total_bytes = map(int, l.split(' ', 1))
Bernhard Leiner
Add missing catch of a TypeError
r7063 except (ValueError, TypeError):
Matt Mackall
error: move UnexpectedOutput (now ResponseError)
r7641 raise error.ResponseError(
Martin Geisler
localrepo: lowercase "unexpected response" message
r16941 _('unexpected response from remote server:'), l)
Adrian Buehlmann
localrepo: acquire lock on stream_in
r13390 self.ui.status(_('%d files to transfer, %s of data\n') %
(total_files, util.bytecount(total_bytes)))
Augie Fackler
clone: add progress calls to uncompressed code path
r16770 handled_bytes = 0
self.ui.progress(_('clone'), 0, total=total_bytes)
Adrian Buehlmann
localrepo: acquire lock on stream_in
r13390 start = time.time()
for i in xrange(total_files):
# XXX doesn't support '\n' or '\r' in filenames
l = fp.readline()
try:
name, size = l.split('\0', 1)
size = int(size)
except (ValueError, TypeError):
raise error.ResponseError(
Martin Geisler
localrepo: lowercase "unexpected response" message
r16941 _('unexpected response from remote server:'), l)
Matt Mackall
stream_in: avoid debug calls when debug is disabled
r16398 if self.ui.debugflag:
self.ui.debug('adding %s (%s)\n' %
(name, util.bytecount(size)))
Adrian Buehlmann
localrepo: acquire lock on stream_in
r13390 # for backwards compat, name was partially encoded
ofp = self.sopener(store.decodedir(name), 'w')
for chunk in util.filechunkiter(fp, limit=size):
Augie Fackler
clone: add progress calls to uncompressed code path
r16770 handled_bytes += len(chunk)
self.ui.progress(_('clone'), handled_bytes,
total=total_bytes)
Adrian Buehlmann
localrepo: acquire lock on stream_in
r13390 ofp.write(chunk)
ofp.close()
elapsed = time.time() - start
if elapsed <= 0:
elapsed = 0.001
Augie Fackler
clone: add progress calls to uncompressed code path
r16770 self.ui.progress(_('clone'), None)
Adrian Buehlmann
localrepo: acquire lock on stream_in
r13390 self.ui.status(_('transferred %s in %.1f seconds (%s/sec)\n') %
(util.bytecount(total_bytes), elapsed,
util.bytecount(total_bytes / elapsed)))
Sune Foldager
clone: only use stream when we understand the revlog format...
r12296
Brodie Rao
cleanup: eradicate long lines
r16683 # new requirements = old non-format requirements +
# new format-related
Adrian Buehlmann
localrepo: acquire lock on stream_in
r13390 # requirements from the streamed-in repository
requirements.update(set(self.requirements) - self.supportedformats)
self._applyrequirements(requirements)
self._writerequirements()
Sune Foldager
clone: only use stream when we understand the revlog format...
r12296
Tomasz Kleczek
branchcache: fetch source branchcache during clone (issue3378)...
r17740 if rbranchmap:
rbheads = []
for bheads in rbranchmap.itervalues():
rbheads.extend(bheads)
if rbheads:
rtiprev = max((int(self.changelog.rev(node))
for node in rbheads))
Pierre-Yves David
branchmap: add the tipnode (cache key) on the branchcache object...
r18125 cache = branchmap.branchcache(rbranchmap,
Pierre-Yves David
branchmap: add the tiprev (cache key) on the branchmap object...
r18126 self[rtiprev].node(),
rtiprev)
Pierre-Yves David
stream_in: write the remote branchcache for a usage as wide as possible...
r18397 # Try to stick it as low as possible
# filter above served are unlikely to be fetch from a clone
for candidate in ('base', 'immutable', 'served'):
rview = self.filtered(candidate)
if cache.validfor(rview):
self._branchcaches[candidate] = cache
cache.write(rview)
break
Adrian Buehlmann
localrepo: acquire lock on stream_in
r13390 self.invalidate()
return len(self.heads()) + 1
finally:
lock.release()
mpm@selenic.com
Break apart hg.py...
r1089
Vadim Gelfer
clone: do not make streaming default. add --stream option instead.
r2613 def clone(self, remote, heads=[], stream=False):
Vadim Gelfer
add support for streaming clone....
r2612 '''clone remote repository.
Matt Mackall
hg verify: more consistency checking between changesets and manifests
r1382
Vadim Gelfer
add support for streaming clone....
r2612 keyword arguments:
heads: list of revs to clone (forces use of pull)
Vadim Gelfer
clone: disable stream support on server side by default....
r2621 stream: use streaming clone if possible'''
mpm@selenic.com
Break apart hg.py...
r1089
Vadim Gelfer
clone: disable stream support on server side by default....
r2621 # now, all clients that can request uncompressed clones can
# read repo formats supported by all servers that can serve
# them.
mpm@selenic.com
Break apart hg.py...
r1089
Vadim Gelfer
add support for streaming clone....
r2612 # if revlog format changes, client will have to check version
Vadim Gelfer
clone: disable stream support on server side by default....
r2621 # and format flags on "stream" capability, and use
# uncompressed only if compatible.
mpm@selenic.com
Break apart hg.py...
r1089
Benoit Allard
protocol: Add the stream-preferred capability...
r16361 if not stream:
Mads Kiilerich
improve some comments and docstrings, fixing issues found when spell checking
r17427 # if the server explicitly prefers to stream (for fast LANs)
Benoit Allard
protocol: Add the stream-preferred capability...
r16361 stream = remote.capable('stream-preferred')
Sune Foldager
clone: only use stream when we understand the revlog format...
r12296 if stream and not heads:
# 'stream' means remote revlog format is revlogv1 only
if remote.capable('stream'):
return self.stream_in(remote, set(('revlogv1',)))
# otherwise, 'streamreqs' contains the remote revlog format
streamreqs = remote.capable('streamreqs')
if streamreqs:
streamreqs = set(streamreqs.split(','))
# if we support it, stream in and adjust our requirements
if not streamreqs - self.supportedformats:
return self.stream_in(remote, streamreqs)
Vadim Gelfer
add support for streaming clone....
r2612 return self.pull(remote, heads)
mason@suse.com
Automatic nesting into running transactions in the same repository....
r1806
Matt Mackall
pushkey: add localrepo support
r11368 def pushkey(self, namespace, key, old, new):
Brodie Rao
pushkey: add hooks for pushkey/listkeys
r14102 self.hook('prepushkey', throw=True, namespace=namespace, key=key,
old=old, new=new)
Pierre-Yves David
pushkey: add more verbose debug output regarding pushkey...
r17293 self.ui.debug('pushing key for "%s:%s"\n' % (namespace, key))
Brodie Rao
pushkey: add hooks for pushkey/listkeys
r14102 ret = pushkey.push(self, namespace, key, old, new)
self.hook('pushkey', namespace=namespace, key=key, old=old, new=new,
ret=ret)
return ret
Matt Mackall
pushkey: add localrepo support
r11368
def listkeys(self, namespace):
Brodie Rao
pushkey: add hooks for pushkey/listkeys
r14102 self.hook('prelistkeys', throw=True, namespace=namespace)
Pierre-Yves David
pushkey: add more verbose debug output regarding pushkey...
r17293 self.ui.debug('listing keys for "%s"\n' % namespace)
Brodie Rao
pushkey: add hooks for pushkey/listkeys
r14102 values = pushkey.list(self, namespace)
self.hook('listkeys', namespace=namespace, values=values)
return values
Matt Mackall
pushkey: add localrepo support
r11368
Peter Arrenbrecht
wireproto: add test for new optional arg missing on server...
r14048 def debugwireargs(self, one, two, three=None, four=None, five=None):
Peter Arrenbrecht
debug: add debugwireargs to test argument passing over the wire...
r13720 '''used to test argument passing over the wire'''
Peter Arrenbrecht
wireproto: add test for new optional arg missing on server...
r14048 return "%s %s %s %s %s" % (one, two, three, four, five)
Matt Mackall
pushkey: add localrepo support
r11368
Patrick Mezard
localrepo: add savecommitmessage() to write last-message.txt
r14529 def savecommitmessage(self, text):
fp = self.opener('last-message.txt', 'wb')
try:
fp.write(text)
finally:
fp.close()
Mads Kiilerich
check-code: there must also be whitespace between ')' and operator...
r18054 return self.pathto(fp.name[len(self.root) + 1:])
Patrick Mezard
localrepo: add savecommitmessage() to write last-message.txt
r14529
mason@suse.com
Automatic nesting into running transactions in the same repository....
r1806 # used to avoid circular references so destructors work
Benoit Boissinot
localrepo: change aftertrans to be independant of the store path
r3790 def aftertrans(files):
renamefiles = [tuple(t) for t in files]
mason@suse.com
Automatic nesting into running transactions in the same repository....
r1806 def a():
FUJIWARA Katsunori
localrepo: use "vfs.rename()" instead of "util.rename()"...
r18952 for vfs, src, dest in renamefiles:
Alain Leufroy
localrepo: do not complain about missing journal files
r16441 try:
FUJIWARA Katsunori
localrepo: use "vfs.rename()" instead of "util.rename()"...
r18952 vfs.rename(src, dest)
Alain Leufroy
localrepo: do not complain about missing journal files
r16441 except OSError: # journal file does not yet exist
pass
mason@suse.com
Automatic nesting into running transactions in the same repository....
r1806 return a
Alexander Solovyov
fix bookmarks rollback behavior...
r14266 def undoname(fn):
base, name = os.path.split(fn)
assert name.startswith('journal')
return os.path.join(base, name.replace('journal', 'undo', 1))
Vadim Gelfer
clean up hg.py: move repo constructor code into each repo module
r2740 def instance(ui, path, create):
Mads Kiilerich
util: rename the util.localpath that uses url to urllocalpath (issue2875)...
r14825 return localrepository(ui, util.urllocalpath(path), create)
Thomas Arendsen Hein
Whitespace/Tab cleanup
r3223
Vadim Gelfer
clean up hg.py: move repo constructor code into each repo module
r2740 def islocal(path):
return True