--- a/contrib/bash_completion Tue Nov 10 09:58:10 2015 -0800
+++ b/contrib/bash_completion Thu Nov 12 13:51:09 2015 -0600
@@ -629,7 +629,7 @@
_hg_cmd_shelve()
{
- if [[ "$prev" = @(-d|--delete|-l|--list) ]]; then
+ if [[ "$prev" = @(-d|--delete|-l|--list|-p|--patch|--stat) ]]; then
_hg_shelves
else
_hg_status "mard"
--- a/hgext/rebase.py Tue Nov 10 09:58:10 2015 -0800
+++ b/hgext/rebase.py Thu Nov 12 13:51:09 2015 -0600
@@ -48,6 +48,9 @@
s = ctx.extra().get('source', None)
if s is not None:
extra['source'] = s
+ s = ctx.extra().get('intermediate-source', None)
+ if s is not None:
+ extra['intermediate-source'] = s
def _savebranch(ctx, extra):
extra['branch'] = ctx.branch()
@@ -220,6 +223,7 @@
abortf = opts.get('abort')
collapsef = opts.get('collapse', False)
collapsemsg = cmdutil.logmessage(ui, opts)
+ date = opts.get('date', None)
e = opts.get('extrafn') # internal, used by e.g. hgsubversion
extrafns = [_savegraft]
if e:
@@ -454,7 +458,8 @@
editor = cmdutil.getcommiteditor(editform=editform, **opts)
newnode = concludenode(repo, rev, p1, p2, extrafn=extrafn,
editor=editor,
- keepbranches=keepbranchesf)
+ keepbranches=keepbranchesf,
+ date=date)
else:
# Skip commit if we are collapsing
repo.dirstate.beginparentchange()
@@ -505,7 +510,8 @@
editor = cmdutil.getcommiteditor(edit=editopt, editform=editform)
newnode = concludenode(repo, rev, p1, external, commitmsg=commitmsg,
extrafn=extrafn, editor=editor,
- keepbranches=keepbranchesf)
+ keepbranches=keepbranchesf,
+ date=date)
if newnode is None:
newrev = target
else:
@@ -586,7 +592,7 @@
', '.join(str(p) for p in sorted(parents))))
def concludenode(repo, rev, p1, p2, commitmsg=None, editor=None, extrafn=None,
- keepbranches=False):
+ keepbranches=False, date=None):
'''Commit the wd changes with parents p1 and p2. Reuse commit info from rev
but also store useful information in extra.
Return node of committed revision.'''
@@ -608,8 +614,10 @@
if keepbranch:
repo.ui.setconfig('ui', 'allowemptycommit', True)
# Commit might fail if unresolved files exist
+ if date is None:
+ date = ctx.date()
newnode = repo.commit(text=commitmsg, user=ctx.user(),
- date=ctx.date(), extra=extra, editor=editor)
+ date=date, extra=extra, editor=editor)
finally:
repo.ui.restoreconfig(backup)
--- a/mercurial/commands.py Tue Nov 10 09:58:10 2015 -0800
+++ b/mercurial/commands.py Thu Nov 12 13:51:09 2015 -0600
@@ -5655,7 +5655,11 @@
else:
# backup pre-resolve (merge uses .orig for its own purposes)
a = repo.wjoin(f)
- util.copyfile(a, a + ".resolve")
+ try:
+ util.copyfile(a, a + ".resolve")
+ except (IOError, OSError) as inst:
+ if inst.errno != errno.ENOENT:
+ raise
try:
# preresolve file
@@ -5673,7 +5677,11 @@
# replace filemerge's .orig file with our resolve file
# for files in tocomplete, ms.resolve will not overwrite
# .orig -- only preresolve does
- util.rename(a + ".resolve", a + ".orig")
+ try:
+ util.rename(a + ".resolve", a + ".orig")
+ except OSError as inst:
+ if inst.errno != errno.ENOENT:
+ raise
for f in tocomplete:
try:
@@ -6578,10 +6586,10 @@
tr.close()
except error.BundleUnknownFeatureError as exc:
raise error.Abort(_('%s: unknown bundle feature, %s')
- % (fname, exc),
- hint=_("see https://mercurial-scm.org/"
- "wiki/BundleFeature for more "
- "information"))
+ % (fname, exc),
+ hint=_("see https://mercurial-scm.org/"
+ "wiki/BundleFeature for more "
+ "information"))
finally:
if tr:
tr.release()
--- a/mercurial/discovery.py Tue Nov 10 09:58:10 2015 -0800
+++ b/mercurial/discovery.py Thu Nov 12 13:51:09 2015 -0600
@@ -238,6 +238,23 @@
unsynced = set()
return {None: (oldheads, newheads, unsynced)}
+def _nowarnheads(repo, remote, newbookmarks):
+ # Compute newly pushed bookmarks. We don't warn about bookmarked heads.
+ localbookmarks = repo._bookmarks
+ remotebookmarks = remote.listkeys('bookmarks')
+ bookmarkedheads = set()
+ for bm in localbookmarks:
+ rnode = remotebookmarks.get(bm)
+ if rnode and rnode in repo:
+ lctx, rctx = repo[bm], repo[rnode]
+ if bookmarks.validdest(repo, rctx, lctx):
+ bookmarkedheads.add(lctx.node())
+ else:
+ if bm in newbookmarks and bm not in remotebookmarks:
+ bookmarkedheads.add(repo[bm].node())
+
+ return bookmarkedheads
+
def checkheads(repo, remote, outgoing, remoteheads, newbranch=False, inc=False,
newbookmarks=[]):
"""Check that a push won't add any outgoing head
@@ -268,19 +285,8 @@
hint=_("use 'hg push --new-branch' to create"
" new remote branches"))
- # 2. Compute newly pushed bookmarks. We don't warn about bookmarked heads.
- localbookmarks = repo._bookmarks
- remotebookmarks = remote.listkeys('bookmarks')
- bookmarkedheads = set()
- for bm in localbookmarks:
- rnode = remotebookmarks.get(bm)
- if rnode and rnode in repo:
- lctx, rctx = repo[bm], repo[rnode]
- if bookmarks.validdest(repo, rctx, lctx):
- bookmarkedheads.add(lctx.node())
- else:
- if bm in newbookmarks and bm not in remotebookmarks:
- bookmarkedheads.add(repo[bm].node())
+ # 2. Find heads that we need not warn about
+ nowarnheads = _nowarnheads(repo, remote, newbookmarks)
# 3. Check for new heads.
# If there are more heads after the push than before, a suitable
@@ -366,7 +372,7 @@
" pushing new heads")
elif len(newhs) > len(oldhs):
# remove bookmarked or existing remote heads from the new heads list
- dhs = sorted(newhs - bookmarkedheads - oldhs)
+ dhs = sorted(newhs - nowarnheads - oldhs)
if dhs:
if errormsg is None:
if branch not in ('default', None):
--- a/mercurial/encoding.py Tue Nov 10 09:58:10 2015 -0800
+++ b/mercurial/encoding.py Thu Nov 12 13:51:09 2015 -0600
@@ -414,6 +414,25 @@
return ''.join(_jsonmap[c] for c in toutf8b(s))
+_utf8len = [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 4]
+
+def getutf8char(s, pos):
+ '''get the next full utf-8 character in the given string, starting at pos
+
+ Raises a UnicodeError if the given location does not start a valid
+ utf-8 character.
+ '''
+
+ # find how many bytes to attempt decoding from first nibble
+ l = _utf8len[ord(s[pos]) >> 4]
+ if not l: # ascii
+ return s[pos]
+
+ c = s[pos:pos + l]
+ # validate with attempted decode
+ c.decode("utf-8")
+ return c
+
def toutf8b(s):
'''convert a local, possibly-binary string into UTF-8b
@@ -444,24 +463,32 @@
internal surrogate encoding as a UTF-8 string.)
'''
- if isinstance(s, localstr):
- return s._utf8
+ if "\xed" not in s:
+ if isinstance(s, localstr):
+ return s._utf8
+ try:
+ s.decode('utf-8')
+ return s
+ except UnicodeDecodeError:
+ pass
- try:
- s.decode('utf-8')
- return s
- except UnicodeDecodeError:
- # surrogate-encode any characters that don't round-trip
- s2 = s.decode('utf-8', 'ignore').encode('utf-8')
- r = ""
- pos = 0
- for c in s:
- if s2[pos:pos + 1] == c:
- r += c
+ r = ""
+ pos = 0
+ l = len(s)
+ while pos < l:
+ try:
+ c = getutf8char(s, pos)
+ if "\xed\xb0\x80" <= c <= "\xed\xb3\xbf":
+ # have to re-escape existing U+DCxx characters
+ c = unichr(0xdc00 + ord(s[pos])).encode('utf-8')
pos += 1
else:
- r += unichr(0xdc00 + ord(c)).encode('utf-8')
- return r
+ pos += len(c)
+ except UnicodeDecodeError:
+ c = unichr(0xdc00 + ord(s[pos])).encode('utf-8')
+ pos += 1
+ r += c
+ return r
def fromutf8b(s):
'''Given a UTF-8b string, return a local, possibly-binary string.
@@ -485,7 +512,7 @@
u = s.decode("utf-8")
r = ""
for c in u:
- if ord(c) & 0xff00 == 0xdc00:
+ if ord(c) & 0xffff00 == 0xdc00:
r += chr(ord(c) & 0xff)
else:
r += c.encode("utf-8")
--- a/mercurial/error.py Tue Nov 10 09:58:10 2015 -0800
+++ b/mercurial/error.py Thu Nov 12 13:51:09 2015 -0600
@@ -72,6 +72,12 @@
class UpdateAbort(Abort):
"""Raised when an update is aborted for destination issue"""
+class ResponseExpected(Abort):
+ """Raised when an EOF is received for a prompt"""
+ def __init__(self):
+ from .i18n import _
+ Abort.__init__(self, _('response expected'))
+
class OutOfBandError(Exception):
"""Exception raised when a remote repo reports failure"""
--- a/mercurial/filemerge.py Tue Nov 10 09:58:10 2015 -0800
+++ b/mercurial/filemerge.py Thu Nov 12 13:51:09 2015 -0600
@@ -175,12 +175,19 @@
ui = repo.ui
fd = fcd.path()
- if ui.promptchoice(_(" no tool found to merge %s\n"
- "keep (l)ocal or take (o)ther?"
- "$$ &Local $$ &Other") % fd, 0):
- return _iother(repo, mynode, orig, fcd, fco, fca, toolconf)
- else:
- return _ilocal(repo, mynode, orig, fcd, fco, fca, toolconf)
+ try:
+ index = ui.promptchoice(_(" no tool found to merge %s\n"
+ "keep (l)ocal or take (o)ther?"
+ "$$ &Local $$ &Other") % fd, 0)
+ choice = ['local', 'other'][index]
+
+ if choice == 'other':
+ return _iother(repo, mynode, orig, fcd, fco, fca, toolconf)
+ else:
+ return _ilocal(repo, mynode, orig, fcd, fco, fca, toolconf)
+ except error.ResponseExpected:
+ ui.write("\n")
+ return 1
@internaltool('local', nomerge)
def _ilocal(repo, mynode, orig, fcd, fco, fca, toolconf):
@@ -305,16 +312,12 @@
"""
assert localorother is not None
tool, toolpath, binary, symlink = toolconf
- if symlink:
- repo.ui.warn(_('warning: :merge-%s cannot merge symlinks '
- 'for %s\n') % (localorother, fcd.path()))
- return False, 1
a, b, c, back = files
r = simplemerge.simplemerge(repo.ui, a, b, c, label=labels,
localorother=localorother)
return True, r
-@internaltool('merge-local', mergeonly)
+@internaltool('merge-local', mergeonly, precheck=_symlinkcheck)
def _imergelocal(*args, **kwargs):
"""
Like :merge, but resolve all conflicts non-interactively in favor
@@ -322,7 +325,7 @@
success, status = _imergeauto(localorother='local', *args, **kwargs)
return success, status
-@internaltool('merge-other', mergeonly)
+@internaltool('merge-other', mergeonly, precheck=_symlinkcheck)
def _imergeother(*args, **kwargs):
"""
Like :merge, but resolve all conflicts non-interactively in favor
--- a/mercurial/help.py Tue Nov 10 09:58:10 2015 -0800
+++ b/mercurial/help.py Thu Nov 12 13:51:09 2015 -0600
@@ -115,20 +115,20 @@
doclines = docs.splitlines()
if doclines:
summary = doclines[0]
- cmdname = cmd.split('|')[0].lstrip('^')
+ cmdname = cmd.partition('|')[0].lstrip('^')
results['commands'].append((cmdname, summary))
for name, docs in itertools.chain(
extensions.enabled(False).iteritems(),
extensions.disabled().iteritems()):
# extensions.load ignores the UI argument
mod = extensions.load(None, name, '')
- name = name.split('.')[-1]
+ name = name.rpartition('.')[-1]
if lowercontains(name) or lowercontains(docs):
# extension docs are already translated
results['extensions'].append((name, docs.splitlines()[0]))
for cmd, entry in getattr(mod, 'cmdtable', {}).iteritems():
if kw in cmd or (len(entry) > 2 and lowercontains(entry[2])):
- cmdname = cmd.split('|')[0].lstrip('^')
+ cmdname = cmd.partition('|')[0].lstrip('^')
if entry[0].__doc__:
cmddoc = gettext(entry[0].__doc__).splitlines()[0]
else:
@@ -330,7 +330,7 @@
h = {}
cmds = {}
for c, e in commands.table.iteritems():
- f = c.split("|", 1)[0]
+ f = c.partition("|")[0]
if select and not select(f):
continue
if (not select and name != 'shortlist' and
@@ -445,7 +445,7 @@
head, tail = doc, ""
else:
head, tail = doc.split('\n', 1)
- rst = [_('%s extension - %s\n\n') % (name.split('.')[-1], head)]
+ rst = [_('%s extension - %s\n\n') % (name.rpartition('.')[-1], head)]
if tail:
rst.extend(tail.splitlines(True))
rst.append('\n')
@@ -460,7 +460,7 @@
ct = mod.cmdtable
except AttributeError:
ct = {}
- modcmds = set([c.split('|', 1)[0] for c in ct])
+ modcmds = set([c.partition('|')[0] for c in ct])
rst.extend(helplist(modcmds.__contains__))
else:
rst.append(_('(use "hg help extensions" for information on enabling'
--- a/mercurial/help/config.txt Tue Nov 10 09:58:10 2015 -0800
+++ b/mercurial/help/config.txt Thu Nov 12 13:51:09 2015 -0600
@@ -666,6 +666,14 @@
``format``
----------
+``usegeneraldelta``
+ Enable or disable the "generaldelta" repository format which improves
+ repository compression by allowing "revlog" to store delta against arbitrary
+ revision instead of the previous stored one. This provides significant
+ improvement for repositories with branches. Disabling this option ensures that
+ the on-disk format of newly created repository will be compatible with
+ Mercurial before version 1.9.
+
``usestore``
Enable or disable the "store" repository format which improves
compatibility with systems that fold case or otherwise mangle
--- a/mercurial/hgweb/hgweb_mod.py Tue Nov 10 09:58:10 2015 -0800
+++ b/mercurial/hgweb/hgweb_mod.py Thu Nov 12 13:51:09 2015 -0600
@@ -304,8 +304,8 @@
parts = parts[len(repo_parts):]
query = '/'.join(parts)
else:
- query = req.env['QUERY_STRING'].split('&', 1)[0]
- query = query.split(';', 1)[0]
+ query = req.env['QUERY_STRING'].partition('&')[0]
+ query = query.partition(';')[0]
# process this if it's a protocol request
# protocol bits don't need to create any URLs
--- a/mercurial/hgweb/request.py Tue Nov 10 09:58:10 2015 -0800
+++ b/mercurial/hgweb/request.py Thu Nov 12 13:51:09 2015 -0600
@@ -80,7 +80,7 @@
if self._start_response is not None:
self.headers.append(('Content-Type', type))
if filename:
- filename = (filename.split('/')[-1]
+ filename = (filename.rpartition('/')[-1]
.replace('\\', '\\\\').replace('"', '\\"'))
self.headers.append(('Content-Disposition',
'inline; filename="%s"' % filename))
--- a/mercurial/hgweb/server.py Tue Nov 10 09:58:10 2015 -0800
+++ b/mercurial/hgweb/server.py Thu Nov 12 13:51:09 2015 -0600
@@ -197,47 +197,6 @@
self.wfile.write('0\r\n\r\n')
self.wfile.flush()
-class _httprequesthandleropenssl(_httprequesthandler):
- """HTTPS handler based on pyOpenSSL"""
-
- url_scheme = 'https'
-
- @staticmethod
- def preparehttpserver(httpserver, ssl_cert):
- try:
- import OpenSSL
- OpenSSL.SSL.Context
- except ImportError:
- raise error.Abort(_("SSL support is unavailable"))
- ctx = OpenSSL.SSL.Context(OpenSSL.SSL.TLSv1_METHOD)
- ctx.use_privatekey_file(ssl_cert)
- ctx.use_certificate_file(ssl_cert)
- sock = socket.socket(httpserver.address_family, httpserver.socket_type)
- httpserver.socket = OpenSSL.SSL.Connection(ctx, sock)
- httpserver.server_bind()
- httpserver.server_activate()
-
- def setup(self):
- self.connection = self.request
- self.rfile = socket._fileobject(self.request, "rb", self.rbufsize)
- self.wfile = socket._fileobject(self.request, "wb", self.wbufsize)
-
- def do_write(self):
- import OpenSSL
- try:
- _httprequesthandler.do_write(self)
- except OpenSSL.SSL.SysCallError as inst:
- if inst.args[0] != errno.EPIPE:
- raise
-
- def handle_one_request(self):
- import OpenSSL
- try:
- _httprequesthandler.handle_one_request(self)
- except (OpenSSL.SSL.SysCallError, OpenSSL.SSL.ZeroReturnError):
- self.close_connection = True
- pass
-
class _httprequesthandlerssl(_httprequesthandler):
"""HTTPS handler based on Python's ssl module"""
@@ -311,10 +270,7 @@
def create_server(ui, app):
if ui.config('web', 'certificate'):
- if sys.version_info >= (2, 6):
- handler = _httprequesthandlerssl
- else:
- handler = _httprequesthandleropenssl
+ handler = _httprequesthandlerssl
else:
handler = _httprequesthandler
--- a/mercurial/hgweb/webcommands.py Tue Nov 10 09:58:10 2015 -0800
+++ b/mercurial/hgweb/webcommands.py Thu Nov 12 13:51:09 2015 -0600
@@ -264,8 +264,8 @@
yield tmpl('searchentry',
parity=parity.next(),
author=ctx.user(),
- parent=webutil.parents(ctx),
- child=webutil.children(ctx),
+ parent=lambda **x: webutil.parents(ctx),
+ child=lambda **x: webutil.children(ctx),
changelogtag=showtags,
desc=ctx.description(),
extra=ctx.extra(),
@@ -1000,8 +1000,8 @@
"author": iterfctx.user(),
"date": iterfctx.date(),
"rename": webutil.renamelink(iterfctx),
- "parent": webutil.parents(iterfctx),
- "child": webutil.children(iterfctx),
+ "parent": lambda **x: webutil.parents(iterfctx),
+ "child": lambda **x: webutil.children(iterfctx),
"desc": iterfctx.description(),
"extra": iterfctx.extra(),
"tags": webutil.nodetagsdict(repo, iterfctx.node()),
@@ -1248,7 +1248,7 @@
def _getdoc(e):
doc = e[0].__doc__
if doc:
- doc = _(doc).split('\n')[0]
+ doc = _(doc).partition('\n')[0]
else:
doc = _('(no help text available)')
return doc
@@ -1278,7 +1278,7 @@
yield {'topic': entries[0], 'summary': summary}
early, other = [], []
- primary = lambda s: s.split('|')[0]
+ primary = lambda s: s.partition('|')[0]
for c, e in commands.table.iteritems():
doc = _getdoc(e)
if 'DEPRECATED' in doc or c.startswith('debug'):
--- a/mercurial/hgweb/webutil.py Tue Nov 10 09:58:10 2015 -0800
+++ b/mercurial/hgweb/webutil.py Thu Nov 12 13:51:09 2015 -0600
@@ -297,8 +297,8 @@
return {
"author": ctx.user(),
- "parent": parents(ctx, rev - 1),
- "child": children(ctx, rev + 1),
+ "parent": lambda **x: parents(ctx, rev - 1),
+ "child": lambda **x: children(ctx, rev + 1),
"changelogtag": showtags,
"desc": ctx.description(),
"extra": ctx.extra(),
--- a/mercurial/localrepo.py Tue Nov 10 09:58:10 2015 -0800
+++ b/mercurial/localrepo.py Thu Nov 12 13:51:09 2015 -0600
@@ -258,8 +258,7 @@
'\0\0\0\2' # represents revlogv2
' dummy changelog to prevent using the old repo layout'
)
- # experimental config: format.generaldelta
- if self.ui.configbool('format', 'generaldelta', False):
+ if scmutil.gdinitconfig(self.ui):
self.requirements.add("generaldelta")
if self.ui.configbool('experimental', 'treemanifest', False):
self.requirements.add("treemanifest")
@@ -359,6 +358,7 @@
aggressivemergedeltas = self.ui.configbool('format',
'aggressivemergedeltas', False)
self.svfs.options['aggressivemergedeltas'] = aggressivemergedeltas
+ self.svfs.options['lazydeltabase'] = not scmutil.gddeltaconfig(self.ui)
def _writerequirements(self):
scmutil.writerequires(self.vfs, self.requirements)
--- a/mercurial/manifest.py Tue Nov 10 09:58:10 2015 -0800
+++ b/mercurial/manifest.py Thu Nov 12 13:51:09 2015 -0600
@@ -334,36 +334,44 @@
# zero copy representation of base as a buffer
addbuf = util.buffer(base)
- # start with a readonly loop that finds the offset of
- # each line and creates the deltas
- for f, todelete in changes:
- # bs will either be the index of the item or the insert point
- start, end = _msearch(addbuf, f, start)
- if not todelete:
- h, fl = self._lm[f]
- l = "%s\0%s%s\n" % (f, revlog.hex(h), fl)
- else:
- if start == end:
- # item we want to delete was not found, error out
- raise AssertionError(
- _("failed to remove %s from manifest") % f)
- l = ""
- if dstart is not None and dstart <= start and dend >= start:
- if dend < end:
+ changes = list(changes)
+ if len(changes) < 1000:
+ # start with a readonly loop that finds the offset of
+ # each line and creates the deltas
+ for f, todelete in changes:
+ # bs will either be the index of the item or the insert point
+ start, end = _msearch(addbuf, f, start)
+ if not todelete:
+ h, fl = self._lm[f]
+ l = "%s\0%s%s\n" % (f, revlog.hex(h), fl)
+ else:
+ if start == end:
+ # item we want to delete was not found, error out
+ raise AssertionError(
+ _("failed to remove %s from manifest") % f)
+ l = ""
+ if dstart is not None and dstart <= start and dend >= start:
+ if dend < end:
+ dend = end
+ if l:
+ dline.append(l)
+ else:
+ if dstart is not None:
+ delta.append([dstart, dend, "".join(dline)])
+ dstart = start
dend = end
- if l:
- dline.append(l)
- else:
- if dstart is not None:
- delta.append([dstart, dend, "".join(dline)])
- dstart = start
- dend = end
- dline = [l]
+ dline = [l]
- if dstart is not None:
- delta.append([dstart, dend, "".join(dline)])
- # apply the delta to the base, and get a delta for addrevision
- deltatext, arraytext = _addlistdelta(base, delta)
+ if dstart is not None:
+ delta.append([dstart, dend, "".join(dline)])
+ # apply the delta to the base, and get a delta for addrevision
+ deltatext, arraytext = _addlistdelta(base, delta)
+ else:
+ # For large changes, it's much cheaper to just build the text and
+ # diff it.
+ arraytext = array.array('c', self.text())
+ deltatext = mdiff.textdiff(base, arraytext)
+
return arraytext, deltatext
def _msearch(m, s, lo=0, hi=None):
--- a/mercurial/merge.py Tue Nov 10 09:58:10 2015 -0800
+++ b/mercurial/merge.py Thu Nov 12 13:51:09 2015 -0600
@@ -395,10 +395,15 @@
return complete, r
def preresolve(self, dfile, wctx, labels=None):
+ """run premerge process for dfile
+
+ Returns whether the merge is complete, and the exit code."""
return self._resolve(True, dfile, wctx, labels=labels)
def resolve(self, dfile, wctx, labels=None):
- """rerun merge process for file path `dfile`"""
+ """run merge process (assuming premerge was run) for dfile
+
+ Returns the exit code of the merge."""
return self._resolve(False, dfile, wctx, labels=labels)[1]
def _checkunknownfile(repo, wctx, mctx, f, f2=None):
--- a/mercurial/posix.py Tue Nov 10 09:58:10 2015 -0800
+++ b/mercurial/posix.py Thu Nov 12 13:51:09 2015 -0600
@@ -261,40 +261,17 @@
except UnicodeDecodeError:
# OS X percent-encodes any bytes that aren't valid utf-8
s = ''
- g = ''
- l = 0
- for c in path:
- o = ord(c)
- if l and o < 128 or o >= 192:
- # we want a continuation byte, but didn't get one
- s += ''.join(["%%%02X" % ord(x) for x in g])
- g = ''
- l = 0
- if l == 0 and o < 128:
- # ascii
- s += c
- elif l == 0 and 194 <= o < 245:
- # valid leading bytes
- if o < 224:
- l = 1
- elif o < 240:
- l = 2
- else:
- l = 3
- g = c
- elif l > 0 and 128 <= o < 192:
- # valid continuations
- g += c
- l -= 1
- if not l:
- s += g
- g = ''
- else:
- # invalid
- s += "%%%02X" % o
+ pos = 0
+ l = len(s)
+ while pos < l:
+ try:
+ c = encoding.getutf8char(path, pos)
+ pos += len(c)
+ except ValueError:
+ c = '%%%%02X' % path[pos]
+ pos += 1
+ s += c
- # any remaining partial characters
- s += ''.join(["%%%02X" % ord(x) for x in g])
u = s.decode('utf-8')
# Decompose then lowercase (HFS+ technote specifies lower)
--- a/mercurial/revlog.py Tue Nov 10 09:58:10 2015 -0800
+++ b/mercurial/revlog.py Thu Nov 12 13:51:09 2015 -0600
@@ -230,6 +230,7 @@
self._maxchainlen = opts['maxchainlen']
if 'aggressivemergedeltas' in opts:
self._aggressivemergedeltas = opts['aggressivemergedeltas']
+ self._lazydeltabase = bool(opts.get('lazydeltabase', False))
if self._chunkcachesize <= 0:
raise RevlogError(_('revlog chunk cache size %r is not greater '
@@ -1370,7 +1371,11 @@
# should we try to build a delta?
if prev != nullrev:
- if self._generaldelta:
+ if cachedelta and self._generaldelta and self._lazydeltabase:
+ # Assume what we received from the server is a good choice
+ # build delta will reuse the cache
+ d = builddelta(cachedelta[0])
+ elif self._generaldelta:
if p2r != nullrev and self._aggressivemergedeltas:
d = builddelta(p1r)
d2 = builddelta(p2r)
--- a/mercurial/scmutil.py Tue Nov 10 09:58:10 2015 -0800
+++ b/mercurial/scmutil.py Thu Nov 12 13:51:09 2015 -0600
@@ -1170,3 +1170,16 @@
subprocess."""
return _locksub(repo, repo.currentwlock(), 'HG_WLOCK_LOCKER', cmd, *args,
**kwargs)
+
+def gdinitconfig(ui):
+ """helper function to know if a repo should be created as general delta
+ """
+ # experimental config: format.generaldelta
+ return (ui.configbool('format', 'generaldelta', False)
+ or ui.configbool('format', 'usegeneraldelta', False))
+
+def gddeltaconfig(ui):
+ """helper function to know if incoming delta should be optimised
+ """
+ # experimental config: format.generaldelta
+ return ui.configbool('format', 'generaldelta', False)
--- a/mercurial/templatefilters.py Tue Nov 10 09:58:10 2015 -0800
+++ b/mercurial/templatefilters.py Thu Nov 12 13:51:09 2015 -0600
@@ -223,7 +223,7 @@
raise TypeError('cannot encode type %s' % obj.__class__.__name__)
def _uescape(c):
- if ord(c) < 0x80:
+ if 0x20 <= ord(c) < 0x80:
return c
else:
return '\\u%04x' % ord(c)
--- a/mercurial/templates/static/mercurial.js Tue Nov 10 09:58:10 2015 -0800
+++ b/mercurial/templates/static/mercurial.js Thu Nov 12 13:51:09 2015 -0600
@@ -50,18 +50,6 @@
this.cell_height = this.box_size;
}
- function colorPart(num) {
- num *= 255
- num = num < 0 ? 0 : num;
- num = num > 255 ? 255 : num;
- var digits = Math.round(num).toString(16);
- if (num < 16) {
- return '0' + digits;
- } else {
- return digits;
- }
- }
-
this.setColor = function(color, bg, fg) {
// Set the colour.
--- a/mercurial/ui.py Tue Nov 10 09:58:10 2015 -0800
+++ b/mercurial/ui.py Thu Nov 12 13:51:09 2015 -0600
@@ -756,7 +756,7 @@
self.write(r, "\n")
return r
except EOFError:
- raise error.Abort(_('response expected'))
+ raise error.ResponseExpected()
@staticmethod
def extractchoices(prompt):
@@ -803,7 +803,7 @@
else:
return getpass.getpass('')
except EOFError:
- raise error.Abort(_('response expected'))
+ raise error.ResponseExpected()
def status(self, *msg, **opts):
'''write status message to output (if ui.quiet is False)
--- a/mercurial/util.py Tue Nov 10 09:58:10 2015 -0800
+++ b/mercurial/util.py Thu Nov 12 13:51:09 2015 -0600
@@ -91,39 +91,7 @@
def safehasattr(thing, attr):
return getattr(thing, attr, _notset) is not _notset
-def sha1(s=''):
- '''
- Low-overhead wrapper around Python's SHA support
-
- >>> f = _fastsha1
- >>> a = sha1()
- >>> a = f()
- >>> a.hexdigest()
- 'da39a3ee5e6b4b0d3255bfef95601890afd80709'
- '''
-
- return _fastsha1(s)
-
-def _fastsha1(s=''):
- # This function will import sha1 from hashlib or sha (whichever is
- # available) and overwrite itself with it on the first call.
- # Subsequent calls will go directly to the imported function.
- if sys.version_info >= (2, 5):
- from hashlib import sha1 as _sha1
- else:
- from sha import sha as _sha1
- global _fastsha1, sha1
- _fastsha1 = sha1 = _sha1
- return _sha1(s)
-
-def md5(s=''):
- try:
- from hashlib import md5 as _md5
- except ImportError:
- from md5 import md5 as _md5
- global md5
- md5 = _md5
- return _md5(s)
+from hashlib import md5, sha1
DIGESTS = {
'md5': md5,
--- a/mercurial/verify.py Tue Nov 10 09:58:10 2015 -0800
+++ b/mercurial/verify.py Thu Nov 12 13:51:09 2015 -0600
@@ -35,6 +35,17 @@
f = f.replace('//', '/')
return f
+def _validpath(repo, path):
+ """Returns False if a path should NOT be treated as part of a repo.
+
+ For all in-core cases, this returns True, as we have no way for a
+ path to be mentioned in the history but not actually be
+ relevant. For narrow clones, this is important because many
+ filelogs will be missing, and changelog entries may mention
+ modified files that are outside the narrow scope.
+ """
+ return True
+
def _verify(repo):
repo = repo.unfiltered()
mflinkrevs = {}
@@ -154,7 +165,8 @@
mflinkrevs.setdefault(changes[0], []).append(i)
refersmf = True
for f in changes[3]:
- filelinkrevs.setdefault(_normpath(f), []).append(i)
+ if _validpath(repo, f):
+ filelinkrevs.setdefault(_normpath(f), []).append(i)
except Exception as inst:
refersmf = True
exc(i, _("unpacking changeset %s") % short(n), inst)
@@ -181,7 +193,9 @@
if not f:
err(lr, _("file without name in manifest"))
elif f != "/dev/null": # ignore this in very old repos
- filenodes.setdefault(_normpath(f), {}).setdefault(fn, lr)
+ if _validpath(repo, f):
+ filenodes.setdefault(
+ _normpath(f), {}).setdefault(fn, lr)
except Exception as inst:
exc(lr, _("reading manifest delta %s") % short(n), inst)
ui.progress(_('checking'), None)
--- a/tests/hghave.py Tue Nov 10 09:58:10 2015 -0800
+++ b/tests/hghave.py Thu Nov 12 13:51:09 2015 -0600
@@ -463,3 +463,12 @@
@check("slow", "allow slow tests")
def has_slow():
return os.environ.get('HGTEST_SLOW') == 'slow'
+
+@check("hypothesis", "is Hypothesis installed")
+def has_hypothesis():
+ try:
+ import hypothesis
+ hypothesis.given
+ return True
+ except ImportError:
+ return False
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/hypothesishelpers.py Thu Nov 12 13:51:09 2015 -0600
@@ -0,0 +1,62 @@
+# Helper module to use the Hypothesis tool in tests
+#
+# Copyright 2015 David R. MacIver
+#
+# For details see http://hypothesis.readthedocs.org
+
+import os
+import sys
+import traceback
+
+from hypothesis.settings import set_hypothesis_home_dir
+import hypothesis.strategies as st
+from hypothesis import given, Settings
+
+# hypothesis store data regarding generate example and code
+set_hypothesis_home_dir(os.path.join(
+ os.getenv('TESTTMP'), ".hypothesis"
+))
+
+def check(*args, **kwargs):
+ """decorator to make a function a hypothesis test
+
+ Decorated function are run immediately (to be used doctest style)"""
+ def accept(f):
+ # Workaround for https://github.com/DRMacIver/hypothesis/issues/206
+ # Fixed in version 1.13 (released 2015 october 29th)
+ f.__module__ = '__anon__'
+ try:
+ given(*args, settings=Settings(max_examples=2000), **kwargs)(f)()
+ except Exception:
+ traceback.print_exc(file=sys.stdout)
+ sys.exit(1)
+ return accept
+
+
+def roundtrips(data, decode, encode):
+ """helper to tests function that must do proper encode/decode roundtripping
+ """
+ @given(data)
+ def testroundtrips(value):
+ encoded = encode(value)
+ decoded = decode(encoded)
+ if decoded != value:
+ raise ValueError(
+ "Round trip failed: %s(%r) -> %s(%r) -> %r" % (
+ encode.__name__, value, decode.__name__, encoded,
+ decoded
+ ))
+ try:
+ testroundtrips()
+ except Exception:
+ # heredoc swallow traceback, we work around it
+ traceback.print_exc(file=sys.stdout)
+ raise
+ print("Round trip OK")
+
+
+# strategy for generating bytestring that might be an issue for Mercurial
+bytestrings = (
+ st.builds(lambda s, e: s.encode(e), st.text(), st.sampled_from([
+ 'utf-8', 'utf-16',
+ ]))) | st.binary()
--- a/tests/test-commit-interactive.t Tue Nov 10 09:58:10 2015 -0800
+++ b/tests/test-commit-interactive.t Thu Nov 12 13:51:09 2015 -0600
@@ -153,7 +153,7 @@
Add binary file
- $ hg bundle --base -2 tip.bundle
+ $ hg bundle --type v1 --base -2 tip.bundle
1 changesets found
$ hg add tip.bundle
$ hg commit -i -d '4 0' -m binary<<EOF
@@ -178,7 +178,7 @@
Change binary file
- $ hg bundle --base -2 tip.bundle
+ $ hg bundle --base -2 --type v1 tip.bundle
1 changesets found
$ hg commit -i -d '5 0' -m binary-change<<EOF
> y
@@ -202,7 +202,7 @@
Rename and change binary file
$ hg mv tip.bundle top.bundle
- $ hg bundle --base -2 top.bundle
+ $ hg bundle --base -2 --type v1 top.bundle
1 changesets found
$ hg commit -i -d '6 0' -m binary-change-rename<<EOF
> y
--- a/tests/test-convert-filemap.t Tue Nov 10 09:58:10 2015 -0800
+++ b/tests/test-convert-filemap.t Thu Nov 12 13:51:09 2015 -0600
@@ -740,4 +740,48 @@
- converted/a
- toberemoved
+ $ cd ..
+Test case where cleanp2 contains a file that doesn't exist in p2 - for
+example because filemap changed.
+
+ $ hg init cleanp2
+ $ cd cleanp2
+ $ touch f f1 f2 && hg ci -Aqm '0'
+ $ echo f1 > f1 && echo >> f && hg ci -m '1'
+ $ hg up -qr0 && echo f2 > f2 && echo >> f && hg ci -qm '2'
+ $ echo "include f" > filemap
+ $ hg convert --filemap filemap .
+ assuming destination .-hg
+ initializing destination .-hg repository
+ scanning source...
+ sorting...
+ converting...
+ 2 0
+ 1 1
+ 0 2
+ $ hg merge && hg ci -qm '3'
+ 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ (branch merge, don't forget to commit)
+ $ echo "include ." > filemap
+ $ hg convert --filemap filemap .
+ assuming destination .-hg
+ scanning source...
+ sorting...
+ converting...
+ 0 3
+ $ hg -R .-hg log -G -T '{shortest(node)} {desc}\n{files % "- {file}\n"}\n'
+ o e9ed 3
+ |\
+ | o 33a0 2
+ | | - f
+ | |
+ o | f73e 1
+ |/ - f
+ |
+ o d681 0
+ - f
+
+ $ hg -R .-hg mani -r tip
+ f
+ $ cd ..
--- a/tests/test-convert-git.t Tue Nov 10 09:58:10 2015 -0800
+++ b/tests/test-convert-git.t Thu Nov 12 13:51:09 2015 -0600
@@ -689,10 +689,7 @@
$ cd git-repo7
$ echo a >> a
- $ git commit -am "move master forward"
- [master 0c81947] move master forward
- Author: nottest <test@example.org>
- 1 file changed, 1 insertion(+)
+ $ git commit -q -am "move master forward"
$ cd ..
$ rm -rf hg-repo7
$ hg convert --config convert.git.remoteprefix=origin git-repo7-client hg-repo7
--- a/tests/test-debugbundle.t Tue Nov 10 09:58:10 2015 -0800
+++ b/tests/test-debugbundle.t Thu Nov 12 13:51:09 2015 -0600
@@ -6,7 +6,7 @@
$ touch a ; hg add a ; hg ci -ma
$ touch b ; hg add b ; hg ci -mb
$ touch c ; hg add c ; hg ci -mc
- $ hg bundle --base 0 --rev tip bundle.hg -v
+ $ hg bundle --base 0 --rev tip bundle.hg -v --type v1
2 changesets found
uncompressed size of bundle content:
332 (changelog)
--- a/tests/test-generaldelta.t Tue Nov 10 09:58:10 2015 -0800
+++ b/tests/test-generaldelta.t Thu Nov 12 13:51:09 2015 -0600
@@ -62,7 +62,7 @@
o 0 3903 a
$ cd ..
- $ hg init client
+ $ hg init client --config format.generaldelta=false
$ cd client
$ hg pull -q ../server -r 4
$ hg debugindex x
@@ -71,10 +71,55 @@
$ cd ..
+Test "usegeneraldelta" config
+(repo are general delta, but incoming bundle are not re-deltified)
+
+delta coming from the server base delta server are not recompressed.
+(also include the aggressive version for comparison)
+
+ $ hg clone repo --pull --config format.usegeneraldelta=1 usegd
+ requesting all changes
+ adding changesets
+ adding manifests
+ adding file changes
+ added 4 changesets with 5 changes to 2 files (+2 heads)
+ updating to branch default
+ 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ $ hg clone repo --pull --config format.generaldelta=1 full
+ requesting all changes
+ adding changesets
+ adding manifests
+ adding file changes
+ added 4 changesets with 5 changes to 2 files (+2 heads)
+ updating to branch default
+ 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ $ hg -R repo debugindex -m
+ rev offset length base linkrev nodeid p1 p2
+ 0 0 77 0 0 0273e8a1b972 000000000000 000000000000
+ 1 77 57 0 1 e0c49f5ef780 0273e8a1b972 000000000000
+ 2 134 77 2 2 de950093e41b 0273e8a1b972 000000000000
+ 3 211 57 2 3 db74c7cde4d0 0273e8a1b972 000000000000
+ $ hg -R usegd debugindex -m
+ rev offset length delta linkrev nodeid p1 p2
+ 0 0 77 -1 0 0273e8a1b972 000000000000 000000000000
+ 1 77 57 0 1 e0c49f5ef780 0273e8a1b972 000000000000
+ 2 134 77 -1 2 de950093e41b 0273e8a1b972 000000000000
+ 3 211 57 2 3 db74c7cde4d0 0273e8a1b972 000000000000
+ $ hg -R full debugindex -m
+ rev offset length delta linkrev nodeid p1 p2
+ 0 0 77 -1 0 0273e8a1b972 000000000000 000000000000
+ 1 77 57 0 1 e0c49f5ef780 0273e8a1b972 000000000000
+ 2 134 57 0 2 de950093e41b 0273e8a1b972 000000000000
+ 3 191 57 0 3 db74c7cde4d0 0273e8a1b972 000000000000
+
Test format.aggressivemergedeltas
$ hg init --config format.generaldelta=1 aggressive
$ cd aggressive
+ $ cat << EOF >> .hg/hgrc
+ > [format]
+ > generaldelta = 1
+ > EOF
$ touch a b c d e
$ hg commit -Aqm side1
$ hg up -q null
--- a/tests/test-merge-prompt.t Tue Nov 10 09:58:10 2015 -0800
+++ b/tests/test-merge-prompt.t Thu Nov 12 13:51:09 2015 -0600
@@ -5,6 +5,9 @@
840e2b315c1f: Fix misleading error and prompts during update/merge
(issue556)
+Make sure HGMERGE doesn't interfere with the test
+ $ unset HGMERGE
+
$ status() {
> echo "--- status ---"
> hg st -A file1 file2
@@ -148,3 +151,25 @@
changed
*** file2 does not exist
+Non-interactive linear update
+
+ $ hg co -C 0
+ 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ $ echo changed >> file1
+ $ hg rm file2
+ $ hg update 1 -y
+ local changed file1 which remote deleted
+ use (c)hanged version or (d)elete? c
+ remote changed file2 which local deleted
+ use (c)hanged version or leave (d)eleted? c
+ 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ $ status
+ --- status ---
+ A file1
+ C file2
+ --- file1 ---
+ 1
+ changed
+ --- file2 ---
+ 2
+ changed
--- a/tests/test-merge-tools.t Tue Nov 10 09:58:10 2015 -0800
+++ b/tests/test-merge-tools.t Thu Nov 12 13:51:09 2015 -0600
@@ -50,6 +50,8 @@
> cat f
> echo "# hg stat"
> hg stat
+ > echo "# hg resolve --list"
+ > hg resolve --list
> rm -f f.orig
> }
@@ -82,6 +84,8 @@
# hg stat
M f
? f.orig
+ # hg resolve --list
+ U f
simplest hgrc using false for merge:
@@ -103,6 +107,8 @@
# hg stat
M f
? f.orig
+ # hg resolve --list
+ U f
#if unix-permissions
@@ -150,6 +156,8 @@
space
# hg stat
M f
+ # hg resolve --list
+ R f
unless lowered on command line:
@@ -171,6 +179,8 @@
# hg stat
M f
? f.orig
+ # hg resolve --list
+ U f
or false set higher on command line:
@@ -192,6 +202,8 @@
# hg stat
M f
? f.orig
+ # hg resolve --list
+ U f
or true set to disabled:
$ beforemerge
@@ -212,6 +224,8 @@
# hg stat
M f
? f.orig
+ # hg resolve --list
+ U f
or true.executable not found in PATH:
@@ -233,6 +247,8 @@
# hg stat
M f
? f.orig
+ # hg resolve --list
+ U f
or true.executable with bogus path:
@@ -254,6 +270,8 @@
# hg stat
M f
? f.orig
+ # hg resolve --list
+ U f
but true.executable set to cat found in PATH works:
@@ -280,6 +298,8 @@
space
# hg stat
M f
+ # hg resolve --list
+ R f
and true.executable set to cat with path works:
@@ -305,6 +325,8 @@
space
# hg stat
M f
+ # hg resolve --list
+ R f
#if unix-permissions
@@ -330,6 +352,8 @@
space
# hg stat
M f
+ # hg resolve --list
+ R f
#endif
@@ -356,6 +380,8 @@
# hg stat
M f
? f.orig
+ # hg resolve --list
+ U f
merge-patterns specifies executable not found in PATH and gets warning:
@@ -380,6 +406,8 @@
# hg stat
M f
? f.orig
+ # hg resolve --list
+ U f
merge-patterns specifies executable with bogus path and gets warning:
@@ -404,6 +432,8 @@
# hg stat
M f
? f.orig
+ # hg resolve --list
+ U f
ui.merge overrules priority
@@ -428,6 +458,8 @@
# hg stat
M f
? f.orig
+ # hg resolve --list
+ U f
ui.merge specifies internal:fail:
@@ -447,6 +479,8 @@
space
# hg stat
M f
+ # hg resolve --list
+ U f
ui.merge specifies :local (without internal prefix):
@@ -465,6 +499,8 @@
space
# hg stat
M f
+ # hg resolve --list
+ R f
ui.merge specifies internal:other:
@@ -483,6 +519,8 @@
space
# hg stat
M f
+ # hg resolve --list
+ R f
ui.merge specifies internal:prompt:
@@ -503,6 +541,70 @@
space
# hg stat
M f
+ # hg resolve --list
+ R f
+
+prompt with EOF
+
+ $ beforemerge
+ [merge-tools]
+ false.whatever=
+ true.priority=1
+ true.executable=cat
+ # hg update -C 1
+ $ hg merge -r 2 --config ui.merge=internal:prompt --config ui.interactive=true
+ no tool found to merge f
+ keep (l)ocal or take (o)ther?
+ 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
+ use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
+ [1]
+ $ aftermerge
+ # cat f
+ revision 1
+ space
+ # hg stat
+ M f
+ # hg resolve --list
+ U f
+ $ hg resolve --all --config ui.merge=internal:prompt --config ui.interactive=true
+ no tool found to merge f
+ keep (l)ocal or take (o)ther?
+ [1]
+ $ aftermerge
+ # cat f
+ revision 1
+ space
+ # hg stat
+ M f
+ ? f.orig
+ # hg resolve --list
+ U f
+ $ rm f
+ $ hg resolve --all --config ui.merge=internal:prompt --config ui.interactive=true
+ no tool found to merge f
+ keep (l)ocal or take (o)ther?
+ [1]
+ $ aftermerge
+ # cat f
+ revision 1
+ space
+ # hg stat
+ M f
+ # hg resolve --list
+ U f
+ $ hg resolve --all --config ui.merge=internal:prompt
+ no tool found to merge f
+ keep (l)ocal or take (o)ther? l
+ (no more unresolved files)
+ $ aftermerge
+ # cat f
+ revision 1
+ space
+ # hg stat
+ M f
+ ? f.orig
+ # hg resolve --list
+ R f
ui.merge specifies internal:dump:
@@ -527,6 +629,8 @@
? f.local
? f.orig
? f.other
+ # hg resolve --list
+ U f
f.base:
@@ -568,6 +672,8 @@
# hg stat
M f
? f.orig
+ # hg resolve --list
+ U f
Premerge
@@ -592,6 +698,8 @@
# hg stat
M f
? f.orig
+ # hg resolve --list
+ U f
HGMERGE specifies internal:other but is overruled by --tool=false
@@ -615,6 +723,8 @@
# hg stat
M f
? f.orig
+ # hg resolve --list
+ U f
$ unset HGMERGE # make sure HGMERGE doesn't interfere with remaining tests
@@ -671,6 +781,8 @@
space
# hg stat
M f
+ # hg resolve --list
+ R f
update should also have --tool
@@ -712,6 +824,8 @@
# hg stat
M f
? f.orig
+ # hg resolve --list
+ U f
Default is silent simplemerge:
@@ -732,6 +846,8 @@
revision 3
# hg stat
M f
+ # hg resolve --list
+ R f
.premerge=True is same:
@@ -752,6 +868,8 @@
revision 3
# hg stat
M f
+ # hg resolve --list
+ R f
.premerge=False executes merge-tool:
@@ -778,6 +896,8 @@
space
# hg stat
M f
+ # hg resolve --list
+ R f
premerge=keep keeps conflict markers in:
@@ -810,6 +930,8 @@
>>>>>>> other: 81448d39c9a0 - test: revision 4
# hg stat
M f
+ # hg resolve --list
+ R f
premerge=keep-merge3 keeps conflict markers with base content:
@@ -848,6 +970,8 @@
>>>>>>> other: 81448d39c9a0 - test: revision 4
# hg stat
M f
+ # hg resolve --list
+ R f
Tool execution
@@ -886,6 +1010,8 @@
space
# hg stat
M f
+ # hg resolve --list
+ R f
Merge with "echo mergeresult > $local":
@@ -904,6 +1030,8 @@
mergeresult
# hg stat
M f
+ # hg resolve --list
+ R f
- and $local is the file f:
@@ -922,6 +1050,8 @@
mergeresult
# hg stat
M f
+ # hg resolve --list
+ R f
Merge with "echo mergeresult > $output" - the variable is a bit magic:
@@ -940,6 +1070,8 @@
mergeresult
# hg stat
M f
+ # hg resolve --list
+ R f
Merge using tool with a path that must be quoted:
@@ -969,6 +1101,8 @@
space
# hg stat
M f
+ # hg resolve --list
+ R f
Issue3581: Merging a filename that needs to be quoted
(This test doesn't work on Windows filesystems even on Linux, so check
@@ -1029,6 +1163,8 @@
# hg stat
M f
? f.orig
+ # hg resolve --list
+ U f
#if symlink
--- a/tests/test-merge-types.t Tue Nov 10 09:58:10 2015 -0800
+++ b/tests/test-merge-types.t Thu Nov 12 13:51:09 2015 -0600
@@ -105,6 +105,50 @@
a is an executable file with content:
a
+ $ hg update -C 1
+ 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+ $ hg merge --debug --tool :merge-local
+ searching for copies back to rev 1
+ resolving manifests
+ branchmerge: True, force: False, partial: False
+ ancestor: c334dc3be0da, local: 3574f3e69b1c+, remote: 521a1e40188f
+ preserving a for resolve of a
+ a: versions differ -> m (premerge)
+ picked tool ':merge-local' for a (binary False symlink True)
+ merging a
+ my a@3574f3e69b1c+ other a@521a1e40188f ancestor a@c334dc3be0da
+ warning: internal :merge-local cannot merge symlinks for a
+ 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
+ use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
+ [1]
+
+ $ tellmeabout a
+ a is an executable file with content:
+ a
+
+ $ hg update -C 1
+ 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+ $ hg merge --debug --tool :merge-other
+ searching for copies back to rev 1
+ resolving manifests
+ branchmerge: True, force: False, partial: False
+ ancestor: c334dc3be0da, local: 3574f3e69b1c+, remote: 521a1e40188f
+ preserving a for resolve of a
+ a: versions differ -> m (premerge)
+ picked tool ':merge-other' for a (binary False symlink True)
+ merging a
+ my a@3574f3e69b1c+ other a@521a1e40188f ancestor a@c334dc3be0da
+ warning: internal :merge-other cannot merge symlinks for a
+ 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
+ use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
+ [1]
+
+ $ tellmeabout a
+ a is an executable file with content:
+ a
+
Update to link without local change should get us a symlink (issue3316):
$ hg up -C 0
--- a/tests/test-pathencode.py Tue Nov 10 09:58:10 2015 -0800
+++ b/tests/test-pathencode.py Thu Nov 12 13:51:09 2015 -0600
@@ -9,9 +9,6 @@
import binascii, itertools, math, os, random, sys, time
import collections
-if sys.version_info[:2] < (2, 6):
- sys.exit(0)
-
validchars = set(map(chr, range(0, 256)))
alphanum = range(ord('A'), ord('Z'))
--- a/tests/test-push-cgi.t Tue Nov 10 09:58:10 2015 -0800
+++ b/tests/test-push-cgi.t Thu Nov 12 13:51:09 2015 -0600
@@ -31,7 +31,7 @@
$ . "$TESTDIR/cgienv"
$ REQUEST_METHOD="POST"; export REQUEST_METHOD
$ CONTENT_TYPE="application/octet-stream"; export CONTENT_TYPE
- $ hg bundle --all bundle.hg
+ $ hg bundle --type v1 --all bundle.hg
1 changesets found
$ CONTENT_LENGTH=279; export CONTENT_LENGTH;
--- a/tests/test-rebase-obsolete.t Tue Nov 10 09:58:10 2015 -0800
+++ b/tests/test-rebase-obsolete.t Thu Nov 12 13:51:09 2015 -0600
@@ -248,6 +248,30 @@
D
+ $ hg up -qr 'desc(G)'
+ $ hg graft 4596109a6a4328c398bde3a4a3b6737cfade3003
+ grafting 11:4596109a6a43 "D"
+ $ hg up -qr 'desc(E)'
+ $ hg rebase -s tip -d .
+ rebasing 14:9e36056a46e3 "D" (tip)
+ $ hg log --style default --debug -r tip
+ changeset: 15:627d4614809036ba22b9e7cb31638ddc06ab99ab
+ tag: tip
+ phase: draft
+ parent: 4:9520eea781bcca16c1e15acc0ba14335a0e8e5ba
+ parent: -1:0000000000000000000000000000000000000000
+ manifest: 15:648e8ede73ae3e497d093d3a4c8fcc2daa864f42
+ user: Nicolas Dumazet <nicdumz.commits@gmail.com>
+ date: Sat Apr 30 15:24:48 2011 +0200
+ files+: D
+ extra: branch=default
+ extra: intermediate-source=4596109a6a4328c398bde3a4a3b6737cfade3003
+ extra: rebase_source=9e36056a46e37c9776168c7375734eebc70e294f
+ extra: source=32af7686d403cf45b5d95f2d70cebea587ac806a
+ description:
+ D
+
+
$ cd ..
collapse rebase
--- a/tests/test-template-engine.t Tue Nov 10 09:58:10 2015 -0800
+++ b/tests/test-template-engine.t Thu Nov 12 13:51:09 2015 -0600
@@ -44,4 +44,17 @@
0 97e5f848f0936960273bbf75be6388cd0350a32b -1 0000000000000000000000000000000000000000
-1 0000000000000000000000000000000000000000 -1 0000000000000000000000000000000000000000
+Fuzzing the unicode escaper to ensure it produces valid data
+
+#if hypothesis
+
+ >>> from hypothesishelpers import *
+ >>> import mercurial.templatefilters as tf
+ >>> import json
+ >>> @check(st.text().map(lambda s: s.encode('utf-8')))
+ ... def testtfescapeproducesvalidjson(text):
+ ... json.loads('"' + tf.jsonescape(text) + '"')
+
+#endif
+
$ cd ..