--- a/mercurial/context.py Mon Dec 17 15:05:52 2018 +0100
+++ b/mercurial/context.py Tue Dec 18 10:21:25 2018 -0500
@@ -2330,6 +2330,9 @@
if copied:
self._copied = (copied, nullid)
+ def cmp(self, fctx):
+ return self.data() != fctx.data()
+
def data(self):
return self._data
--- a/mercurial/pure/osutil.py Mon Dec 17 15:05:52 2018 +0100
+++ b/mercurial/pure/osutil.py Tue Dec 18 10:21:25 2018 -0500
@@ -267,7 +267,8 @@
return self._file.__setattr__(name, value)
def __enter__(self):
- return self._file.__enter__()
+ self._file.__enter__()
+ return self
def __exit__(self, exc_type, exc_value, exc_tb):
return self._file.__exit__(exc_type, exc_value, exc_tb)
--- a/mercurial/vfs.py Mon Dec 17 15:05:52 2018 +0100
+++ b/mercurial/vfs.py Tue Dec 18 10:21:25 2018 -0500
@@ -525,7 +525,8 @@
return delattr(self._origfh, attr)
def __enter__(self):
- return self._origfh.__enter__()
+ self._origfh.__enter__()
+ return self
def __exit__(self, exc_type, exc_value, exc_tb):
raise NotImplementedError('attempted instantiating ' + str(type(self)))
--- a/mercurial/windows.py Mon Dec 17 15:05:52 2018 +0100
+++ b/mercurial/windows.py Tue Dec 18 10:21:25 2018 -0500
@@ -70,7 +70,8 @@
object.__setattr__(self, r'_lastop', 0)
def __enter__(self):
- return self._fp.__enter__()
+ self._fp.__enter__()
+ return self
def __exit__(self, exc_type, exc_val, exc_tb):
self._fp.__exit__(exc_type, exc_val, exc_tb)
@@ -132,7 +133,10 @@
self._fp = fp
def __enter__(self):
- return self._fp.__enter__()
+ self._fp.__enter__()
+ # Return this wrapper for the context manager so that the name is
+ # still available.
+ return self
def __exit__(self, exc_type, exc_value, traceback):
self._fp.__exit__(exc_type, exc_value, traceback)
--- a/mercurial/worker.py Mon Dec 17 15:05:52 2018 +0100
+++ b/mercurial/worker.py Tue Dec 18 10:21:25 2018 -0500
@@ -213,11 +213,7 @@
waitforworkers()
signal.signal(signal.SIGCHLD, oldchldhandler)
selector.close()
- status = problem[0]
- if status:
- if status < 0:
- os.kill(os.getpid(), -status)
- sys.exit(status)
+ return problem[0]
try:
openpipes = len(pipes)
while openpipes > 0:
@@ -236,7 +232,11 @@
killworkers()
cleanup()
raise
- cleanup()
+ status = cleanup()
+ if status:
+ if status < 0:
+ os.kill(os.getpid(), -status)
+ sys.exit(status)
def _posixexitstatus(code):
'''convert a posix exit status into the same form returned by
--- a/tests/run-tests.py Mon Dec 17 15:05:52 2018 +0100
+++ b/tests/run-tests.py Tue Dec 18 10:21:25 2018 -0500
@@ -587,6 +587,17 @@
shutil.copy(src, dst)
os.remove(src)
+def makecleanable(path):
+ """Try to fix directory permission recursively so that the entire tree
+ can be deleted"""
+ for dirpath, dirnames, _filenames in os.walk(path, topdown=True):
+ for d in dirnames:
+ p = os.path.join(dirpath, d)
+ try:
+ os.chmod(p, os.stat(p).st_mode & 0o777 | 0o700) # chmod u+rwx
+ except OSError:
+ pass
+
_unified_diff = difflib.unified_diff
if PYTHON3:
import functools
@@ -953,7 +964,13 @@
(self._testtmp.decode('utf-8'),
self._threadtmp.decode('utf-8')))
else:
- shutil.rmtree(self._testtmp, True)
+ try:
+ shutil.rmtree(self._testtmp)
+ except OSError:
+ # unreadable directory may be left in $TESTTMP; fix permission
+ # and try again
+ makecleanable(self._testtmp)
+ shutil.rmtree(self._testtmp, True)
shutil.rmtree(self._threadtmp, True)
if self._usechg: