##// END OF EJS Templates
revert: remove dangerous `parents` argument from `cmdutil.revert()`...
revert: remove dangerous `parents` argument from `cmdutil.revert()` As we found out the hard way (thanks to spectral@ for figuring it out!), `cmdutil.revert()`'s `parents` argument must be `repo.dirstate.parents()` or things may go wrong. We had an extension that passed in the target commit as the first parent. The `hg split` command from the evolve extension seems to have made the same mistake, but I haven't looked carefully. The problem is that `cmdutil._performrevert()` calls `dirstate.normal()` on reverted files if the commit to revert to equals the first parent. So if you pass in `ctx=foo` and `parents=(foo.node(), nullid)`, then `dirstate.normal()` will be called for the revert files, even though they might not be clean in the working copy. There doesn't seem to be any reason, other than a tiny performance benefit, to passing the `parents` around instead of looking them up again in `cmdutil._performrevert()`, so that's what this patch does. Differential Revision: https://phab.mercurial-scm.org/D8925

File last commit:

r44937:9d2b2df2 default
r45935:8c466bcb default
Show More
remotestore.py
153 lines | 5.1 KiB | text/x-python | PythonLexer
various
hgext: add largefiles extension...
r15168 # Copyright 2010-2011 Fog Creek Software
# Copyright 2010-2011 Unity Technologies
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
Mads Kiilerich
fix wording and not-completely-trivial spelling errors and bad docstrings
r17425 '''remote largefile store; the base class for wirestore'''
liscju
py3: make largefiles/remotestore.py use absolute_import
r29313 from __future__ import absolute_import
various
hgext: add largefiles extension...
r15168
from mercurial.i18n import _
liscju
py3: make largefiles/remotestore.py use absolute_import
r29313 from mercurial import (
error,
Gregory Szorc
py3: define and use pycompat.iteritems() for hgext/...
r43375 pycompat,
liscju
py3: make largefiles/remotestore.py use absolute_import
r29313 util,
)
Augie Fackler
formatting: blacken the codebase...
r43346 from mercurial.utils import stringutil
Yuya Nishihara
stringutil: bulk-replace call sites to point to new module...
r37102
liscju
py3: make largefiles/remotestore.py use absolute_import
r29313 from . import (
basestore,
lfutil,
localstore,
)
timeless
pycompat: switch to util.urlreq/util.urlerr for py3 compat
r28883 urlerr = util.urlerr
urlreq = util.urlreq
Augie Fackler
formatting: blacken the codebase...
r43346
various
hgext: add largefiles extension...
r15168 class remotestore(basestore.basestore):
Greg Ward
largefiles: improve comments, internal docstrings...
r15252 '''a largefile store accessed over a network'''
Augie Fackler
formatting: blacken the codebase...
r43346
various
hgext: add largefiles extension...
r15168 def __init__(self, ui, repo, url):
super(remotestore, self).__init__(ui, repo, url)
Boris Feld
largefiles: add support for 'largefiles://' url scheme...
r35580 self._lstore = None
if repo is not None:
self._lstore = localstore.localstore(self.ui, self.repo, self.repo)
various
hgext: add largefiles extension...
r15168
def put(self, source, hash):
if self.sendfile(source, hash):
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'remotestore: could not put %s to remote store %s')
Augie Fackler
formatting: blacken the codebase...
r43346 % (source, util.hidepassword(self.url))
)
various
hgext: add largefiles extension...
r15168 self.ui.debug(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'remotestore: put %s to remote store %s\n')
Augie Fackler
formatting: blacken the codebase...
r43346 % (source, util.hidepassword(self.url))
)
various
hgext: add largefiles extension...
r15168
Na'Tosha Bard
largefiles: batch statlfile requests when pushing a largefiles repo (issue3386)...
r17127 def exists(self, hashes):
Augie Fackler
cleanup: run pyupgrade on our source tree to clean up varying things...
r44937 return {
h: s == 0
Gregory Szorc
py3: define and use pycompat.iteritems() for hgext/...
r43375 for (h, s) in pycompat.iteritems(
self._stat(hashes)
) # dict-from-generator
Augie Fackler
cleanup: run pyupgrade on our source tree to clean up varying things...
r44937 }
various
hgext: add largefiles extension...
r15168
def sendfile(self, filename, hash):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.ui.debug(b'remotestore: sendfile(%s, %s)\n' % (filename, hash))
various
hgext: add largefiles extension...
r15168 try:
Mads Kiilerich
largefiles: use context for file closing...
r30142 with lfutil.httpsendfile(self.ui, filename) as fd:
return self._put(hash, fd)
Gregory Szorc
global: mass rewrite to use modern exception syntax...
r25660 except IOError as e:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'remotestore: could not open file %s: %s')
Augie Fackler
formatting: blacken the codebase...
r43346 % (filename, stringutil.forcebytestr(e))
)
various
hgext: add largefiles extension...
r15168
def _getfile(self, tmpfile, filename, hash):
try:
Mads Kiilerich
largefiles: move protocol conversion into getlfile and make it an iterable...
r19004 chunks = self._get(hash)
timeless
pycompat: switch to util.urlreq/util.urlerr for py3 compat
r28883 except urlerr.httperror as e:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 # 401s get converted to error.Aborts; everything else is fine being
various
hgext: add largefiles extension...
r15168 # turned into a StoreError
Augie Fackler
formatting: blacken the codebase...
r43346 raise basestore.StoreError(
filename, hash, self.url, stringutil.forcebytestr(e)
)
timeless
pycompat: switch to util.urlreq/util.urlerr for py3 compat
r28883 except urlerr.urlerror as e:
various
hgext: add largefiles extension...
r15168 # This usually indicates a connection problem, so don't
# keep trying with the other files... they will probably
# all fail too.
Augie Fackler
formatting: blacken the codebase...
r43346 raise error.Abort(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'%s: %s' % (util.hidepassword(self.url), e.reason)
Augie Fackler
formatting: blacken the codebase...
r43346 )
Gregory Szorc
global: mass rewrite to use modern exception syntax...
r25660 except IOError as e:
Augie Fackler
formatting: blacken the codebase...
r43346 raise basestore.StoreError(
filename, hash, self.url, stringutil.forcebytestr(e)
)
various
hgext: add largefiles extension...
r15168
Mads Kiilerich
largefiles: move protocol conversion into getlfile and make it an iterable...
r19004 return lfutil.copyandhash(chunks, tmpfile)
various
hgext: add largefiles extension...
r15168
liscju
largefiles: send statlfile remote calls only for nonexisting locally files...
r29218 def _hashesavailablelocally(self, hashes):
existslocallymap = self._lstore.exists(hashes)
localhashes = [hash for hash in hashes if existslocallymap[hash]]
return localhashes
liscju
largefiles: change basestore._verifyfile to take list of files to check...
r29067 def _verifyfiles(self, contents, filestocheck):
failed = False
Augie Fackler
formatting: blacken the codebase...
r43346 expectedhashes = [
expectedhash for cset, filename, expectedhash in filestocheck
]
liscju
largefiles: send statlfile remote calls only for nonexisting locally files...
r29218 localhashes = self._hashesavailablelocally(expectedhashes)
Augie Fackler
formatting: blacken the codebase...
r43346 stats = self._stat(
[
expectedhash
for expectedhash in expectedhashes
if expectedhash not in localhashes
]
)
liscju
largefiles: send statlfile remote calls only for nonexisting locally files...
r29218
liscju
largefiles: change basestore._verifyfile to take list of files to check...
r29067 for cset, filename, expectedhash in filestocheck:
liscju
largefiles: send statlfile remote calls only for nonexisting locally files...
r29218 if expectedhash in localhashes:
filetocheck = (cset, filename, expectedhash)
Augie Fackler
formatting: blacken the codebase...
r43346 verifyresult = self._lstore._verifyfiles(
contents, [filetocheck]
)
liscju
largefiles: send statlfile remote calls only for nonexisting locally files...
r29218 if verifyresult:
liscju
largefiles: change basestore._verifyfile to take list of files to check...
r29067 failed = True
liscju
largefiles: send statlfile remote calls only for nonexisting locally files...
r29218 else:
stat = stats[expectedhash]
if stat:
if stat == 1:
self.ui.warn(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'changeset %s: %s: contents differ\n')
Augie Fackler
formatting: blacken the codebase...
r43346 % (cset, filename)
)
liscju
largefiles: send statlfile remote calls only for nonexisting locally files...
r29218 failed = True
elif stat == 2:
self.ui.warn(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'changeset %s: %s missing\n') % (cset, filename)
Augie Fackler
formatting: blacken the codebase...
r43346 )
liscju
largefiles: send statlfile remote calls only for nonexisting locally files...
r29218 failed = True
else:
Augie Fackler
formatting: blacken the codebase...
r43346 raise RuntimeError(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'verify failed: unexpected response '
b'from statlfile (%r)' % stat
Augie Fackler
formatting: blacken the codebase...
r43346 )
liscju
largefiles: change basestore._verifyfile to take list of files to check...
r29067 return failed
Na'Tosha Bard
largefiles: batch statlfile requests when pushing a largefiles repo (issue3386)...
r17127
liscju
largefiles: add abstract methods in remotestore class...
r28442 def _put(self, hash, fd):
'''Put file with the given hash in the remote store.'''
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise NotImplementedError(b'abstract method')
liscju
largefiles: add abstract methods in remotestore class...
r28442
def _get(self, hash):
Mads Kiilerich
largefiles: always use filechunkiter when iterating files...
r30180 '''Get a iterator for content with the given hash.'''
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise NotImplementedError(b'abstract method')
liscju
largefiles: add abstract methods in remotestore class...
r28442
def _stat(self, hashes):
'''Get information about availability of files specified by
hashes in the remote store. Return dictionary mapping hashes
to return code where 0 means that file is available, other
values if not.'''
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise NotImplementedError(b'abstract method')