Hello community,
here is the log from the commit of package mercurial for openSUSE:Factory checked in at 2016-04-03 23:04:58
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/mercurial (Old)
and /work/SRC/openSUSE:Factory/.mercurial.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "mercurial"
Changes:
--------
--- /work/SRC/openSUSE:Factory/mercurial/mercurial.changes 2016-03-18 21:36:29.000000000 +0100
+++ /work/SRC/openSUSE:Factory/.mercurial.new/mercurial.changes 2016-04-03 23:04:59.000000000 +0200
@@ -1,0 +2,33 @@
+Wed Mar 30 13:18:23 UTC 2016 - develop7@develop7.info
+
+- update to v3.7.3
+ This is an out of cycle release to address three security issues:
+ * CVE-2016-3630 Mercurial: remote code execution in binary delta decoding
+ Mercurial prior to 3.7.3 contained two bounds-checking errors in its binary
+ delta decoder that may be exploitable via clone, push, or pull.
+ * CVE-2016-3068 Mercurial: arbitrary code execution with Git subrepos
+ Mercurial prior to 3.7.3 allowed URLs for Git subrepos that could result in
+ arbitrary code execution on clone. This is a further side-effect of Git
+ CVE-2015-7545. Reported by Blake Burkhart.
+ * CVE-2016-3069 Mercurial: arbitrary code execution when converting Git repos
+ Mercurial prior to 3.7.3 allowed arbitrary code execution when converting
+ Git repos with hostile names. This could affect automated conversion
+ services. Reported by Blake Burkhart.
+
+ + bdiff: (pure) support array.array arrays (issue5130)
+ + convert: add new, non-clowny interface for shelling out to git (SEC)
+ + convert: dead code removal - old git calling functions (SEC)
+ + convert: rewrite calls to Git to use the new shelling mechanism (SEC)
+ + convert: rewrite gitpipe to use common.commandline (SEC)
+ + convert: test for shell injection in git calls (SEC)
+ + files: don't recurse into subrepos without a path or -S (issue5127)
+ + hg: perform update after pulling during clone with share (issue5103)
+ + mq: restrict generated patch name to 75 characters (issue5117)
+ + obsolete: fix n^2 marker computation behavior
+ + parsers: detect short records (SEC)
+ + parsers: fix list sizing rounding error (SEC)
+ + streamclone: fix error when store files grow while stream cloning
+ + subrepo: adapt to git's recent renames-by-default
+ + subrepo: set GIT_ALLOW_PROTOCOL to limit git clone protocols (SEC)
+
+-------------------------------------------------------------------
Old:
----
mercurial-3.7.2.tar.gz
New:
----
mercurial-3.7.3.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ mercurial.spec ++++++
--- /var/tmp/diff_new_pack.EKpNvL/_old 2016-04-03 23:05:00.000000000 +0200
+++ /var/tmp/diff_new_pack.EKpNvL/_new 2016-04-03 23:05:00.000000000 +0200
@@ -17,7 +17,7 @@
Name: mercurial
-Version: 3.7.2
+Version: 3.7.3
Release: 0
Summary: Scalable Distributed SCM
License: GPL-2.0+
++++++ mercurial-3.7.2.tar.gz -> mercurial-3.7.3.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mercurial-3.7.2/.hgsigs new/mercurial-3.7.3/.hgsigs
--- old/mercurial-3.7.2/.hgsigs 2016-03-02 01:03:50.000000000 +0100
+++ new/mercurial-3.7.3/.hgsigs 2016-03-29 18:54:47.000000000 +0200
@@ -121,3 +121,4 @@
158bdc8965720ca4061f8f8d806563cfc7cdb62e 0 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
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mercurial-3.7.2/.hgtags new/mercurial-3.7.3/.hgtags
--- old/mercurial-3.7.2/.hgtags 2016-03-02 01:03:50.000000000 +0100
+++ new/mercurial-3.7.3/.hgtags 2016-03-29 18:54:47.000000000 +0200
@@ -134,3 +134,4 @@
158bdc8965720ca4061f8f8d806563cfc7cdb62e 3.7-rc
2408645de650d8a29a6ce9e7dce601d8dd0d1474 3.7
b698abf971e7377d9b7ec7fc8c52df45255b0329 3.7.1
+d493d64757eb45ada99fcb3693e479a51b7782da 3.7.2
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mercurial-3.7.2/PKG-INFO new/mercurial-3.7.3/PKG-INFO
--- old/mercurial-3.7.2/PKG-INFO 2016-03-02 01:04:02.000000000 +0100
+++ new/mercurial-3.7.3/PKG-INFO 2016-03-29 18:55:00.000000000 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: mercurial
-Version: 3.7.2
+Version: 3.7.3
Summary: Fast scalable distributed SCM (revision control, version control) system
Home-page: https://mercurial-scm.org/
Author: Matt Mackall and many others
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mercurial-3.7.2/hgext/convert/common.py new/mercurial-3.7.3/hgext/convert/common.py
--- old/mercurial-3.7.2/hgext/convert/common.py 2016-03-02 01:03:43.000000000 +0100
+++ new/mercurial-3.7.3/hgext/convert/common.py 2016-03-29 18:54:44.000000000 +0200
@@ -341,6 +341,9 @@
def _run2(self, cmd, *args, **kwargs):
return self._dorun(util.popen2, cmd, *args, **kwargs)
+ def _run3(self, cmd, *args, **kwargs):
+ return self._dorun(util.popen3, cmd, *args, **kwargs)
+
def _dorun(self, openfunc, cmd, *args, **kwargs):
cmdline = self._cmdline(cmd, *args, **kwargs)
self.ui.debug('running: %s\n' % (cmdline,))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mercurial-3.7.2/hgext/convert/git.py new/mercurial-3.7.3/hgext/convert/git.py
--- old/mercurial-3.7.2/hgext/convert/git.py 2016-03-02 01:03:43.000000000 +0100
+++ new/mercurial-3.7.3/hgext/convert/git.py 2016-03-29 18:54:44.000000000 +0200
@@ -11,7 +11,7 @@
from mercurial.node import hex, nullid
from mercurial.i18n import _
-from common import NoRepo, commit, converter_source, checktool
+from common import NoRepo, commit, converter_source, checktool, commandline
class submodule(object):
def __init__(self, path, node, url):
@@ -25,61 +25,28 @@
def hgsubstate(self):
return "%s %s" % (self.node, self.path)
-class convert_git(converter_source):
+class convert_git(converter_source, commandline):
# Windows does not support GIT_DIR= construct while other systems
# cannot remove environment variable. Just assume none have
# both issues.
- if util.safehasattr(os, 'unsetenv'):
- def gitopen(self, s, err=None):
- prevgitdir = os.environ.get('GIT_DIR')
- os.environ['GIT_DIR'] = self.path
- try:
- if err == subprocess.PIPE:
- (stdin, stdout, stderr) = util.popen3(s)
- return stdout
- elif err == subprocess.STDOUT:
- return self.popen_with_stderr(s)
- else:
- return util.popen(s, 'rb')
- finally:
- if prevgitdir is None:
- del os.environ['GIT_DIR']
- else:
- os.environ['GIT_DIR'] = prevgitdir
- def gitpipe(self, s):
- prevgitdir = os.environ.get('GIT_DIR')
- os.environ['GIT_DIR'] = self.path
- try:
- return util.popen3(s)
- finally:
- if prevgitdir is None:
- del os.environ['GIT_DIR']
- else:
- os.environ['GIT_DIR'] = prevgitdir
+ def _gitcmd(self, cmd, *args, **kwargs):
+ return cmd('--git-dir=%s' % self.path, *args, **kwargs)
- else:
- def gitopen(self, s, err=None):
- if err == subprocess.PIPE:
- (sin, so, se) = util.popen3('GIT_DIR=%s %s' % (self.path, s))
- return so
- elif err == subprocess.STDOUT:
- return self.popen_with_stderr(s)
- else:
- return util.popen('GIT_DIR=%s %s' % (self.path, s), 'rb')
+ def gitrun0(self, *args, **kwargs):
+ return self._gitcmd(self.run0, *args, **kwargs)
- def gitpipe(self, s):
- return util.popen3('GIT_DIR=%s %s' % (self.path, s))
+ def gitrun(self, *args, **kwargs):
+ return self._gitcmd(self.run, *args, **kwargs)
- def popen_with_stderr(self, s):
- p = subprocess.Popen(s, shell=True, bufsize=-1,
- close_fds=util.closefds,
- stdin=subprocess.PIPE,
- stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT,
- universal_newlines=False,
- env=None)
- return p.stdout
+ def gitrunlines0(self, *args, **kwargs):
+ return self._gitcmd(self.runlines0, *args, **kwargs)
+
+ def gitrunlines(self, *args, **kwargs):
+ return self._gitcmd(self.runlines, *args, **kwargs)
+
+ def gitpipe(self, *args, **kwargs):
+ return self._gitcmd(self._run3, *args, **kwargs)
def gitread(self, s):
fh = self.gitopen(s)
@@ -88,6 +55,7 @@
def __init__(self, ui, path, revs=None):
super(convert_git, self).__init__(ui, path, revs=revs)
+ commandline.__init__(self, ui, 'git')
if os.path.isdir(path + "/.git"):
path += "/.git"
@@ -99,20 +67,20 @@
if similarity < 0 or similarity > 100:
raise error.Abort(_('similarity must be between 0 and 100'))
if similarity > 0:
- self.simopt = '-C%d%%' % similarity
+ self.simopt = ['-C%d%%' % similarity]
findcopiesharder = ui.configbool('convert', 'git.findcopiesharder',
False)
if findcopiesharder:
- self.simopt += ' --find-copies-harder'
+ self.simopt.append('--find-copies-harder')
else:
- self.simopt = ''
+ self.simopt = []
checktool('git', 'git')
self.path = path
self.submodules = []
- self.catfilepipe = self.gitpipe('git cat-file --batch')
+ self.catfilepipe = self.gitpipe('cat-file', '--batch')
def after(self):
for f in self.catfilepipe:
@@ -120,14 +88,14 @@
def getheads(self):
if not self.revs:
- heads, ret = self.gitread('git rev-parse --branches --remotes')
- heads = heads.splitlines()
- if ret:
+ output, status = self.gitrun('rev-parse', '--branches', '--remotes')
+ heads = output.splitlines()
+ if status:
raise error.Abort(_('cannot retrieve git heads'))
else:
heads = []
for rev in self.revs:
- rawhead, ret = self.gitread("git rev-parse --verify %s" % rev)
+ rawhead, ret = self.gitrun('rev-parse', '--verify', rev)
heads.append(rawhead[:-1])
if ret:
raise error.Abort(_('cannot retrieve git head "%s"') % rev)
@@ -187,7 +155,7 @@
self.submodules.append(submodule(s['path'], '', s['url']))
def retrievegitmodules(self, version):
- modules, ret = self.gitread("git show %s:%s" % (version, '.gitmodules'))
+ modules, ret = self.gitrun('show', '%s:%s' % (version, '.gitmodules'))
if ret:
# This can happen if a file is in the repo that has permissions
# 160000, but there is no .gitmodules file.
@@ -203,7 +171,7 @@
return
for m in self.submodules:
- node, ret = self.gitread("git rev-parse %s:%s" % (version, m.path))
+ node, ret = self.gitrun('rev-parse', '%s:%s' % (version, m.path))
if ret:
continue
m.node = node.strip()
@@ -212,15 +180,17 @@
if full:
raise error.Abort(_("convert from git does not support --full"))
self.modecache = {}
- fh = self.gitopen("git diff-tree -z --root -m -r %s %s" % (
- self.simopt, version))
+ cmd = ['diff-tree','-z', '--root', '-m', '-r'] + self.simopt + [version]
+ output, status = self.gitrun(*cmd)
+ if status:
+ raise error.Abort(_('cannot read changes in %s') % version)
changes = []
copies = {}
seen = set()
entry = None
subexists = [False]
subdeleted = [False]
- difftree = fh.read().split('\x00')
+ difftree = output.split('\x00')
lcount = len(difftree)
i = 0
@@ -282,8 +252,6 @@
if f != '.gitmodules' and fdest != '.gitmodules':
copies[fdest] = f
entry = None
- if fh.close():
- raise error.Abort(_('cannot read changes in %s') % version)
if subexists[0]:
if subdeleted[0]:
@@ -329,17 +297,23 @@
return c
def numcommits(self):
- return len([None for _ in self.gitopen('git rev-list --all')])
+ output, ret = self.gitrunlines('rev-list', '--all')
+ if ret:
+ raise error.Abort(_('cannot retrieve number of commits in %s') \
+ % self.path)
+ return len(output)
def gettags(self):
tags = {}
alltags = {}
- fh = self.gitopen('git ls-remote --tags "%s"' % self.path,
- err=subprocess.STDOUT)
+ output, status = self.gitrunlines('ls-remote', '--tags', self.path)
+
+ if status:
+ raise error.Abort(_('cannot read tags from %s') % self.path)
prefix = 'refs/tags/'
# Build complete list of tags, both annotated and bare ones
- for line in fh:
+ for line in output:
line = line.strip()
if line.startswith("error:") or line.startswith("fatal:"):
raise error.Abort(_('cannot read tags from %s') % self.path)
@@ -347,8 +321,6 @@
if not tag.startswith(prefix):
continue
alltags[tag[len(prefix):]] = node
- if fh.close():
- raise error.Abort(_('cannot read tags from %s') % self.path)
# Filter out tag objects for annotated tag refs
for tag in alltags:
@@ -365,18 +337,20 @@
def getchangedfiles(self, version, i):
changes = []
if i is None:
- fh = self.gitopen("git diff-tree --root -m -r %s" % version)
- for l in fh:
+ output, status = self.gitrunlines('diff-tree', '--root', '-m',
+ '-r', version)
+ if status:
+ raise error.Abort(_('cannot read changes in %s') % version)
+ for l in output:
if "\t" not in l:
continue
m, f = l[:-1].split("\t")
changes.append(f)
else:
- fh = self.gitopen('git diff-tree --name-only --root -r %s '
- '"%s^%s" --' % (version, version, i + 1))
- changes = [f.rstrip('\n') for f in fh]
- if fh.close():
- raise error.Abort(_('cannot read changes in %s') % version)
+ output, status = self.gitrunlines('diff-tree', '--name-only',
+ '--root', '-r', version,
+ '%s^%s' % (version, i + 1), '--')
+ changes = [f.rstrip('\n') for f in output]
return changes
@@ -396,8 +370,8 @@
])
try:
- fh = self.gitopen('git show-ref', err=subprocess.PIPE)
- for line in fh:
+ output, status = self.gitrunlines('show-ref')
+ for line in output:
line = line.strip()
rev, name = line.split(None, 1)
# Process each type of branch
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mercurial-3.7.2/hgext/mq.py new/mercurial-3.7.3/hgext/mq.py
--- old/mercurial-3.7.2/hgext/mq.py 2016-03-02 01:03:43.000000000 +0100
+++ new/mercurial-3.7.3/hgext/mq.py 2016-03-29 18:54:44.000000000 +0200
@@ -1117,6 +1117,7 @@
"""Return a suitable filename for title, adding a suffix to make
it unique in the existing list"""
namebase = re.sub('[\s\W_]+', '_', title.lower()).strip('_')
+ namebase = namebase[:75] # avoid too long name (issue5117)
if namebase:
try:
self.checkreservedname(namebase)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mercurial-3.7.2/mercurial/__version__.py new/mercurial-3.7.3/mercurial/__version__.py
--- old/mercurial-3.7.2/mercurial/__version__.py 2016-03-02 01:04:00.000000000 +0100
+++ new/mercurial-3.7.3/mercurial/__version__.py 2016-03-29 18:54:57.000000000 +0200
@@ -1,2 +1,2 @@
# this file is autogenerated by setup.py
-version = "3.7.2"
+version = "3.7.3"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mercurial-3.7.2/mercurial/cmdutil.py new/mercurial-3.7.3/mercurial/cmdutil.py
--- old/mercurial-3.7.2/mercurial/cmdutil.py 2016-03-02 01:03:43.000000000 +0100
+++ new/mercurial-3.7.3/mercurial/cmdutil.py 2016-03-29 18:54:44.000000000 +0200
@@ -2340,14 +2340,15 @@
for subpath in sorted(ctx.substate):
def matchessubrepo(subpath):
- return (m.always() or m.exact(subpath)
+ return (m.exact(subpath)
or any(f.startswith(subpath + '/') for f in m.files()))
if subrepos or matchessubrepo(subpath):
sub = ctx.sub(subpath)
try:
submatch = matchmod.narrowmatcher(subpath, m)
- if sub.printfiles(ui, submatch, fm, fmt, subrepos) == 0:
+ recurse = m.exact(subpath) or subrepos
+ if sub.printfiles(ui, submatch, fm, fmt, recurse) == 0:
ret = 0
except error.LookupError:
ui.status(_("skipping missing subrepository: %s\n")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mercurial-3.7.2/mercurial/hg.py new/mercurial-3.7.3/mercurial/hg.py
--- old/mercurial-3.7.2/mercurial/hg.py 2016-03-02 01:03:43.000000000 +0100
+++ new/mercurial-3.7.3/mercurial/hg.py 2016-03-29 18:54:45.000000000 +0200
@@ -236,20 +236,7 @@
r = repository(ui, destwvfs.base)
postshare(srcrepo, r, bookmarks=bookmarks)
-
- if update:
- r.ui.status(_("updating working directory\n"))
- if update is not True:
- checkout = update
- for test in (checkout, 'default', 'tip'):
- if test is None:
- continue
- try:
- uprev = r.lookup(test)
- break
- except error.RepoLookupError:
- continue
- _update(r, uprev)
+ _postshareupdate(r, update, checkout=checkout)
def postshare(sourcerepo, destrepo, bookmarks=True):
"""Called after a new shared repo is created.
@@ -272,6 +259,27 @@
fp.write('bookmarks\n')
fp.close()
+def _postshareupdate(repo, update, checkout=None):
+ """Maybe perform a working directory update after a shared repo is created.
+
+ ``update`` can be a boolean or a revision to update to.
+ """
+ if not update:
+ return
+
+ repo.ui.status(_("updating working directory\n"))
+ if update is not True:
+ checkout = update
+ for test in (checkout, 'default', 'tip'):
+ if test is None:
+ continue
+ try:
+ uprev = repo.lookup(test)
+ break
+ except error.RepoLookupError:
+ continue
+ _update(repo, uprev)
+
def copystore(ui, srcrepo, destpath):
'''copy files from store of srcrepo in destpath
@@ -361,7 +369,7 @@
rev=rev, update=False, stream=stream)
sharerepo = repository(ui, path=sharepath)
- share(ui, sharerepo, dest=dest, update=update, bookmarks=False)
+ share(ui, sharerepo, dest=dest, update=False, bookmarks=False)
# We need to perform a pull against the dest repo to fetch bookmarks
# and other non-store data that isn't shared by default. In the case of
@@ -371,6 +379,8 @@
destrepo = repository(ui, path=dest)
exchange.pull(destrepo, srcpeer, heads=revs)
+ _postshareupdate(destrepo, update)
+
return srcpeer, peer(ui, peeropts, dest)
def clone(ui, peeropts, source, dest=None, pull=False, rev=None,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mercurial-3.7.2/mercurial/mpatch.c new/mercurial-3.7.3/mercurial/mpatch.c
--- old/mercurial-3.7.2/mercurial/mpatch.c 2016-03-02 01:03:43.000000000 +0100
+++ new/mercurial-3.7.3/mercurial/mpatch.c 2016-03-29 18:54:44.000000000 +0200
@@ -205,7 +205,7 @@
int pos = 0;
/* assume worst case size, we won't have many of these lists */
- l = lalloc(len / 12);
+ l = lalloc(len / 12 + 1);
if (!l)
return NULL;
@@ -215,10 +215,10 @@
lt->start = getbe32(bin + pos);
lt->end = getbe32(bin + pos + 4);
lt->len = getbe32(bin + pos + 8);
- if (lt->start > lt->end)
- break; /* sanity check */
lt->data = bin + pos + 12;
pos += 12 + lt->len;
+ if (lt->start > lt->end || lt->len < 0)
+ break; /* sanity check */
lt++;
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mercurial-3.7.2/mercurial/obsolete.py new/mercurial-3.7.3/mercurial/obsolete.py
--- old/mercurial-3.7.2/mercurial/obsolete.py 2016-03-02 01:03:43.000000000 +0100
+++ new/mercurial-3.7.3/mercurial/obsolete.py 2016-03-29 18:54:45.000000000 +0200
@@ -1225,6 +1225,7 @@
metadata['user'] = repo.ui.username()
tr = repo.transaction('add-obsolescence-marker')
try:
+ markerargs = []
for rel in relations:
prec = rel[0]
sucs = rel[1]
@@ -1243,6 +1244,15 @@
npare = tuple(p.node() for p in prec.parents())
if nprec in nsucs:
raise error.Abort("changeset %s cannot obsolete itself" % prec)
+
+ # Creating the marker causes the hidden cache to become invalid,
+ # which causes recomputation when we ask for prec.parents() above.
+ # Resulting in n^2 behavior. So let's prepare all of the args
+ # first, then create the markers.
+ markerargs.append((nprec, nsucs, npare, localmetadata))
+
+ for args in markerargs:
+ nprec, nsucs, npare, localmetadata = args
repo.obsstore.create(tr, nprec, nsucs, flag, parents=npare,
date=date, metadata=localmetadata)
repo.filteredrevcache.clear()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mercurial-3.7.2/mercurial/pure/bdiff.py new/mercurial-3.7.3/mercurial/pure/bdiff.py
--- old/mercurial-3.7.2/mercurial/pure/bdiff.py 2016-03-02 01:03:43.000000000 +0100
+++ new/mercurial-3.7.3/mercurial/pure/bdiff.py 2016-03-29 18:54:44.000000000 +0200
@@ -7,6 +7,7 @@
from __future__ import absolute_import
+import array
import difflib
import re
import struct
@@ -50,9 +51,15 @@
r.append(prev)
return r
+def _tostring(c):
+ if type(c) is array.array:
+ # this copy overhead isn't ideal
+ return c.tostring()
+ return str(c)
+
def bdiff(a, b):
- a = str(a).splitlines(True)
- b = str(b).splitlines(True)
+ a = _tostring(a).splitlines(True)
+ b = _tostring(b).splitlines(True)
if not a:
s = "".join(b)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mercurial-3.7.2/mercurial/streamclone.py new/mercurial-3.7.3/mercurial/streamclone.py
--- old/mercurial-3.7.2/mercurial/streamclone.py 2016-03-02 01:03:43.000000000 +0100
+++ new/mercurial-3.7.3/mercurial/streamclone.py 2016-03-29 18:54:45.000000000 +0200
@@ -206,7 +206,8 @@
# partially encode name over the wire for backwards compat
yield '%s\0%d\n' % (store.encodedir(name), size)
if size <= 65536:
- yield svfs.read(name)
+ with svfs(name, 'rb') as fp:
+ yield fp.read(size)
else:
for chunk in util.filechunkiter(svfs(name), limit=size):
yield chunk
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mercurial-3.7.2/mercurial/subrepo.py new/mercurial-3.7.3/mercurial/subrepo.py
--- old/mercurial-3.7.2/mercurial/subrepo.py 2016-03-02 01:03:43.000000000 +0100
+++ new/mercurial-3.7.3/mercurial/subrepo.py 2016-03-29 18:54:45.000000000 +0200
@@ -1383,6 +1383,11 @@
are not supported and very probably fail.
"""
self.ui.debug('%s: git %s\n' % (self._relpath, ' '.join(commands)))
+ if env is None:
+ env = os.environ.copy()
+ # fix for Git CVE-2015-7545
+ if 'GIT_ALLOW_PROTOCOL' not in env:
+ env['GIT_ALLOW_PROTOCOL'] = 'file:git:http:https:ssh'
# unless ui.quiet is set, print git's stderr,
# which is mostly progress and useful info
errpipe = None
@@ -1810,9 +1815,9 @@
modified, added, removed = [], [], []
self._gitupdatestat()
if rev2:
- command = ['diff-tree', '-r', rev1, rev2]
+ command = ['diff-tree', '--no-renames', '-r', rev1, rev2]
else:
- command = ['diff-index', rev1]
+ command = ['diff-index', '--no-renames', rev1]
out = self._gitcommand(command)
for line in out.split('\n'):
tab = line.find('\t')
@@ -1871,7 +1876,7 @@
@annotatesubrepoerror
def diff(self, ui, diffopts, node2, match, prefix, **opts):
node1 = self._state[1]
- cmd = ['diff']
+ cmd = ['diff', '--no-renames']
if opts['stat']:
cmd.append('--stat')
else:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mercurial-3.7.2/tests/hypothesishelpers.py new/mercurial-3.7.3/tests/hypothesishelpers.py
--- old/mercurial-3.7.2/tests/hypothesishelpers.py 2016-03-02 01:03:43.000000000 +0100
+++ new/mercurial-3.7.3/tests/hypothesishelpers.py 2016-03-29 18:54:45.000000000 +0200
@@ -8,9 +8,16 @@
import sys
import traceback
-from hypothesis.settings import set_hypothesis_home_dir
+try:
+ # hypothesis 2.x
+ from hypothesis.configuration import set_hypothesis_home_dir
+ from hypothesis import settings
+except ImportError:
+ # hypothesis 1.x
+ from hypothesis.settings import set_hypothesis_home_dir
+ from hypothesis import Settings as settings
import hypothesis.strategies as st
-from hypothesis import given, Settings
+from hypothesis import given
# hypothesis store data regarding generate example and code
set_hypothesis_home_dir(os.path.join(
@@ -26,7 +33,7 @@
# Fixed in version 1.13 (released 2015 october 29th)
f.__module__ = '__anon__'
try:
- given(*args, settings=Settings(max_examples=2000), **kwargs)(f)()
+ given(*args, settings=settings(max_examples=2000), **kwargs)(f)()
except Exception:
traceback.print_exc(file=sys.stdout)
sys.exit(1)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mercurial-3.7.2/tests/test-clone-uncompressed.t new/mercurial-3.7.3/tests/test-clone-uncompressed.t
--- old/mercurial-3.7.2/tests/test-clone-uncompressed.t 2016-03-02 01:03:43.000000000 +0100
+++ new/mercurial-3.7.3/tests/test-clone-uncompressed.t 2016-03-29 18:54:45.000000000 +0200
@@ -1,5 +1,8 @@
#require serve
+Initialize repository
+the status call is to check for issue5130
+
$ hg init server
$ cd server
$ touch foo
@@ -8,6 +11,7 @@
... with open(str(i), 'wb') as fh:
... fh.write(str(i))
$ hg -q commit -A -m 'add a lot of files'
+ $ hg st
$ hg serve -p $HGPORT -d --pid-file=hg.pid
$ cat hg.pid >> $DAEMON_PIDS
$ cd ..
@@ -46,3 +50,43 @@
preparing listkeys for "phases"
sending listkeys command
received listkey for "phases": 58 bytes
+
+
+Stream clone while repo is changing:
+
+ $ mkdir changing
+ $ cd changing
+
+extension for delaying the server process so we reliably can modify the repo
+while cloning
+
+ $ cat > delayer.py <