--- a/contrib/bash_completion Sun Nov 15 22:18:48 2015 +0100
+++ b/contrib/bash_completion Wed Nov 18 20:59:17 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/contrib/import-checker.py Sun Nov 15 22:18:48 2015 +0100
+++ b/contrib/import-checker.py Wed Nov 18 20:59:17 2015 -0600
@@ -1,4 +1,7 @@
+#!/usr/bin/env python
+
import ast
+import collections
import os
import sys
@@ -35,6 +38,17 @@
return False
+def walklocal(root):
+ """Recursively yield all descendant nodes but not in a different scope"""
+ todo = collections.deque(ast.iter_child_nodes(root))
+ yield root, False
+ while todo:
+ node = todo.popleft()
+ newscope = isinstance(node, ast.FunctionDef)
+ if not newscope:
+ todo.extend(ast.iter_child_nodes(node))
+ yield node, newscope
+
def dotted_name_of_path(path, trimpure=False):
"""Given a relative path to a source file, return its dotted module name.
@@ -237,7 +251,7 @@
>>> sorted(imported_modules(
... 'import foo1; from bar import bar1',
... modulename, localmods))
- ['foo.bar.__init__', 'foo.bar.bar1', 'foo.foo1']
+ ['foo.bar.bar1', 'foo.foo1']
>>> sorted(imported_modules(
... 'from bar.bar1 import name1, name2, name3',
... modulename, localmods))
@@ -284,19 +298,26 @@
continue
absname, dottedpath, hassubmod = found
- yield dottedpath
if not hassubmod:
+ # "dottedpath" is not a package; must be imported
+ yield dottedpath
# examination of "node.names" should be redundant
# e.g.: from mercurial.node import nullid, nullrev
continue
+ modnotfound = False
prefix = absname + '.'
for n in node.names:
found = fromlocal(prefix + n.name)
if not found:
# this should be a function or a property of "node.module"
+ modnotfound = True
continue
yield found[1]
+ if modnotfound:
+ # "dottedpath" is a package, but imported because of non-module
+ # lookup
+ yield dottedpath
def verify_import_convention(module, source):
"""Verify imports match our established coding convention.
@@ -315,7 +336,7 @@
else:
return verify_stdlib_on_own_line(root)
-def verify_modern_convention(module, root):
+def verify_modern_convention(module, root, root_col_offset=0):
"""Verify a file conforms to the modern import convention rules.
The rules of the modern convention are:
@@ -352,29 +373,36 @@
# Relative import levels encountered so far.
seenlevels = set()
- for node in ast.walk(root):
- if isinstance(node, ast.Import):
+ for node, newscope in walklocal(root):
+ def msg(fmt, *args):
+ return (fmt % args, node.lineno)
+ if newscope:
+ # Check for local imports in function
+ for r in verify_modern_convention(module, node,
+ node.col_offset + 4):
+ yield r
+ elif isinstance(node, ast.Import):
# Disallow "import foo, bar" and require separate imports
# for each module.
if len(node.names) > 1:
- yield 'multiple imported names: %s' % ', '.join(
- n.name for n in node.names)
+ yield msg('multiple imported names: %s',
+ ', '.join(n.name for n in node.names))
name = node.names[0].name
asname = node.names[0].asname
# Ignore sorting rules on imports inside blocks.
- if node.col_offset == 0:
+ if node.col_offset == root_col_offset:
if lastname and name < lastname:
- yield 'imports not lexically sorted: %s < %s' % (
- name, lastname)
+ yield msg('imports not lexically sorted: %s < %s',
+ name, lastname)
lastname = name
# stdlib imports should be before local imports.
stdlib = name in stdlib_modules
- if stdlib and seenlocal and node.col_offset == 0:
- yield 'stdlib import follows local import: %s' % name
+ if stdlib and seenlocal and node.col_offset == root_col_offset:
+ yield msg('stdlib import follows local import: %s', name)
if not stdlib:
seenlocal = True
@@ -382,11 +410,11 @@
# Import of sibling modules should use relative imports.
topname = name.split('.')[0]
if topname == topmodule:
- yield 'import should be relative: %s' % name
+ yield msg('import should be relative: %s', name)
if name in requirealias and asname != requirealias[name]:
- yield '%s module must be "as" aliased to %s' % (
- name, requirealias[name])
+ yield msg('%s module must be "as" aliased to %s',
+ name, requirealias[name])
elif isinstance(node, ast.ImportFrom):
# Resolve the full imported module name.
@@ -400,39 +428,40 @@
topname = fullname.split('.')[0]
if topname == topmodule:
- yield 'import should be relative: %s' % fullname
+ yield msg('import should be relative: %s', fullname)
# __future__ is special since it needs to come first and use
# symbol import.
if fullname != '__future__':
if not fullname or fullname in stdlib_modules:
- yield 'relative import of stdlib module'
+ yield msg('relative import of stdlib module')
else:
seenlocal = True
# Direct symbol import is only allowed from certain modules and
# must occur before non-symbol imports.
- if node.module and node.col_offset == 0:
+ if node.module and node.col_offset == root_col_offset:
if fullname not in allowsymbolimports:
- yield 'direct symbol import from %s' % fullname
+ yield msg('direct symbol import from %s', fullname)
if seennonsymbolrelative:
- yield ('symbol import follows non-symbol import: %s' %
- fullname)
+ yield msg('symbol import follows non-symbol import: %s',
+ fullname)
if not node.module:
assert node.level
seennonsymbolrelative = True
# Only allow 1 group per level.
- if node.level in seenlevels and node.col_offset == 0:
- yield 'multiple "from %s import" statements' % (
- '.' * node.level)
+ if (node.level in seenlevels
+ and node.col_offset == root_col_offset):
+ yield msg('multiple "from %s import" statements',
+ '.' * node.level)
# Higher-level groups come before lower-level groups.
if any(node.level > l for l in seenlevels):
- yield 'higher-level import should come first: %s' % (
- fullname)
+ yield msg('higher-level import should come first: %s',
+ fullname)
seenlevels.add(node.level)
@@ -442,14 +471,14 @@
for n in node.names:
if lastentryname and n.name < lastentryname:
- yield 'imports from %s not lexically sorted: %s < %s' % (
- fullname, n.name, lastentryname)
+ yield msg('imports from %s not lexically sorted: %s < %s',
+ fullname, n.name, lastentryname)
lastentryname = n.name
if n.name in requirealias and n.asname != requirealias[n.name]:
- yield '%s from %s must be "as" aliased to %s' % (
- n.name, fullname, requirealias[n.name])
+ yield msg('%s from %s must be "as" aliased to %s',
+ n.name, fullname, requirealias[n.name])
def verify_stdlib_on_own_line(root):
"""Given some python source, verify that stdlib imports are done
@@ -460,7 +489,7 @@
http://bugs.python.org/issue19510.
>>> list(verify_stdlib_on_own_line(ast.parse('import sys, foo')))
- ['mixed imports\\n stdlib: sys\\n relative: foo']
+ [('mixed imports\\n stdlib: sys\\n relative: foo', 1)]
>>> list(verify_stdlib_on_own_line(ast.parse('import sys, os')))
[]
>>> list(verify_stdlib_on_own_line(ast.parse('import foo, bar')))
@@ -474,7 +503,7 @@
if from_stdlib[True] and from_stdlib[False]:
yield ('mixed imports\n stdlib: %s\n relative: %s' %
(', '.join(sorted(from_stdlib[True])),
- ', '.join(sorted(from_stdlib[False]))))
+ ', '.join(sorted(from_stdlib[False]))), node.lineno)
class CircularImport(Exception):
pass
@@ -546,9 +575,9 @@
src = f.read()
used_imports[modname] = sorted(
imported_modules(src, modname, localmods, ignore_nested=True))
- for error in verify_import_convention(modname, src):
+ for error, lineno in verify_import_convention(modname, src):
any_errors = True
- print source_path, error
+ print '%s:%d: %s' % (source_path, lineno, error)
f.close()
cycles = find_cycles(used_imports)
if cycles:
--- a/hgext/convert/hg.py Sun Nov 15 22:18:48 2015 +0100
+++ b/hgext/convert/hg.py Wed Nov 18 20:59:17 2015 -0600
@@ -23,6 +23,7 @@
from mercurial.node import bin, hex, nullid
from mercurial import hg, util, context, bookmarks, error, scmutil, exchange
from mercurial import phases
+from mercurial import lock as lockmod
from mercurial import merge as mergemod
from common import NoRepo, commit, converter_source, converter_sink, mapfile
@@ -410,12 +411,19 @@
def putbookmarks(self, updatedbookmark):
if not len(updatedbookmark):
return
-
- self.ui.status(_("updating bookmarks\n"))
- destmarks = self.repo._bookmarks
- for bookmark in updatedbookmark:
- destmarks[bookmark] = bin(updatedbookmark[bookmark])
- destmarks.write()
+ wlock = lock = tr = None
+ try:
+ wlock = self.repo.wlock()
+ lock = self.repo.lock()
+ tr = self.repo.transaction('bookmark')
+ self.ui.status(_("updating bookmarks\n"))
+ destmarks = self.repo._bookmarks
+ for bookmark in updatedbookmark:
+ destmarks[bookmark] = bin(updatedbookmark[bookmark])
+ destmarks.recordchange(tr)
+ tr.close()
+ finally:
+ lockmod.release(lock, wlock, tr)
def hascommitfrommap(self, rev):
# the exact semantics of clonebranches is unclear so we can't say no
--- a/hgext/histedit.py Sun Nov 15 22:18:48 2015 +0100
+++ b/hgext/histedit.py Wed Nov 18 20:59:17 2015 -0600
@@ -502,6 +502,9 @@
editor=editor)
return repo.commitctx(new)
+def _isdirtywc(repo):
+ return repo[None].dirty(missing=True)
+
class pick(histeditaction):
def run(self):
rulectx = self.repo[self.node]
@@ -971,11 +974,9 @@
actobj = actiontable[action].fromrule(state, currentnode)
- s = repo.status()
- if s.modified or s.added or s.removed or s.deleted:
+ if _isdirtywc(repo):
actobj.continuedirty()
- s = repo.status()
- if s.modified or s.added or s.removed or s.deleted:
+ if _isdirtywc(repo):
raise error.Abort(_("working copy still dirty"))
parentctx, replacements = actobj.continueclean()
--- a/hgext/largefiles/lfcommands.py Sun Nov 15 22:18:48 2015 +0100
+++ b/hgext/largefiles/lfcommands.py Wed Nov 18 20:59:17 2015 -0600
@@ -444,12 +444,14 @@
updated, removed = 0, 0
for lfile in lfiles:
abslfile = repo.wjoin(lfile)
+ abslfileorig = cmdutil.origpath(ui, repo, abslfile)
absstandin = repo.wjoin(lfutil.standin(lfile))
+ absstandinorig = cmdutil.origpath(ui, repo, absstandin)
if os.path.exists(absstandin):
- if (os.path.exists(absstandin + '.orig') and
+ if (os.path.exists(absstandinorig) and
os.path.exists(abslfile)):
- shutil.copyfile(abslfile, abslfile + '.orig')
- util.unlinkpath(absstandin + '.orig')
+ shutil.copyfile(abslfile, abslfileorig)
+ util.unlinkpath(absstandinorig)
expecthash = lfutil.readstandin(repo, lfile)
if expecthash != '':
if lfile not in repo[None]: # not switched to normal file
--- a/hgext/largefiles/overrides.py Sun Nov 15 22:18:48 2015 +0100
+++ b/hgext/largefiles/overrides.py Wed Nov 18 20:59:17 2015 -0600
@@ -481,6 +481,9 @@
(lm, largs, lmsg) = actions.get(lfile, (None, None, None))
(sm, sargs, smsg) = actions.get(standin, (None, None, None))
if sm in ('g', 'dc') and lm != 'r':
+ if sm == 'dc':
+ f1, f2, fa, move, anc = sargs
+ sargs = (p2[f2].flags(),)
# Case 1: normal file in the working copy, largefile in
# the second parent
usermsg = _('remote turned local normal file %s into a largefile\n'
@@ -496,6 +499,9 @@
else:
actions[standin] = ('r', None, 'replaced by non-standin')
elif lm in ('g', 'dc') and sm != 'r':
+ if lm == 'dc':
+ f1, f2, fa, move, anc = largs
+ largs = (p2[f2].flags(),)
# Case 2: largefile in the working copy, normal file in
# the second parent
usermsg = _('remote turned local largefile %s into a normal file\n'
--- a/hgext/mq.py Sun Nov 15 22:18:48 2015 +0100
+++ b/hgext/mq.py Wed Nov 18 20:59:17 2015 -0600
@@ -68,6 +68,7 @@
from mercurial import commands, cmdutil, hg, scmutil, util, revset
from mercurial import extensions, error, phases
from mercurial import patch as patchmod
+from mercurial import lock as lockmod
from mercurial import localrepo
from mercurial import subrepo
import os, re, errno, shutil
@@ -697,11 +698,13 @@
absf = repo.wjoin(f)
if os.path.lexists(absf):
self.ui.note(_('saving current version of %s as %s\n') %
- (f, f + '.orig'))
+ (f, cmdutil.origpath(self.ui, repo, f)))
+
+ absorig = cmdutil.origpath(self.ui, repo, absf)
if copy:
- util.copyfile(absf, absf + '.orig')
+ util.copyfile(absf, absorig)
else:
- util.rename(absf, absf + '.orig')
+ util.rename(absf, absorig)
def printdiff(self, repo, diffopts, node1, node2=None, files=None,
fp=None, changes=None, opts={}):
@@ -1788,27 +1791,34 @@
# Ensure we create a new changeset in the same phase than
# the old one.
- n = newcommit(repo, oldphase, message, user, ph.date,
+ lock = tr = None
+ try:
+ lock = repo.lock()
+ tr = repo.transaction('mq')
+ n = newcommit(repo, oldphase, message, user, ph.date,
match=match, force=True, editor=editor)
- # only write patch after a successful commit
- c = [list(x) for x in refreshchanges]
- if inclsubs:
- self.putsubstate2changes(substatestate, c)
- chunks = patchmod.diff(repo, patchparent,
- changes=c, opts=diffopts)
- comments = str(ph)
- if comments:
- patchf.write(comments)
- for chunk in chunks:
- patchf.write(chunk)
- patchf.close()
-
- marks = repo._bookmarks
- for bm in bmlist:
- marks[bm] = n
- marks.write()
-
- self.applied.append(statusentry(n, patchfn))
+ # only write patch after a successful commit
+ c = [list(x) for x in refreshchanges]
+ if inclsubs:
+ self.putsubstate2changes(substatestate, c)
+ chunks = patchmod.diff(repo, patchparent,
+ changes=c, opts=diffopts)
+ comments = str(ph)
+ if comments:
+ patchf.write(comments)
+ for chunk in chunks:
+ patchf.write(chunk)
+ patchf.close()
+
+ marks = repo._bookmarks
+ for bm in bmlist:
+ marks[bm] = n
+ marks.recordchange(tr)
+ tr.close()
+
+ self.applied.append(statusentry(n, patchfn))
+ finally:
+ lockmod.release(lock, tr)
except: # re-raises
ctx = repo[cparents[0]]
repo.dirstate.rebuild(ctx.node(), ctx.manifest())
--- a/hgext/rebase.py Sun Nov 15 22:18:48 2015 +0100
+++ b/hgext/rebase.py Wed Nov 18 20:59:17 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/hgext/shelve.py Sun Nov 15 22:18:48 2015 +0100
+++ b/hgext/shelve.py Wed Nov 18 20:59:17 2015 -0600
@@ -507,7 +507,7 @@
# revert will overwrite unknown files, so move them out of the way
for file in repo.status(unknown=True).unknown:
if file in files:
- util.rename(file, file + ".orig")
+ util.rename(file, cmdutil.origpath(ui, repo, file))
ui.pushbuffer(True)
cmdutil.revert(ui, repo, shelvectx, repo.dirstate.parents(),
*pathtofiles(repo, files),
@@ -531,7 +531,7 @@
lock = None
try:
checkparents(repo, state)
- ms = merge.mergestate(repo)
+ ms = merge.mergestate.read(repo)
if [f for f in ms if ms[f] == 'u']:
raise error.Abort(
_("unresolved conflicts, can't continue"),
--- a/hgext/strip.py Sun Nov 15 22:18:48 2015 +0100
+++ b/hgext/strip.py Wed Nov 18 20:59:17 2015 -0600
@@ -7,7 +7,7 @@
from mercurial.node import nullid
from mercurial.lock import release
from mercurial import cmdutil, hg, scmutil, util, error
-from mercurial import repair, bookmarks, merge
+from mercurial import repair, bookmarks as bookmarksmod , merge
cmdtable = {}
command = cmdutil.command(cmdtable)
@@ -62,12 +62,12 @@
repair.strip(ui, repo, revs, backup)
- marks = repo._bookmarks
+ repomarks = repo._bookmarks
if bookmark:
if bookmark == repo._activebookmark:
- bookmarks.deactivate(repo)
- del marks[bookmark]
- marks.write()
+ bookmarksmod.deactivate(repo)
+ del repomarks[bookmark]
+ repomarks.write()
ui.write(_("bookmark '%s' deleted\n") % bookmark)
finally:
release(lock, wlock)
@@ -127,27 +127,27 @@
wlock = repo.wlock()
try:
- if opts.get('bookmark'):
- mark = opts.get('bookmark')
- marks = repo._bookmarks
- if mark not in marks:
- raise error.Abort(_("bookmark '%s' not found") % mark)
+ bookmark = opts.get('bookmark')
+ if bookmark:
+ repomarks = repo._bookmarks
+ if bookmark not in repomarks:
+ raise error.Abort(_("bookmark '%s' not found") % bookmark)
# If the requested bookmark is not the only one pointing to a
# a revision we have to only delete the bookmark and not strip
# anything. revsets cannot detect that case.
uniquebm = True
- for m, n in marks.iteritems():
- if m != mark and n == repo[mark].node():
+ for m, n in repomarks.iteritems():
+ if m != bookmark and n == repo[bookmark].node():
uniquebm = False
break
if uniquebm:
- rsrevs = repair.stripbmrevset(repo, mark)
+ rsrevs = repair.stripbmrevset(repo, bookmark)
revs.update(set(rsrevs))
if not revs:
- del marks[mark]
- marks.write()
- ui.write(_("bookmark '%s' deleted\n") % mark)
+ del repomarks[bookmark]
+ repomarks.write()
+ ui.write(_("bookmark '%s' deleted\n") % bookmark)
if not revs:
raise error.Abort(_('empty revision set'))
@@ -208,14 +208,13 @@
repo.dirstate.write(repo.currenttransaction())
# clear resolve state
- ms = merge.mergestate(repo)
- ms.reset(repo['.'].node())
+ merge.mergestate.clean(repo, repo['.'].node())
update = False
strip(ui, repo, revs, backup=backup, update=update,
- force=opts.get('force'), bookmark=opts.get('bookmark'))
+ force=opts.get('force'), bookmark=bookmark)
finally:
wlock.release()
--- a/mercurial/bookmarks.py Sun Nov 15 22:18:48 2015 +0100
+++ b/mercurial/bookmarks.py Wed Nov 18 20:59:17 2015 -0600
@@ -249,7 +249,14 @@
update = True
if update:
- marks.write()
+ lock = tr = None
+ try:
+ lock = repo.lock()
+ tr = repo.transaction('bookmark')
+ marks.recordchange(tr)
+ tr.close()
+ finally:
+ lockmod.release(tr, lock)
return update
def listbookmarks(repo):
--- a/mercurial/cmdutil.py Sun Nov 15 22:18:48 2015 +0100
+++ b/mercurial/cmdutil.py Wed Nov 18 20:59:17 2015 -0600
@@ -3082,7 +3082,7 @@
xlist.append(abs)
if dobackup and (backup <= dobackup
or wctx[abs].cmp(ctx[abs])):
- bakname = "%s.orig" % rel
+ bakname = origpath(ui, repo, rel)
ui.note(_('saving current version of %s as %s\n') %
(rel, bakname))
if not opts.get('dry_run'):
@@ -3114,6 +3114,26 @@
finally:
wlock.release()
+def origpath(ui, repo, filepath):
+ '''customize where .orig files are created
+
+ Fetch user defined path from config file: [ui] origbackuppath = <path>
+ Fall back to default (filepath) if not specified
+ '''
+ origbackuppath = ui.config('ui', 'origbackuppath', None)
+ if origbackuppath is None:
+ return filepath + ".orig"
+
+ filepathfromroot = os.path.relpath(filepath, start=repo.root)
+ fullorigpath = repo.wjoin(origbackuppath, filepathfromroot)
+
+ origbackupdir = repo.vfs.dirname(fullorigpath)
+ if not repo.vfs.exists(origbackupdir):
+ ui.note(_('creating directory: %s\n') % origbackupdir)
+ util.makedirs(origbackupdir)
+
+ return fullorigpath + ".orig"
+
def _revertprefetch(repo, ctx, *files):
"""Let extension changing the storage layer prefetch content"""
pass
--- a/mercurial/commands.py Sun Nov 15 22:18:48 2015 +0100
+++ b/mercurial/commands.py Wed Nov 18 20:59:17 2015 -0600
@@ -2547,8 +2547,8 @@
flags = r[7]
else:
onode, flags = r[7:9]
- ui.write(('file: %s (state "%s", hash %s)\n')
- % (f, state, hash))
+ ui.write(('file: %s (record type "%s", state "%s", hash %s)\n')
+ % (f, rtype, state, hash))
ui.write((' local path: %s (flags "%s")\n') % (lfile, flags))
ui.write((' ancestor path: %s (node %s)\n') % (afile, anode))
ui.write((' other path: %s (node %s)\n') % (ofile, onode))
@@ -2556,6 +2556,9 @@
ui.write(('unrecognized entry: %s\t%s\n')
% (rtype, record.replace('\0', '\t')))
+ # Avoid mergestate.read() since it may raise an exception for unsupported
+ # merge state records. We shouldn't be doing this, but this is OK since this
+ # command is pretty low-level.
ms = mergemod.mergestate(repo)
# sort so that reasonable information is on top
@@ -3162,8 +3165,12 @@
[('', 'nodates', None, _('do not display the saved mtime')),
('', 'datesort', None, _('sort by saved mtime'))],
_('[OPTION]...'))
-def debugstate(ui, repo, nodates=None, datesort=None):
+def debugstate(ui, repo, **opts):
"""show the contents of the current dirstate"""
+
+ nodates = opts.get('nodates')
+ datesort = opts.get('datesort')
+
timestr = ""
if datesort:
keyfunc = lambda x: (x[1][3], x[0]) # sort by mtime, then by filename
@@ -5227,10 +5234,9 @@
checkout, movemarkfrom, brev = updata
ret = hg.update(repo, checkout)
except error.UpdateAbort as inst:
- ui.warn(_("not updating: %s\n") % str(inst))
- if inst.hint:
- ui.warn(_("(%s)\n") % inst.hint)
- return 0
+ msg = _("not updating: %s") % str(inst)
+ hint = inst.hint
+ raise error.UpdateAbort(msg, hint=hint)
if not ret and not checkout:
if bookmarks.update(repo, [movemarkfrom], repo['.'].node()):
ui.status(_("updating bookmark %s\n") % repo._activebookmark)
@@ -5590,7 +5596,7 @@
if show:
fm = ui.formatter('resolve', opts)
- ms = mergemod.mergestate(repo)
+ ms = mergemod.mergestate.read(repo)
m = scmutil.match(repo[None], pats, opts)
for f in ms:
if not m(f):
@@ -5605,7 +5611,7 @@
wlock = repo.wlock()
try:
- ms = mergemod.mergestate(repo)
+ ms = mergemod.mergestate.read(repo)
if not (ms.active() or repo.dirstate.p2() != nullid):
raise error.Abort(
@@ -5655,7 +5661,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 +5683,12 @@
# replace filemerge's .orig file with our resolve file, but only
# for merges that are complete
if complete:
- util.rename(a + ".resolve", a + ".orig")
+ try:
+ util.rename(a + ".resolve",
+ cmdutil.origpath(ui, repo, a))
+ except OSError as inst:
+ if inst.errno != errno.ENOENT:
+ raise
for f in tocomplete:
try:
@@ -6205,8 +6220,15 @@
if d in status.added:
status.added.remove(d)
- ms = mergemod.mergestate(repo)
- unresolved = [f for f in ms if ms[f] == 'u']
+ try:
+ ms = mergemod.mergestate.read(repo)
+ except error.UnsupportedMergeRecords as e:
+ s = ' '.join(e.recordtypes)
+ ui.warn(
+ _('warning: merge state has unsupported record types: %s\n') % s)
+ unresolved = 0
+ else:
+ unresolved = [f for f in ms if ms[f] == 'u']
subs = [s for s in ctx.substate if ctx.sub(s).dirty()]
@@ -6582,10 +6604,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/context.py Sun Nov 15 22:18:48 2015 +0100
+++ b/mercurial/context.py Wed Nov 18 20:59:17 2015 -0600
@@ -747,11 +747,22 @@
def islink(self):
return 'l' in self.flags()
+ def isabsent(self):
+ """whether this filectx represents a file not in self._changectx
+
+ This is mainly for merge code to detect change/delete conflicts. This is
+ expected to be True for all subclasses of basectx."""
+ return False
+
+ _customcmp = False
def cmp(self, fctx):
"""compare with other file context
returns True if different than fctx.
"""
+ if fctx._customcmp:
+ return fctx.cmp(self)
+
if (fctx._filerev is None
and (self._repo._encodefilterpats
# if file data starts with '\1\n', empty metadata block is
--- a/mercurial/dirstate.py Sun Nov 15 22:18:48 2015 +0100
+++ b/mercurial/dirstate.py Wed Nov 18 20:59:17 2015 -0600
@@ -1008,14 +1008,8 @@
# We may not have walked the full directory tree above,
# so stat and check everything we missed.
nf = iter(visit).next
- pos = 0
- while pos < len(visit):
- # visit in mid-sized batches so that we don't
- # block signals indefinitely
- xr = xrange(pos, min(len(visit), pos + 1000))
- for st in util.statfiles([join(visit[n]) for n in xr]):
- results[nf()] = st
- pos += 1000
+ for st in util.statfiles([join(i) for i in visit]):
+ results[nf()] = st
return results
def status(self, match, subrepos, ignored, clean, unknown):
--- a/mercurial/discovery.py Sun Nov 15 22:18:48 2015 +0100
+++ b/mercurial/discovery.py Wed Nov 18 20:59:17 2015 -0600
@@ -238,12 +238,42 @@
unsynced = set()
return {None: (oldheads, newheads, unsynced)}
-def checkheads(repo, remote, outgoing, remoteheads, newbranch=False, inc=False,
- newbookmarks=[]):
+def _nowarnheads(pushop):
+ # Compute newly pushed bookmarks. We don't warn about bookmarked heads.
+
+ # internal config: bookmarks.pushing
+ newbookmarks = pushop.ui.configlist('bookmarks', 'pushing')
+
+ repo = pushop.repo.unfiltered()
+ remote = pushop.remote
+ 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(pushop):
"""Check that a push won't add any outgoing head
raise Abort error and display ui message as needed.
"""
+
+ repo = pushop.repo.unfiltered()
+ remote = pushop.remote
+ outgoing = pushop.outgoing
+ remoteheads = pushop.remoteheads
+ newbranch = pushop.newbranch
+ inc = bool(pushop.incoming)
+
# Check for each named branch if we're creating new remote heads.
# To be a remote head after push, node must be either:
# - unknown locally
@@ -268,19 +298,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(pushop)
# 3. Check for new heads.
# If there are more heads after the push than before, a suitable
@@ -366,7 +385,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 Sun Nov 15 22:18:48 2015 +0100
+++ b/mercurial/encoding.py Wed Nov 18 20:59:17 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.
@@ -470,11 +497,17 @@
is a round-trip process for strings like filenames, but metadata
that's was passed through tolocal will remain in UTF-8.
+ >>> roundtrip = lambda x: fromutf8b(toutf8b(x)) == x
>>> m = "\\xc3\\xa9\\x99abcd"
- >>> n = toutf8b(m)
- >>> n
+ >>> toutf8b(m)
'\\xc3\\xa9\\xed\\xb2\\x99abcd'
- >>> fromutf8b(n) == m
+ >>> roundtrip(m)
+ True
+ >>> roundtrip("\\xc2\\xc2\\x80")
+ True
+ >>> roundtrip("\\xef\\xbf\\xbd")
+ True
+ >>> roundtrip("\\xef\\xef\\xbf\\xbd")
True
'''
@@ -485,7 +518,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 Sun Nov 15 22:18:48 2015 +0100
+++ b/mercurial/error.py Wed Nov 18 20:59:17 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"""
@@ -106,6 +112,16 @@
class RequirementError(RepoError):
"""Exception raised if .hg/requires has an unknown entry."""
+class UnsupportedMergeRecords(Abort):
+ def __init__(self, recordtypes):
+ from .i18n import _
+ self.recordtypes = sorted(recordtypes)
+ s = ' '.join(self.recordtypes)
+ Abort.__init__(
+ self, _('unsupported merge state records: %s') % s,
+ hint=_('see https://mercurial-scm.org/wiki/MergeStateRecords for '
+ 'more information'))
+
class LockError(IOError):
def __init__(self, errno, strerror, filename, desc):
IOError.__init__(self, errno, strerror, filename)
--- a/mercurial/exchange.py Sun Nov 15 22:18:48 2015 +0100
+++ b/mercurial/exchange.py Wed Nov 18 20:59:17 2015 -0600
@@ -571,13 +571,7 @@
elif ctx.troubled():
raise error.Abort(mst[ctx.troubles()[0]] % ctx)
- # internal config: bookmarks.pushing
- newbm = pushop.ui.configlist('bookmarks', 'pushing')
- discovery.checkheads(unfi, pushop.remote, outgoing,
- pushop.remoteheads,
- pushop.newbranch,
- bool(pushop.incoming),
- newbm)
+ discovery.checkheads(pushop)
return True
# List of names of steps to perform for an outgoing bundle2, order matters.
--- a/mercurial/filemerge.py Sun Nov 15 22:18:48 2015 +0100
+++ b/mercurial/filemerge.py Wed Nov 18 20:59:17 2015 -0600
@@ -13,9 +13,10 @@
import tempfile
from .i18n import _
-from .node import short
+from .node import nullid, short
from . import (
+ cmdutil,
error,
match,
simplemerge,
@@ -43,6 +44,50 @@
mergeonly = 'mergeonly' # just the full merge, no premerge
fullmerge = 'fullmerge' # both premerge and merge
+class absentfilectx(object):
+ """Represents a file that's ostensibly in a context but is actually not
+ present in it.
+
+ This is here because it's very specific to the filemerge code for now --
+ other code is likely going to break with the values this returns."""
+ def __init__(self, ctx, f):
+ self._ctx = ctx
+ self._f = f
+
+ def path(self):
+ return self._f
+
+ def size(self):
+ return None
+
+ def data(self):
+ return None
+
+ def filenode(self):
+ return nullid
+
+ _customcmp = True
+ def cmp(self, fctx):
+ """compare with other file context
+
+ returns True if different from fctx.
+ """
+ return not (fctx.isabsent() and
+ fctx.ctx() == self.ctx() and
+ fctx.path() == self.path())
+
+ def flags(self):
+ return ''
+
+ def changectx(self):
+ return self._ctx
+
+ def isbinary(self):
+ return False
+
+ def isabsent(self):
+ return True
+
def internaltool(name, mergetype, onfailure=None, precheck=None):
'''return a decorator for populating internal merge tool table'''
def decorator(func):
@@ -175,12 +220,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):
@@ -236,7 +288,7 @@
util.copyfile(back, a) # restore from backup and try again
return 1 # continue merging
-def _symlinkcheck(repo, mynode, orig, fcd, fco, fca, toolconf):
+def _mergecheck(repo, mynode, orig, fcd, fco, fca, toolconf):
tool, toolpath, binary, symlink = toolconf
if symlink:
repo.ui.warn(_('warning: internal %s cannot merge symlinks '
@@ -260,7 +312,7 @@
@internaltool('union', fullmerge,
_("warning: conflicts while merging %s! "
"(edit, then use 'hg resolve --mark')\n"),
- precheck=_symlinkcheck)
+ precheck=_mergecheck)
def _iunion(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels=None):
"""
Uses the internal non-interactive simple merge algorithm for merging
@@ -272,7 +324,7 @@
@internaltool('merge', fullmerge,
_("warning: conflicts while merging %s! "
"(edit, then use 'hg resolve --mark')\n"),
- precheck=_symlinkcheck)
+ precheck=_mergecheck)
def _imerge(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels=None):
"""
Uses the internal non-interactive simple merge algorithm for merging
@@ -285,7 +337,7 @@
@internaltool('merge3', fullmerge,
_("warning: conflicts while merging %s! "
"(edit, then use 'hg resolve --mark')\n"),
- precheck=_symlinkcheck)
+ precheck=_mergecheck)
def _imerge3(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels=None):
"""
Uses the internal non-interactive simple merge algorithm for merging
@@ -305,16 +357,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=_mergecheck)
def _imergelocal(*args, **kwargs):
"""
Like :merge, but resolve all conflicts non-interactively in favor
@@ -322,7 +370,7 @@
success, status = _imergeauto(localorother='local', *args, **kwargs)
return success, status
-@internaltool('merge-other', mergeonly)
+@internaltool('merge-other', mergeonly, precheck=_mergecheck)
def _imergeother(*args, **kwargs):
"""
Like :merge, but resolve all conflicts non-interactively in favor
@@ -507,7 +555,7 @@
a = repo.wjoin(fd)
b = temp("base", fca)
c = temp("other", fco)
- back = a + ".orig"
+ back = cmdutil.origpath(ui, repo, a)
if premerge:
util.copyfile(a, back)
files = (a, b, c, back)
--- a/mercurial/fileset.py Sun Nov 15 22:18:48 2015 +0100
+++ b/mercurial/fileset.py Wed Nov 18 20:59:17 2015 -0600
@@ -249,7 +249,7 @@
getargs(x, 0, 0, _("resolved takes no arguments"))
if mctx.ctx.rev() is not None:
return []
- ms = merge.mergestate(mctx.ctx.repo())
+ ms = merge.mergestate.read(mctx.ctx.repo())
return [f for f in mctx.subset if f in ms and ms[f] == 'r']
def unresolved(mctx, x):
@@ -260,7 +260,7 @@
getargs(x, 0, 0, _("unresolved takes no arguments"))
if mctx.ctx.rev() is not None:
return []
- ms = merge.mergestate(mctx.ctx.repo())
+ ms = merge.mergestate.read(mctx.ctx.repo())
return [f for f in mctx.subset if f in ms and ms[f] == 'u']
def hgignore(mctx, x):
--- a/mercurial/help.py Sun Nov 15 22:18:48 2015 +0100
+++ b/mercurial/help.py Wed Nov 18 20:59:17 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 Sun Nov 15 22:18:48 2015 +0100
+++ b/mercurial/help/config.txt Wed Nov 18 20:59:17 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
@@ -1488,6 +1496,10 @@
markers is different from the encoding of the merged files,
serious problems may occur.
+``origbackuppath``
+ The path to a directory used to store generated .orig files. If the path is
+ not a directory, one will be created.
+
``patch``
An optional external tool that ``hg import`` and some extensions
will use for applying patches. By default Mercurial uses an
--- a/mercurial/hgweb/hgweb_mod.py Sun Nov 15 22:18:48 2015 +0100
+++ b/mercurial/hgweb/hgweb_mod.py Wed Nov 18 20:59:17 2015 -0600
@@ -8,8 +8,9 @@
import contextlib
import os
-from mercurial import ui, hg, hook, error, encoding, templater, util, repoview
-from mercurial.templatefilters import websub
+from mercurial import hg, hook, error, encoding, templater, util, repoview
+from mercurial import ui as uimod
+from mercurial import templatefilters
from common import ErrorResponse, permhooks, caching
from common import HTTP_OK, HTTP_NOT_MODIFIED, HTTP_BAD_REQUEST
from common import HTTP_NOT_FOUND, HTTP_SERVER_ERROR
@@ -158,7 +159,7 @@
or req.url.strip('/') or self.repo.root)
def websubfilter(text):
- return websub(text, self.websubtable)
+ return templatefilters.websub(text, self.websubtable)
# create the templater
@@ -195,7 +196,7 @@
if baseui:
u = baseui.copy()
else:
- u = ui.ui()
+ u = uimod.ui()
r = hg.repository(u, repo)
else:
# we trust caller to give us a private copy
@@ -304,8 +305,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/hgwebdir_mod.py Sun Nov 15 22:18:48 2015 +0100
+++ b/mercurial/hgweb/hgwebdir_mod.py Wed Nov 18 20:59:17 2015 -0600
@@ -8,7 +8,8 @@
import os, re, time
from mercurial.i18n import _
-from mercurial import ui, hg, scmutil, util, templater
+from mercurial import hg, scmutil, util, templater
+from mercurial import ui as uimod
from mercurial import error, encoding
from common import ErrorResponse, get_mtime, staticfile, paritygen, ismember, \
get_contact, HTTP_OK, HTTP_NOT_FOUND, HTTP_SERVER_ERROR
@@ -108,7 +109,7 @@
if self.baseui:
u = self.baseui.copy()
else:
- u = ui.ui()
+ u = uimod.ui()
u.setconfig('ui', 'report_untrusted', 'off', 'hgwebdir')
u.setconfig('ui', 'nontty', 'true', 'hgwebdir')
# displaying bundling progress bar while serving feels wrong and may
--- a/mercurial/hgweb/request.py Sun Nov 15 22:18:48 2015 +0100
+++ b/mercurial/hgweb/request.py Wed Nov 18 20:59:17 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 Sun Nov 15 22:18:48 2015 +0100
+++ b/mercurial/hgweb/server.py Wed Nov 18 20:59:17 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 Sun Nov 15 22:18:48 2015 +0100
+++ b/mercurial/hgweb/webcommands.py Wed Nov 18 20:59:17 2015 -0600
@@ -15,7 +15,6 @@
from mercurial import graphmod, patch
from mercurial import scmutil
from mercurial.i18n import _
-from mercurial.error import ParseError, RepoLookupError, Abort
from mercurial import revset
__all__ = []
@@ -225,7 +224,7 @@
revdef = 'reverse(%s)' % query
try:
tree = revset.parse(revdef)
- except ParseError:
+ except error.ParseError:
# can't parse to a revset tree
return MODE_KEYWORD, query
@@ -249,7 +248,8 @@
# RepoLookupError: no such revision, e.g. in 'revision:'
# Abort: bookmark/tag not exists
# LookupError: ambiguous identifier, e.g. in '(bc)' on a large repo
- except (ParseError, RepoLookupError, Abort, LookupError):
+ except (error.ParseError, error.RepoLookupError, error.Abort,
+ LookupError):
return MODE_KEYWORD, query
def changelist(**map):
@@ -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 Sun Nov 15 22:18:48 2015 +0100
+++ b/mercurial/hgweb/webutil.py Wed Nov 18 20:59:17 2015 -0600
@@ -8,10 +8,11 @@
import os, copy
import re
-from mercurial import match, patch, error, ui, util, pathutil, context
+from mercurial import match, patch, error, util, pathutil, context
+from mercurial import ui as uimod
from mercurial.i18n import _
from mercurial.node import hex, nullid, short
-from mercurial.templatefilters import revescape
+from mercurial import templatefilters
from common import ErrorResponse, paritygen
from common import HTTP_NOT_FOUND
import difflib
@@ -297,8 +298,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(),
@@ -314,7 +315,7 @@
def symrevorshortnode(req, ctx):
if 'node' in req.form:
- return revescape(req.form['node'][0])
+ return templatefilters.revescape(req.form['node'][0])
else:
return short(ctx.node())
@@ -537,7 +538,7 @@
yield {'name': key, 'value': str(value), 'separator': separator}
separator = '&'
-class wsgiui(ui.ui):
+class wsgiui(uimod.ui):
# default termwidth breaks under mod_wsgi
def termwidth(self):
return 80
--- a/mercurial/localrepo.py Sun Nov 15 22:18:48 2015 +0100
+++ b/mercurial/localrepo.py Wed Nov 18 20:59:17 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)
@@ -1168,8 +1168,7 @@
else:
ui.status(_('working directory now based on '
'revision %d\n') % parents)
- ms = mergemod.mergestate(self)
- ms.reset(self['.'].node())
+ mergemod.mergestate.clean(self, self['.'].node())
# TODO: if we know which new heads may result from this rollback, pass
# them to destroy(), which will prevent the branchhead cache from being
@@ -1456,8 +1455,9 @@
match.explicitdir = vdirs.append
match.bad = fail
- wlock = self.wlock()
+ wlock = lock = tr = None
try:
+ wlock = self.wlock()
wctx = self[None]
merge = len(wctx.parents()) > 1
@@ -1557,7 +1557,7 @@
raise error.Abort(_("cannot commit merge with missing files"))
unresolved, driverresolved = False, False
- ms = mergemod.mergestate(self)
+ ms = mergemod.mergestate.read(self)
for f in status.modified:
if f in ms:
if ms[f] == 'u':
@@ -1592,23 +1592,26 @@
subrepo.writestate(self, newstate)
p1, p2 = self.dirstate.parents()
+ lock = self.lock()
hookp1, hookp2 = hex(p1), (p2 != nullid and hex(p2) or '')
try:
self.hook("precommit", throw=True, parent1=hookp1,
parent2=hookp2)
+ tr = self.transaction('commit')
ret = self.commitctx(cctx, True)
except: # re-raises
if edited:
self.ui.write(
_('note: commit message saved in %s\n') % msgfn)
raise
-
# update bookmarks, dirstate and mergestate
bookmarks.update(self, [p1, p2], ret)
cctx.markcommitted(ret)
ms.reset()
+ tr.close()
+
finally:
- wlock.release()
+ lockmod.release(tr, lock, wlock)
def commithook(node=hex(ret), parent1=hookp1, parent2=hookp2):
# hack for command that use a temporary commit (eg: histedit)
--- a/mercurial/manifest.py Sun Nov 15 22:18:48 2015 +0100
+++ b/mercurial/manifest.py Wed Nov 18 20:59:17 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 Sun Nov 15 22:18:48 2015 +0100
+++ b/mercurial/merge.py Wed Nov 18 20:59:17 2015 -0600
@@ -75,10 +75,27 @@
statepathv1 = 'merge/state'
statepathv2 = 'merge/state2'
+ @staticmethod
+ def clean(repo, node=None, other=None):
+ """Initialize a brand new merge state, removing any existing state on
+ disk."""
+ ms = mergestate(repo)
+ ms.reset(node, other)
+ return ms
+
+ @staticmethod
+ def read(repo):
+ """Initialize the merge state, reading it from disk."""
+ ms = mergestate(repo)
+ ms._read()
+ return ms
+
def __init__(self, repo):
+ """Initialize the merge state.
+
+ Do not use this directly! Instead call read() or clean()."""
self._repo = repo
self._dirty = False
- self._read()
def reset(self, node=None, other=None):
self._state = {}
@@ -110,6 +127,7 @@
del self.otherctx
self._readmergedriver = None
self._mdstate = 's'
+ unsupported = set()
records = self._readrecords()
for rtype, record in records:
if rtype == 'L':
@@ -129,10 +147,12 @@
bits = record.split('\0')
self._state[bits[0]] = bits[1:]
elif not rtype.islower():
- raise error.Abort(_('unsupported merge state record: %s')
- % rtype)
+ unsupported.add(rtype)
self._dirty = False
+ if unsupported:
+ raise error.UnsupportedMergeRecords(unsupported)
+
def _readrecords(self):
"""Read merge state from disk and return a list of record (TYPE, data)
@@ -266,20 +286,24 @@
def commit(self):
"""Write current state on disk (if necessary)"""
if self._dirty:
- records = []
- records.append(('L', hex(self._local)))
- records.append(('O', hex(self._other)))
- if self.mergedriver:
- records.append(('m', '\0'.join([
- self.mergedriver, self._mdstate])))
- for d, v in self._state.iteritems():
- if v[0] == 'd':
- records.append(('D', '\0'.join([d] + v)))
- else:
- records.append(('F', '\0'.join([d] + v)))
+ records = self._makerecords()
self._writerecords(records)
self._dirty = False
+ def _makerecords(self):
+ records = []
+ records.append(('L', hex(self._local)))
+ records.append(('O', hex(self._other)))
+ if self.mergedriver:
+ records.append(('m', '\0'.join([
+ self.mergedriver, self._mdstate])))
+ for d, v in self._state.iteritems():
+ if v[0] == 'd':
+ records.append(('D', '\0'.join([d] + v)))
+ else:
+ records.append(('F', '\0'.join([d] + v)))
+ return records
+
def _writerecords(self, records):
"""Write current state on disk (both v1 and v2)"""
self._writerecordsv1(records)
@@ -395,10 +419,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):
@@ -618,7 +647,8 @@
if acceptremote:
actions[f] = ('r', None, "remote delete")
else:
- actions[f] = ('cd', None, "prompt changed/deleted")
+ actions[f] = ('cd', (f, None, f, False, pa.node()),
+ "prompt changed/deleted")
elif n1[20:] == 'a':
# This extra 'a' is added by working copy manifest to mark
# the file as locally added. We should forget it instead of
@@ -668,7 +698,8 @@
if acceptremote:
actions[f] = ('c', (fl2,), "remote recreating")
else:
- actions[f] = ('dc', (fl2,), "prompt deleted/changed")
+ actions[f] = ('dc', (None, f, f, False, pa.node()),
+ "prompt deleted/changed")
return actions, diverge, renamedelete
@@ -835,8 +866,7 @@
"""
updated, merged, removed, unresolved = 0, 0, 0, 0
- ms = mergestate(repo)
- ms.reset(wctx.p1().node(), mctx.node())
+ ms = mergestate.clean(repo, wctx.p1().node(), mctx.node())
moves = []
for m, l in actions.items():
l.sort()
@@ -965,7 +995,7 @@
# premerge
tocomplete = []
- for f, args, msg in actions['m']:
+ for f, args, msg in mergeactions:
repo.ui.debug(" %s: %s -> m (premerge)\n" % (f, msg))
z += 1
progress(_updating, z, item=f, total=numupdates, unit=_files)
@@ -1007,7 +1037,7 @@
if not driverconclude(repo, ms, wctx, labels=labels):
# XXX setting unresolved to at least 1 is a hack to make sure we
# error out
- return updated, merged, removed, max(unresolved, 1)
+ unresolved = max(unresolved, 1)
ms.commit()
@@ -1257,26 +1287,15 @@
actions['r'].append((f, None, "prompt delete"))
else:
actions['a'].append((f, None, "prompt keep"))
- del actions['cd'][:]
for f, args, msg in sorted(actions['dc']):
- flags, = args
+ f1, f2, fa, move, anc = args
+ flags = p2[f2].flags()
if repo.ui.promptchoice(
_("remote changed %s which local deleted\n"
"use (c)hanged version or leave (d)eleted?"
"$$ &Changed $$ &Deleted") % f, 0) == 0:
actions['g'].append((f, (flags,), "prompt recreating"))
- del actions['dc'][:]
-
- ### apply phase
- if not branchmerge: # just jump to the new rev
- fp1, fp2, xp1, xp2 = fp2, nullid, xp2, ''
- if not partial:
- repo.hook('preupdate', throw=True, parent1=xp1, parent2=xp2)
- # note that we're in the middle of an update
- repo.vfs.write('updatestate', p2.hex())
-
- stats = applyupdates(repo, actions, wc, p2, overwrite, labels=labels)
# divergent renames
for f, fl in sorted(diverge.iteritems()):
@@ -1292,6 +1311,16 @@
for nf in fl:
repo.ui.warn(" %s\n" % nf)
+ ### apply phase
+ if not branchmerge: # just jump to the new rev
+ fp1, fp2, xp1, xp2 = fp2, nullid, xp2, ''
+ if not partial:
+ repo.hook('preupdate', throw=True, parent1=xp1, parent2=xp2)
+ # note that we're in the middle of an update
+ repo.vfs.write('updatestate', p2.hex())
+
+ stats = applyupdates(repo, actions, wc, p2, overwrite, labels=labels)
+
if not partial:
repo.dirstate.beginparentchange()
repo.setparents(fp1, fp2)
--- a/mercurial/node.py Sun Nov 15 22:18:48 2015 +0100
+++ b/mercurial/node.py Wed Nov 18 20:59:17 2015 -0600
@@ -9,17 +9,18 @@
import binascii
+# This ugly style has a noticeable effect in manifest parsing
+hex = binascii.hexlify
+bin = binascii.unhexlify
+
nullrev = -1
nullid = "\0" * 20
+nullhex = hex(nullid)
# pseudo identifiers for working directory
# (they are experimental, so don't add too many dependencies on them)
wdirrev = 0x7fffffff
wdirid = "\xff" * 20
-# This ugly style has a noticeable effect in manifest parsing
-hex = binascii.hexlify
-bin = binascii.unhexlify
-
def short(node):
return hex(node[:6])
--- a/mercurial/osutil.c Sun Nov 15 22:18:48 2015 +0100
+++ b/mercurial/osutil.c Wed Nov 18 20:59:17 2015 -0600
@@ -613,9 +613,14 @@
int ret, kind;
char *path;
+ /* With a large file count or on a slow filesystem,
+ don't block signals for long (issue4878). */
+ if ((i % 1000) == 999 && PyErr_CheckSignals() == -1)
+ goto bail;
+
pypath = PySequence_GetItem(names, i);
if (!pypath)
- return NULL;
+ goto bail;
path = PyString_AsString(pypath);
if (path == NULL) {
Py_DECREF(pypath);
--- a/mercurial/phases.py Sun Nov 15 22:18:48 2015 +0100
+++ b/mercurial/phases.py Wed Nov 18 20:59:17 2015 -0600
@@ -308,9 +308,19 @@
raise error.Abort(_('cannot change null revision phase'))
currentroots = currentroots.copy()
currentroots.update(newroots)
- ctxs = repo.set('roots(%ln::)', currentroots)
- currentroots.intersection_update(ctx.node() for ctx in ctxs)
- self._updateroots(targetphase, currentroots, tr)
+
+ # Only compute new roots for revs above the roots that are being
+ # retracted.
+ minnewroot = min(repo[n].rev() for n in newroots)
+ aboveroots = [n for n in currentroots
+ if repo[n].rev() >= minnewroot]
+ updatedroots = repo.set('roots(%ln::)', aboveroots)
+
+ finalroots = set(n for n in currentroots if repo[n].rev() <
+ minnewroot)
+ finalroots.update(ctx.node() for ctx in updatedroots)
+
+ self._updateroots(targetphase, finalroots, tr)
repo.invalidatevolatilesets()
def filterunknown(self, repo):
--- a/mercurial/posix.py Sun Nov 15 22:18:48 2015 +0100
+++ b/mercurial/posix.py Wed Nov 18 20:59:17 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 Sun Nov 15 22:18:48 2015 +0100
+++ b/mercurial/revlog.py Wed Nov 18 20:59:17 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 Sun Nov 15 22:18:48 2015 +0100
+++ b/mercurial/scmutil.py Wed Nov 18 20:59:17 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/subrepo.py Sun Nov 15 22:18:48 2015 +0100
+++ b/mercurial/subrepo.py Wed Nov 18 20:59:17 2015 -0600
@@ -1910,7 +1910,7 @@
status = self.status(None)
names = status.modified
for name in names:
- bakname = "%s.orig" % name
+ bakname = cmdutil.origpath(self.ui, self._subparent, name)
self.ui.note(_('saving current version of %s as %s\n') %
(name, bakname))
self.wvfs.rename(name, bakname)
--- a/mercurial/templatefilters.py Sun Nov 15 22:18:48 2015 +0100
+++ b/mercurial/templatefilters.py Wed Nov 18 20:59:17 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/monoblue/map Sun Nov 15 22:18:48 2015 +0100
+++ b/mercurial/templates/monoblue/map Wed Nov 18 20:59:17 2015 -0600
@@ -23,7 +23,7 @@
naventry = '<a href="{url|urlescape}log/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
navshortentry = '<a href="{url|urlescape}shortlog/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
navgraphentry = '<a href="{url|urlescape}graph/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
-filenaventry = '<a href="{url|urlescape}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{label|escape}</a>'
+filenaventry = '<a href="{url|urlescape}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{label|escape}</a> '
filedifflink = '<a href="{url|urlescape}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{file|escape}</a> '
filenodelink = '
<tr class="parity{parity}">
--- a/mercurial/templates/static/mercurial.js Sun Nov 15 22:18:48 2015 +0100
+++ b/mercurial/templates/static/mercurial.js Wed Nov 18 20:59:17 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 Sun Nov 15 22:18:48 2015 +0100
+++ b/mercurial/ui.py Wed Nov 18 20:59:17 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 Sun Nov 15 22:18:48 2015 +0100
+++ b/mercurial/util.py Wed Nov 18 20:59:17 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 Sun Nov 15 22:18:48 2015 +0100
+++ b/mercurial/verify.py Wed Nov 18 20:59:17 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/mercurial/wireproto.py Sun Nov 15 22:18:48 2015 +0100
+++ b/mercurial/wireproto.py Wed Nov 18 20:59:17 2015 -0600
@@ -585,7 +585,7 @@
caps.append('stream')
# otherwise, add 'streamreqs' detailing our local revlog format
else:
- caps.append('streamreqs=%s' % ','.join(requiredformats))
+ caps.append('streamreqs=%s' % ','.join(sorted(requiredformats)))
if repo.ui.configbool('experimental', 'bundle2-advertise', True):
capsblob = bundle2.encodecaps(bundle2.getrepocaps(repo))
caps.append('bundle2=' + urllib.quote(capsblob))
--- a/tests/f Sun Nov 15 22:18:48 2015 +0100
+++ b/tests/f Wed Nov 18 20:59:17 2015 -0600
@@ -44,7 +44,7 @@
if opts.type:
facts.append('file')
if opts.hexdump or opts.dump or opts.md5:
- content = file(f).read()
+ content = file(f, 'rb').read()
elif islink:
if opts.type:
facts.append('link')
--- a/tests/hghave.py Sun Nov 15 22:18:48 2015 +0100
+++ b/tests/hghave.py Wed Nov 18 20:59:17 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 Wed Nov 18 20:59:17 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-backout.t Sun Nov 15 22:18:48 2015 +0100
+++ b/tests/test-backout.t Wed Nov 18 20:59:17 2015 -0600
@@ -686,7 +686,7 @@
* version 2 records
local: b71750c4b0fdf719734971e3ef90dbeab5919a2d
other: a30dd8addae3ce71b8667868478542bc417439e6
- file: foo (state "u", hash 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33)
+ file: foo (record type "F", state "u", hash 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33)
local path: foo (flags "")
ancestor path: foo (node f89532f44c247a0e993d63e3a734dd781ab04708)
other path: foo (node f50039b486d6fa1a90ae51778388cad161f425ee)
@@ -694,7 +694,7 @@
$ hg debugmergestate
* version 1 records
local: b71750c4b0fdf719734971e3ef90dbeab5919a2d
- file: foo (state "u", hash 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33)
+ file: foo (record type "F", state "u", hash 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33)
local path: foo (flags "")
ancestor path: foo (node f89532f44c247a0e993d63e3a734dd781ab04708)
other path: foo (node not stored in v1 format)
--- a/tests/test-bundle-type.t Sun Nov 15 22:18:48 2015 +0100
+++ b/tests/test-bundle-type.t Wed Nov 18 20:59:17 2015 -0600
@@ -1,3 +1,9 @@
+
+ $ cat << EOF >> $HGRCPATH
+ > [format]
+ > usegeneraldelta=yes
+ > EOF
+
bundle w/o type option
$ hg init t1
@@ -43,20 +49,26 @@
% test bundle type None
searching for changes
1 changesets found
- HG10UN
- c35a0f9217e65d1fdb90c936ffa7dbe679f83ddf
+ HG20\x00\x00 (esc)
+ Stream params: {}
+ changegroup -- "{'version': '02'}"
+ c35a0f9217e65d1fdb90c936ffa7dbe679f83ddf
% test bundle type bzip2
searching for changes
1 changesets found
- HG10BZ
- c35a0f9217e65d1fdb90c936ffa7dbe679f83ddf
+ HG20\x00\x00 (esc)
+ Stream params: {'Compression': 'BZ'}
+ changegroup -- "{'version': '02'}"
+ c35a0f9217e65d1fdb90c936ffa7dbe679f83ddf
% test bundle type gzip
searching for changes
1 changesets found
- HG10GZ
- c35a0f9217e65d1fdb90c936ffa7dbe679f83ddf
+ HG20\x00\x00 (esc)
+ Stream params: {'Compression': 'GZ'}
+ changegroup -- "{'version': '02'}"
+ c35a0f9217e65d1fdb90c936ffa7dbe679f83ddf
% test bundle type none-v2
searching for changes
--- a/tests/test-bundle.t Sun Nov 15 22:18:48 2015 +0100
+++ b/tests/test-bundle.t Wed Nov 18 20:59:17 2015 -0600
@@ -1,3 +1,9 @@
+
+ $ cat << EOF >> $HGRCPATH
+ > [format]
+ > usegeneraldelta=yes
+ > EOF
+
Setting up test
$ hg init test
@@ -260,15 +266,15 @@
packed1 is produced properly
$ hg -R test debugcreatestreamclonebundle packed.hg
- writing 2608 bytes for 6 files
- bundle requirements: revlogv1
+ writing 2663 bytes for 6 files
+ bundle requirements: generaldelta, revlogv1
$ f -B 64 --size --sha1 --hexdump packed.hg
- packed.hg: size=2758, sha1=864c1c7b490bac9f2950ef5a660668378ac0524e
+ packed.hg: size=2826, sha1=e139f97692a142b19cdcff64a69697d5307ce6d4
0000: 48 47 53 31 55 4e 00 00 00 00 00 00 00 06 00 00 |HGS1UN..........|
- 0010: 00 00 00 00 0a 30 00 09 72 65 76 6c 6f 67 76 31 |.....0..revlogv1|
- 0020: 00 64 61 74 61 2f 61 64 69 66 66 65 72 65 6e 74 |.data/adifferent|
- 0030: 66 69 6c 65 2e 69 00 31 33 39 0a 00 01 00 01 00 |file.i.139......|
+ 0010: 00 00 00 00 0a 67 00 16 67 65 6e 65 72 61 6c 64 |.....g..generald|
+ 0020: 65 6c 74 61 2c 72 65 76 6c 6f 67 76 31 00 64 61 |elta,revlogv1.da|
+ 0030: 74 61 2f 61 64 69 66 66 65 72 65 6e 74 66 69 6c |ta/adifferentfil|
generaldelta requirement is listed in stream clone bundles
@@ -299,8 +305,8 @@
packed1 can be consumed from debug command
$ hg -R packed debugapplystreamclonebundle packed.hg
- 6 files to transfer, 2.55 KB of data
- transferred 2.55 KB in *.* seconds (*) (glob)
+ 6 files to transfer, 2.60 KB of data
+ transferred 2.60 KB in *.* seconds (* */sec) (glob)
Does not work on non-empty repo
@@ -695,6 +701,8 @@
list of changesets:
1a38c1b849e8b70c756d2d80b0b9a3ac0b7ea11a
057f4db07f61970e1c11e83be79e9d08adc4dc31
+ bundle2-output-bundle: "HG20", (1 params) 1 parts total
+ bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
bundling: 1/2 changesets (50.00%)
bundling: 2/2 changesets (100.00%)
bundling: 1/2 manifests (50.00%)
--- a/tests/test-clone-r.t Sun Nov 15 22:18:48 2015 +0100
+++ b/tests/test-clone-r.t Wed Nov 18 20:59:17 2015 -0600
@@ -63,7 +63,7 @@
2 96 48 ..... 2 626a32663c2f 8b89697eba2c 000000000000 (re)
3 144 48 ..... 3 f54c32f13478 626a32663c2f 000000000000 (re)
4 192 .. ..... 6 de68e904d169 626a32663c2f 000000000000 (re)
- 5 2.. 68 ..... 7 09bb521d218d de68e904d169 000000000000 (re)
+ 5 2.. .. ..... 7 09bb521d218d de68e904d169 000000000000 (re)
6 3.. 54 ..... 8 1fde233dfb0f f54c32f13478 000000000000 (re)
$ hg verify
--- a/tests/test-clonebundles.t Sun Nov 15 22:18:48 2015 +0100
+++ b/tests/test-clonebundles.t Wed Nov 18 20:59:17 2015 -0600
@@ -1,5 +1,9 @@
Set up a server
+ $ cat >> $HGRCPATH << EOF
+ > [format]
+ > usegeneraldelta=yes
+ > EOF
$ hg init server
$ cd server
$ cat >> .hg/hgrc << EOF
@@ -80,7 +84,7 @@
$ echo 'http://does.not.exist/bundle.hg' > server/.hg/clonebundles.manifest
$ hg clone http://localhost:$HGPORT 404-url
applying clone bundle from http://does.not.exist/bundle.hg
- error fetching bundle: * not known (glob)
+ error fetching bundle: (.* not known|getaddrinfo failed) (re)
abort: error applying bundle
(if this error persists, consider contacting the server operator or disable clone bundles via "--config experimental.clonebundles=false")
[255]
@@ -90,7 +94,7 @@
$ echo "http://localhost:$HGPORT1/bundle.hg" > server/.hg/clonebundles.manifest
$ hg clone http://localhost:$HGPORT server-not-runner
applying clone bundle from http://localhost:$HGPORT1/bundle.hg
- error fetching bundle: Connection refused
+ error fetching bundle: * refused* (glob)
abort: error applying bundle
(if this error persists, consider contacting the server operator or disable clone bundles via "--config experimental.clonebundles=false")
[255]
@@ -308,7 +312,7 @@
$ hg -R server debugcreatestreamclonebundle packed.hg
writing 613 bytes for 4 files
- bundle requirements: revlogv1
+ bundle requirements: generaldelta, revlogv1
No bundle spec should work
--- a/tests/test-commit-amend.t Sun Nov 15 22:18:48 2015 +0100
+++ b/tests/test-commit-amend.t Wed Nov 18 20:59:17 2015 -0600
@@ -1,3 +1,8 @@
+ $ cat << EOF >> $HGRCPATH
+ > [format]
+ > usegeneraldelta=yes
+ > EOF
+
$ hg init
Setup:
@@ -115,15 +120,15 @@
stripping amended changeset 74609c7f506e
1 changesets found
uncompressed size of bundle content:
- 250 (changelog)
- 143 (manifests)
- 109 a
+ 270 (changelog)
+ 163 (manifests)
+ 129 a
saved backup bundle to $TESTTMP/.hg/strip-backup/74609c7f506e-1bfde511-amend-backup.hg (glob)
1 changesets found
uncompressed size of bundle content:
- 246 (changelog)
- 143 (manifests)
- 109 a
+ 266 (changelog)
+ 163 (manifests)
+ 129 a
adding branch
adding changesets
adding manifests
@@ -259,15 +264,15 @@
stripping amended changeset 5f357c7560ab
1 changesets found
uncompressed size of bundle content:
- 238 (changelog)
- 143 (manifests)
- 111 a
+ 258 (changelog)
+ 163 (manifests)
+ 131 a
saved backup bundle to $TESTTMP/.hg/strip-backup/5f357c7560ab-e7c84ade-amend-backup.hg (glob)
1 changesets found
uncompressed size of bundle content:
- 246 (changelog)
- 143 (manifests)
- 111 a
+ 266 (changelog)
+ 163 (manifests)
+ 131 a
adding branch
adding changesets
adding manifests
@@ -302,15 +307,15 @@
stripping amended changeset 7ab3bf440b54
2 changesets found
uncompressed size of bundle content:
- 450 (changelog)
- 282 (manifests)
- 209 a
+ 490 (changelog)
+ 322 (manifests)
+ 249 a
saved backup bundle to $TESTTMP/.hg/strip-backup/7ab3bf440b54-8e3b5088-amend-backup.hg (glob)
1 changesets found
uncompressed size of bundle content:
- 246 (changelog)
- 143 (manifests)
- 113 a
+ 266 (changelog)
+ 163 (manifests)
+ 133 a
adding branch
adding changesets
adding manifests
@@ -1138,14 +1143,14 @@
R olddirname/commonfile.py
R olddirname/newfile.py
$ hg debugindex newdirname/newfile.py
- rev offset length base linkrev nodeid p1 p2
- 0 0 88 0 3 34a4d536c0c0 000000000000 000000000000
+ rev offset length delta linkrev nodeid p1 p2
+ 0 0 88 -1 3 34a4d536c0c0 000000000000 000000000000
$ echo a >> newdirname/commonfile.py
$ hg ci --amend -m bug
$ hg debugrename newdirname/newfile.py
newdirname/newfile.py renamed from olddirname/newfile.py:690b295714aed510803d3020da9c70fca8336def (glob)
$ hg debugindex newdirname/newfile.py
- rev offset length base linkrev nodeid p1 p2
- 0 0 88 0 3 34a4d536c0c0 000000000000 000000000000
+ rev offset length delta linkrev nodeid p1 p2
+ 0 0 88 -1 3 34a4d536c0c0 000000000000 000000000000
--- a/tests/test-commit-interactive.t Sun Nov 15 22:18:48 2015 +0100
+++ b/tests/test-commit-interactive.t Wed Nov 18 20:59:17 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 Sun Nov 15 22:18:48 2015 +0100
+++ b/tests/test-convert-filemap.t Wed Nov 18 20:59:17 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 Sun Nov 15 22:18:48 2015 +0100
+++ b/tests/test-convert-git.t Wed Nov 18 20:59:17 2015 -0600
@@ -54,7 +54,7 @@
$ hg convert --config extensions.progress= --config progress.assume-tty=1 \
> --config progress.delay=0 --config progress.changedelay=0 \
> --config progress.refresh=0 --config progress.width=60 \
- > --datesort git-repo
+ > --config progress.format='topic, bar, number' --datesort git-repo
\r (no-eol) (esc)
scanning [======> ] 1/6\r (no-eol) (esc)
scanning [=============> ] 2/6\r (no-eol) (esc)
@@ -173,7 +173,8 @@
$ hg convert --datesort git-repo2 fullrepo \
> --config extensions.progress= --config progress.assume-tty=1 \
> --config progress.delay=0 --config progress.changedelay=0 \
- > --config progress.refresh=0 --config progress.width=60
+ > --config progress.refresh=0 --config progress.width=60 \
+ > --config progress.format='topic, bar, number'
\r (no-eol) (esc)
scanning [===> ] 1/9\r (no-eol) (esc)
scanning [========> ] 2/9\r (no-eol) (esc)
@@ -533,8 +534,7 @@
$ git commit -q -m "remove .gitmodules" .gitmodules
$ git commit -q -m "missing .gitmodules"
$ cd ..
- $ hg convert git-repo6 hg-repo6 --traceback
- fatal: Path '.gitmodules' does not exist in '*' (glob)
+ $ hg convert git-repo6 hg-repo6 --traceback 2>&1 | grep -v "fatal: Path '.gitmodules' does not exist"
initializing destination hg-repo6 repository
scanning source...
sorting...
@@ -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-copy.t Sun Nov 15 22:18:48 2015 +0100
+++ b/tests/test-copy.t Wed Nov 18 20:59:17 2015 -0600
@@ -1,3 +1,9 @@
+# enable bundle2 in advance
+
+ $ cat << EOF >> $HGRCPATH
+ > [format]
+ > usegeneraldelta=yes
+ > EOF
$ mkdir part1
$ cd part1
@@ -87,7 +93,7 @@
copyrev: b789fdd96dc2f3bd229c1dd8eedf0fc60e2b68e3
$ md5sum.py .hg/store/data/b.i
- 4999f120a3b88713bbefddd195cf5133 .hg/store/data/b.i
+ 44913824c8f5890ae218f9829535922e .hg/store/data/b.i
$ hg cat b > bsum
$ md5sum.py bsum
60b725f10c9c85c70d97880dfe8191b3 bsum
--- a/tests/test-debugbundle.t Sun Nov 15 22:18:48 2015 +0100
+++ b/tests/test-debugbundle.t Wed Nov 18 20:59:17 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-debugcommands.t Sun Nov 15 22:18:48 2015 +0100
+++ b/tests/test-debugcommands.t Wed Nov 18 20:59:17 2015 -0600
@@ -1,3 +1,8 @@
+ $ cat << EOF >> $HGRCPATH
+ > [format]
+ > usegeneraldelta=yes
+ > EOF
+
$ hg init debugrevlog
$ cd debugrevlog
$ echo a > a
@@ -5,7 +10,7 @@
adding a
$ hg debugrevlog -m
format : 1
- flags : inline
+ flags : inline, generaldelta
revisions : 1
merges : 0 ( 0.00%)
@@ -27,16 +32,16 @@
Test debugindex, with and without the --debug flag
$ hg debugindex a
- rev offset length .... linkrev nodeid p1 p2 (re)
+ rev offset length ..... linkrev nodeid p1 p2 (re)
0 0 3 .... 0 b789fdd96dc2 000000000000 000000000000 (re)
$ hg --debug debugindex a
- rev offset length .... linkrev nodeid p1 p2 (re)
+ rev offset length ..... linkrev nodeid p1 p2 (re)
0 0 3 .... 0 b789fdd96dc2f3bd229c1dd8eedf0fc60e2b68e3 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 (re)
$ hg debugindex -f 1 a
- rev flag offset length size .... link p1 p2 nodeid (re)
+ rev flag offset length size ..... link p1 p2 nodeid (re)
0 0000 0 3 2 .... 0 -1 -1 b789fdd96dc2 (re)
$ hg --debug debugindex -f 1 a
- rev flag offset length size .... link p1 p2 nodeid (re)
+ rev flag offset length size ..... link p1 p2 nodeid (re)
0 0000 0 3 2 .... 0 -1 -1 b789fdd96dc2f3bd229c1dd8eedf0fc60e2b68e3 (re)
--- a/tests/test-encoding.t Sun Nov 15 22:18:48 2015 +0100
+++ b/tests/test-encoding.t Wed Nov 18 20:59:17 2015 -0600
@@ -272,3 +272,14 @@
0 files updated, 0 files merged, 1 files removed, 0 files unresolved
$ cd ..
+
+Test roundtrip encoding/decoding of utf8b for generated data
+
+#if hypothesis
+
+ >>> from hypothesishelpers import *
+ >>> from mercurial import encoding
+ >>> roundtrips(st.binary(), encoding.fromutf8b, encoding.toutf8b)
+ Round trip OK
+
+#endif
--- a/tests/test-fileset.t Sun Nov 15 22:18:48 2015 +0100
+++ b/tests/test-fileset.t Wed Nov 18 20:59:17 2015 -0600
@@ -163,7 +163,7 @@
$ hg merge
merging b2
warning: conflicts while merging b2! (edit, then use 'hg resolve --mark')
- 6 files updated, 0 files merged, 1 files removed, 1 files unresolved
+ * files updated, 0 files merged, 1 files removed, 1 files unresolved (glob)
use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
[1]
$ fileset 'resolved()'
--- a/tests/test-fncache.t Sun Nov 15 22:18:48 2015 +0100
+++ b/tests/test-fncache.t Wed Nov 18 20:59:17 2015 -0600
@@ -96,6 +96,7 @@
.hg/phaseroots
.hg/requires
.hg/undo
+ .hg/undo.backup.dirstate
.hg/undo.backupfiles
.hg/undo.bookmarks
.hg/undo.branch
@@ -132,6 +133,7 @@
.hg/store/undo
.hg/store/undo.backupfiles
.hg/store/undo.phaseroots
+ .hg/undo.backup.dirstate
.hg/undo.bookmarks
.hg/undo.branch
.hg/undo.desc
@@ -223,6 +225,7 @@
$ touch y
$ hg ci -qAm y
abort: forced lock failure
+ Exception mercurial.error.Abort: Abort('forced lock failure',) in <bound method lock.__del__ of <mercurial.lock.lock object at *>> ignored (glob)
[255]
$ cat .hg/store/fncache
data/y.i
--- a/tests/test-generaldelta.t Sun Nov 15 22:18:48 2015 +0100
+++ b/tests/test-generaldelta.t Wed Nov 18 20:59:17 2015 -0600
@@ -3,7 +3,7 @@
implementation of parentdelta: third manifest revision would be fully
inserted due to big distance from its paren revision (zero).
- $ hg init repo
+ $ hg init repo --config format.generaldelta=no --config format.usegeneraldelta=no
$ cd repo
$ echo foo > foo
$ echo bar > bar
@@ -62,7 +62,7 @@
o 0 3903 a
$ cd ..
- $ hg init client
+ $ hg init client --config format.generaldelta=false --config format.usegeneraldelta=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-hardlinks.t Sun Nov 15 22:18:48 2015 +0100
+++ b/tests/test-hardlinks.t Wed Nov 18 20:59:17 2015 -0600
@@ -229,6 +229,7 @@
2 r4/.hg/store/undo.backup.phaseroots
2 r4/.hg/store/undo.backupfiles
2 r4/.hg/store/undo.phaseroots
+ 2 r4/.hg/undo.backup.dirstate
2 r4/.hg/undo.bookmarks
2 r4/.hg/undo.branch
2 r4/.hg/undo.desc
@@ -264,6 +265,7 @@
2 r4/.hg/store/undo.backup.phaseroots
2 r4/.hg/store/undo.backupfiles
2 r4/.hg/store/undo.phaseroots
+ 2 r4/.hg/undo.backup.dirstate
2 r4/.hg/undo.bookmarks
2 r4/.hg/undo.branch
2 r4/.hg/undo.desc
--- a/tests/test-hgweb-commands.t Sun Nov 15 22:18:48 2015 +0100
+++ b/tests/test-hgweb-commands.t Wed Nov 18 20:59:17 2015 -0600
@@ -6,6 +6,11 @@
- unbundle, tested in test-push-http
- changegroupsubset, tested in test-pull
+ $ cat << EOF >> $HGRCPATH
+ > [format]
+ > usegeneraldelta=yes
+ > EOF
+
Set up the repo
$ hg init test
@@ -2098,10 +2103,34 @@
capabilities
- $ get-with-headers.py 127.0.0.1:$HGPORT '?cmd=capabilities'; echo
+(plain version to check the format)
+
+ $ get-with-headers.py 127.0.0.1:$HGPORT '?cmd=capabilities' | dd ibs=75 count=1 2> /dev/null; echo
200 Script output follows
- lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch stream-preferred stream bundle2=HG20%0Achangegroup%3D01%2C02%0Adigests%3Dmd5%2Csha1*%0Alistkeys%0Apushkey%0Aremote-changegroup%3Dhttp%2Chttps unbundle=HG10GZ,HG10BZ,HG10UN httpheader=1024 (glob)
+ lookup changegroupsubset branchmap pushkey known
+
+(spread version to check the content)
+
+ $ get-with-headers.py 127.0.0.1:$HGPORT '?cmd=capabilities' | tr ' ' '\n'; echo
+ 200
+ Script
+ output
+ follows
+
+ lookup
+ changegroupsubset
+ branchmap
+ pushkey
+ known
+ getbundle
+ unbundlehash
+ batch
+ stream-preferred
+ streamreqs=generaldelta,revlogv1
+ bundle2=HG20%0Achangegroup%3D01%2C02%0Adigests%3Dmd5%2Csha1%2Csha512%0Aerror%3Dabort%2Cunsupportedcontent%2Cpushraced%2Cpushkey%0Ahgtagsfnodes%0Alistkeys%0Apushkey%0Aremote-changegroup%3Dhttp%2Chttps
+ unbundle=HG10GZ,HG10BZ,HG10UN
+ httpheader=1024
heads
--- a/tests/test-hgweb-symrev.t Sun Nov 15 22:18:48 2015 +0100
+++ b/tests/test-hgweb-symrev.t Wed Nov 18 20:59:17 2015 -0600
@@ -816,7 +816,7 @@
<a href="/file/43c799df6e75/foo?style=monoblue">file</a> |
<a href="/diff/43c799df6e75/foo?style=monoblue">diff</a> |
<a href="/annotate/43c799df6e75/foo?style=monoblue">annotate</a>
- <a href="/log/43c799df6e75/foo?style=monoblue">(0)</a><a href="/log/tip/foo?style=monoblue">tip</a>
+ <a href="/log/43c799df6e75/foo?style=monoblue">(0)</a> <a href="/log/tip/foo?style=monoblue">tip</a>
$ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT 'annotate/xyzzy/foo?style=monoblue' | egrep $REVLINKS
<li><a href="/graph/xyzzy?style=monoblue">graph</a></li>
--- a/tests/test-histedit-arguments.t Sun Nov 15 22:18:48 2015 +0100
+++ b/tests/test-histedit-arguments.t Wed Nov 18 20:59:17 2015 -0600
@@ -339,7 +339,7 @@
$ mv ../corrupt-histedit .hg/histedit-state
$ hg histedit --abort
warning: encountered an exception during histedit --abort; the repository may not have been completely cleaned up
- abort: No such file or directory: * (glob)
+ abort: .*(No such file or directory:|The system cannot find the file specified).* (re)
[255]
Histedit state has been exited
$ hg summary -q
--- a/tests/test-histedit-edit.t Sun Nov 15 22:18:48 2015 +0100
+++ b/tests/test-histedit-edit.t Wed Nov 18 20:59:17 2015 -0600
@@ -364,9 +364,9 @@
HG: branch 'default'
HG: added f
====
+ note: commit message saved in .hg/last-message.txt
transaction abort!
rollback completed
- note: commit message saved in .hg/last-message.txt
abort: pretxncommit.unexpectedabort hook exited with status 1
[255]
$ cat .hg/last-message.txt
@@ -388,9 +388,9 @@
HG: user: test
HG: branch 'default'
HG: added f
+ note: commit message saved in .hg/last-message.txt
transaction abort!
rollback completed
- note: commit message saved in .hg/last-message.txt
abort: pretxncommit.unexpectedabort hook exited with status 1
[255]
--- a/tests/test-inherit-mode.t Sun Nov 15 22:18:48 2015 +0100
+++ b/tests/test-inherit-mode.t Wed Nov 18 20:59:17 2015 -0600
@@ -83,6 +83,7 @@
00660 ./.hg/store/undo
00660 ./.hg/store/undo.backupfiles
00660 ./.hg/store/undo.phaseroots
+ 00660 ./.hg/undo.backup.dirstate
00660 ./.hg/undo.bookmarks
00660 ./.hg/undo.branch
00660 ./.hg/undo.desc
--- a/tests/test-init.t Sun Nov 15 22:18:48 2015 +0100
+++ b/tests/test-init.t Wed Nov 18 20:59:17 2015 -0600
@@ -1,5 +1,12 @@
This test tries to exercise the ssh functionality with a dummy script
+(enable general delta early)
+
+ $ cat << EOF >> $HGRCPATH
+ > [format]
+ > usegeneraldelta=yes
+ > EOF
+
$ checknewrepo()
> {
> name=$1
@@ -20,6 +27,7 @@
00changelog.i created
dotencode
fncache
+ generaldelta
revlogv1
store
$ echo this > local/foo
@@ -55,6 +63,7 @@
$ hg --config format.usestore=false init old
$ checknewrepo old
+ generaldelta
revlogv1
creating repo with format.usefncache=false
@@ -63,6 +72,7 @@
$ checknewrepo old2
store created
00changelog.i created
+ generaldelta
revlogv1
store
@@ -73,6 +83,18 @@
store created
00changelog.i created
fncache
+ generaldelta
+ revlogv1
+ store
+
+creating repo with format.dotencode=false
+
+ $ hg --config format.generaldelta=false --config format.usegeneraldelta=false init old4
+ $ checknewrepo old4
+ store created
+ 00changelog.i created
+ dotencode
+ fncache
revlogv1
store
@@ -186,6 +208,7 @@
00changelog.i created
dotencode
fncache
+ generaldelta
revlogv1
store
@@ -203,6 +226,7 @@
00changelog.i created
dotencode
fncache
+ generaldelta
revlogv1
store
@@ -216,6 +240,7 @@
00changelog.i created
dotencode
fncache
+ generaldelta
revlogv1
store
--- a/tests/test-issue1502.t Sun Nov 15 22:18:48 2015 +0100
+++ b/tests/test-issue1502.t Wed Nov 18 20:59:17 2015 -0600
@@ -19,8 +19,9 @@
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files (+1 heads)
- not updating: not a linear update
+ abort: not updating: not a linear update
(merge or update --check to force update)
+ [255]
$ hg -R foo1 book branchy
$ hg -R foo1 book
--- a/tests/test-largefiles-cache.t Sun Nov 15 22:18:48 2015 +0100
+++ b/tests/test-largefiles-cache.t Wed Nov 18 20:59:17 2015 -0600
@@ -193,7 +193,7 @@
$ echo corruption > .hg/largefiles/e2fb5f2139d086ded2cb600d5a91a196e76bf020
$ hg up -C
getting changed largefiles
- large: data corruption in $TESTTMP/src/.hg/largefiles/e2fb5f2139d086ded2cb600d5a91a196e76bf020 with hash 6a7bb2556144babe3899b25e5428123735bb1e27
+ large: data corruption in $TESTTMP/src/.hg/largefiles/e2fb5f2139d086ded2cb600d5a91a196e76bf020 with hash 6a7bb2556144babe3899b25e5428123735bb1e27 (glob)
0 largefiles updated, 0 removed
0 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ hg st
--- a/tests/test-largefiles-misc.t Sun Nov 15 22:18:48 2015 +0100
+++ b/tests/test-largefiles-misc.t Wed Nov 18 20:59:17 2015 -0600
@@ -509,6 +509,18 @@
$ hg revert anotherlarge
$ hg st
? sub/anotherlarge.orig
+
+Test orig files go where we want them
+ $ echo moremore >> anotherlarge
+ $ hg revert anotherlarge -v --config 'ui.origbackuppath=.hg/origbackups'
+ creating directory: $TESTTMP/addrm2/.hg/origbackups/.hglf/sub (glob)
+ saving current version of ../.hglf/sub/anotherlarge as $TESTTMP/addrm2/.hg/origbackups/.hglf/sub/anotherlarge.orig (glob)
+ reverting ../.hglf/sub/anotherlarge (glob)
+ creating directory: $TESTTMP/addrm2/.hg/origbackups/sub (glob)
+ found 90c622cf65cebe75c5842f9136c459333faf392e in store
+ found 90c622cf65cebe75c5842f9136c459333faf392e in store
+ $ ls ../.hg/origbackups/sub
+ anotherlarge.orig
$ cd ..
Test glob logging from the root dir
--- a/tests/test-lfconvert.t Sun Nov 15 22:18:48 2015 +0100
+++ b/tests/test-lfconvert.t Wed Nov 18 20:59:17 2015 -0600
@@ -1,6 +1,8 @@
$ USERCACHE="$TESTTMP/cache"; export USERCACHE
$ mkdir "${USERCACHE}"
$ cat >> $HGRCPATH <<EOF
+ > [format]
+ > usegeneraldelta=yes
> [extensions]
> largefiles =
> share =
@@ -97,6 +99,7 @@
$ cat .hg/requires
dotencode
fncache
+ generaldelta
largefiles
revlogv1
store
--- a/tests/test-manifestv2.t Sun Nov 15 22:18:48 2015 +0100
+++ b/tests/test-manifestv2.t Wed Nov 18 20:59:17 2015 -0600
@@ -1,5 +1,10 @@
Create repo with old manifest
+ $ cat << EOF >> $HGRCPATH
+ > [format]
+ > usegeneraldelta=yes
+ > EOF
+
$ hg init existing
$ cd existing
$ echo footext > foo
@@ -91,6 +96,6 @@
Check that manifest revlog is smaller than for v1
$ hg debugindex -m
- rev offset length base linkrev nodeid p1 p2
- 0 0 81 0 0 57361477c778 000000000000 000000000000
+ rev offset length delta linkrev nodeid p1 p2
+ 0 0 81 -1 0 57361477c778 000000000000 000000000000
1 81 33 0 1 aeaab5a2ef74 57361477c778 000000000000
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-merge-changedelete.t Wed Nov 18 20:59:17 2015 -0600
@@ -0,0 +1,175 @@
+Test for
+b5605d88dc27: Make ui.prompt repeat on "unrecognized response" again
+ (issue897)
+
+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
+ > for file in file1 file2; do
+ > if [ -f $file ]; then
+ > echo "--- $file ---"
+ > cat $file
+ > else
+ > echo "*** $file does not exist"
+ > fi
+ > done
+ > }
+
+ $ hg init
+
+ $ echo 1 > file1
+ $ echo 2 > file2
+ $ hg ci -Am 'added file1 and file2'
+ adding file1
+ adding file2
+
+ $ hg rm file1
+ $ echo changed >> file2
+ $ hg ci -m 'removed file1, changed file2'
+
+ $ hg co 0
+ 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+ $ echo changed >> file1
+ $ hg rm file2
+ $ hg ci -m 'changed file1, removed file2'
+ created new head
+
+
+Non-interactive merge:
+
+ $ hg merge -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
+ (branch merge, don't forget to commit)
+
+ $ status
+ --- status ---
+ M file2
+ C file1
+ --- file1 ---
+ 1
+ changed
+ --- file2 ---
+ 2
+ changed
+
+
+Interactive merge:
+
+ $ hg co -C
+ 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+
+ $ hg merge --config ui.interactive=true <<EOF
+ > c
+ > d
+ > EOF
+ 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? d
+ 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ (branch merge, don't forget to commit)
+
+ $ status
+ --- status ---
+ file2: * (glob)
+ C file1
+ --- file1 ---
+ 1
+ changed
+ *** file2 does not exist
+
+
+Interactive merge with bad input:
+
+ $ hg co -C
+ 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+ $ hg merge --config ui.interactive=true <<EOF
+ > foo
+ > bar
+ > d
+ > baz
+ > c
+ > EOF
+ local changed file1 which remote deleted
+ use (c)hanged version or (d)elete? foo
+ unrecognized response
+ local changed file1 which remote deleted
+ use (c)hanged version or (d)elete? bar
+ unrecognized response
+ local changed file1 which remote deleted
+ use (c)hanged version or (d)elete? d
+ remote changed file2 which local deleted
+ use (c)hanged version or leave (d)eleted? baz
+ unrecognized response
+ remote changed file2 which local deleted
+ use (c)hanged version or leave (d)eleted? c
+ 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+ (branch merge, don't forget to commit)
+
+ $ status
+ --- status ---
+ M file2
+ R file1
+ *** file1 does not exist
+ --- file2 ---
+ 2
+ changed
+
+
+Interactive merge with not enough input:
+
+ $ hg co -C
+ 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+
+ $ hg merge --config ui.interactive=true <<EOF
+ > d
+ > EOF
+ local changed file1 which remote deleted
+ use (c)hanged version or (d)elete? d
+ remote changed file2 which local deleted
+ use (c)hanged version or leave (d)eleted? abort: response expected
+ [255]
+
+ $ status
+ --- status ---
+ file2: * (glob)
+ C file1
+ --- file1 ---
+ 1
+ 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-local.t Sun Nov 15 22:18:48 2015 +0100
+++ b/tests/test-merge-local.t Wed Nov 18 20:59:17 2015 -0600
@@ -91,7 +91,7 @@
use 'hg resolve' to retry unresolved file merges
[1]
- $ hg co 0
+ $ hg co 0 --config 'ui.origbackuppath=.hg/origbackups'
merging zzz1_merge_ok
merging zzz2_merge_bad
warning: conflicts while merging zzz2_merge_bad! (edit, then use 'hg resolve --mark')
@@ -99,6 +99,10 @@
use 'hg resolve' to retry unresolved file merges
[1]
+Are orig files from the last commit where we want them?
+ $ ls .hg/origbackups
+ zzz2_merge_bad.orig
+
$ hg diff --nodates | grep "^[+-][^<>]"
--- a/zzz1_merge_ok
+++ b/zzz1_merge_ok
--- a/tests/test-merge-prompt.t Sun Nov 15 22:18:48 2015 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,150 +0,0 @@
-Test for
-b5605d88dc27: Make ui.prompt repeat on "unrecognized response" again
- (issue897)
-
-840e2b315c1f: Fix misleading error and prompts during update/merge
- (issue556)
-
- $ status() {
- > echo "--- status ---"
- > hg st -A file1 file2
- > for file in file1 file2; do
- > if [ -f $file ]; then
- > echo "--- $file ---"
- > cat $file
- > else
- > echo "*** $file does not exist"
- > fi
- > done
- > }
-
- $ hg init
-
- $ echo 1 > file1
- $ echo 2 > file2
- $ hg ci -Am 'added file1 and file2'
- adding file1
- adding file2
-
- $ hg rm file1
- $ echo changed >> file2
- $ hg ci -m 'removed file1, changed file2'
-
- $ hg co 0
- 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
-
- $ echo changed >> file1
- $ hg rm file2
- $ hg ci -m 'changed file1, removed file2'
- created new head
-
-
-Non-interactive merge:
-
- $ hg merge -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
- (branch merge, don't forget to commit)
-
- $ status
- --- status ---
- M file2
- C file1
- --- file1 ---
- 1
- changed
- --- file2 ---
- 2
- changed
-
-
-Interactive merge:
-
- $ hg co -C
- 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
-
- $ hg merge --config ui.interactive=true <<EOF
- > c
- > d
- > EOF
- 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? d
- 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
- (branch merge, don't forget to commit)
-
- $ status
- --- status ---
- file2: * (glob)
- C file1
- --- file1 ---
- 1
- changed
- *** file2 does not exist
-
-
-Interactive merge with bad input:
-
- $ hg co -C
- 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
-
- $ hg merge --config ui.interactive=true <<EOF
- > foo
- > bar
- > d
- > baz
- > c
- > EOF
- local changed file1 which remote deleted
- use (c)hanged version or (d)elete? foo
- unrecognized response
- local changed file1 which remote deleted
- use (c)hanged version or (d)elete? bar
- unrecognized response
- local changed file1 which remote deleted
- use (c)hanged version or (d)elete? d
- remote changed file2 which local deleted
- use (c)hanged version or leave (d)eleted? baz
- unrecognized response
- remote changed file2 which local deleted
- use (c)hanged version or leave (d)eleted? c
- 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
- (branch merge, don't forget to commit)
-
- $ status
- --- status ---
- M file2
- R file1
- *** file1 does not exist
- --- file2 ---
- 2
- changed
-
-
-Interactive merge with not enough input:
-
- $ hg co -C
- 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
-
- $ hg merge --config ui.interactive=true <<EOF
- > d
- > EOF
- local changed file1 which remote deleted
- use (c)hanged version or (d)elete? d
- remote changed file2 which local deleted
- use (c)hanged version or leave (d)eleted? abort: response expected
- [255]
-
- $ status
- --- status ---
- file2: * (glob)
- C file1
- --- file1 ---
- 1
- changed
- *** file2 does not exist
-
--- a/tests/test-merge-tools.t Sun Nov 15 22:18:48 2015 +0100
+++ b/tests/test-merge-tools.t Wed Nov 18 20:59:17 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:
@@ -493,7 +531,7 @@
true.executable=cat
# hg update -C 1
$ hg merge -r 2 --config ui.merge=internal:prompt
- no tool found to merge f
+ no tool found to merge f
keep (l)ocal or take (o)ther? l
0 files updated, 1 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)
@@ -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 Sun Nov 15 22:18:48 2015 +0100
+++ b/tests/test-merge-types.t Wed Nov 18 20:59:17 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
@@ -127,7 +171,7 @@
a: versions differ -> m (premerge)
(couldn't find merge tool hgmerge|tool hgmerge can't handle symlinks) (re)
picked tool ':prompt' for a (binary False symlink True)
- no tool found to merge a
+ no tool found to merge a
keep (l)ocal or take (o)ther? l
0 files updated, 1 files merged, 0 files removed, 0 files unresolved
$ hg diff --git
--- a/tests/test-module-imports.t Sun Nov 15 22:18:48 2015 +0100
+++ b/tests/test-module-imports.t Wed Nov 18 20:59:17 2015 -0600
@@ -68,6 +68,23 @@
> from .. import parent
> EOF
+ $ touch testpackage/subpackage/foo.py
+ $ cat > testpackage/subpackage/__init__.py << EOF
+ > from __future__ import absolute_import
+ > from . import levelpriority # should not cause cycle
+ > EOF
+
+ $ cat > testpackage/subpackage/localimport.py << EOF
+ > from __future__ import absolute_import
+ > from . import foo
+ > def bar():
+ > # should not cause "higher-level import should come first"
+ > from .. import unsorted
+ > # but other errors should be detected
+ > from .. import more
+ > import testpackage.subpackage.levelpriority
+ > EOF
+
$ cat > testpackage/sortedentries.py << EOF
> from __future__ import absolute_import
> from . import (
@@ -87,20 +104,22 @@
> EOF
$ python "$import_checker" testpackage/*.py testpackage/subpackage/*.py
- testpackage/importalias.py ui module must be "as" aliased to uimod
- testpackage/importfromalias.py ui from testpackage must be "as" aliased to uimod
- testpackage/importfromrelative.py import should be relative: testpackage.unsorted
- testpackage/importfromrelative.py direct symbol import from testpackage.unsorted
- testpackage/latesymbolimport.py symbol import follows non-symbol import: mercurial.node
- testpackage/multiple.py multiple imported names: os, sys
- testpackage/multiplegroups.py multiple "from . import" statements
- testpackage/relativestdlib.py relative import of stdlib module
- testpackage/requirerelative.py import should be relative: testpackage.unsorted
- testpackage/sortedentries.py imports from testpackage not lexically sorted: bar < foo
- testpackage/stdafterlocal.py stdlib import follows local import: os
- testpackage/subpackage/levelpriority.py higher-level import should come first: testpackage
- testpackage/symbolimport.py direct symbol import from testpackage.unsorted
- testpackage/unsorted.py imports not lexically sorted: os < sys
+ testpackage/importalias.py:2: ui module must be "as" aliased to uimod
+ testpackage/importfromalias.py:2: ui from testpackage must be "as" aliased to uimod
+ testpackage/importfromrelative.py:2: import should be relative: testpackage.unsorted
+ testpackage/importfromrelative.py:2: direct symbol import from testpackage.unsorted
+ testpackage/latesymbolimport.py:3: symbol import follows non-symbol import: mercurial.node
+ testpackage/multiple.py:2: multiple imported names: os, sys
+ testpackage/multiplegroups.py:3: multiple "from . import" statements
+ testpackage/relativestdlib.py:2: relative import of stdlib module
+ testpackage/requirerelative.py:2: import should be relative: testpackage.unsorted
+ testpackage/sortedentries.py:2: imports from testpackage not lexically sorted: bar < foo
+ testpackage/stdafterlocal.py:3: stdlib import follows local import: os
+ testpackage/subpackage/levelpriority.py:3: higher-level import should come first: testpackage
+ testpackage/subpackage/localimport.py:7: multiple "from .. import" statements
+ testpackage/subpackage/localimport.py:8: import should be relative: testpackage.subpackage.levelpriority
+ testpackage/symbolimport.py:2: direct symbol import from testpackage.unsorted
+ testpackage/unsorted.py:3: imports not lexically sorted: os < sys
[1]
$ cd "$TESTDIR"/..
--- a/tests/test-mq-qfold.t Sun Nov 15 22:18:48 2015 +0100
+++ b/tests/test-mq-qfold.t Wed Nov 18 20:59:17 2015 -0600
@@ -229,9 +229,9 @@
HG: added aa
HG: changed a
====
+ note: commit message saved in .hg/last-message.txt
transaction abort!
rollback completed
- note: commit message saved in .hg/last-message.txt
qrefresh interrupted while patch was popped! (revert --all, qpush to recover)
abort: pretxncommit.unexpectedabort hook exited with status 1
[255]
--- a/tests/test-mq-qnew.t Sun Nov 15 22:18:48 2015 +0100
+++ b/tests/test-mq-qnew.t Wed Nov 18 20:59:17 2015 -0600
@@ -299,9 +299,9 @@
HG: branch 'default'
HG: no files changed
====
+ note: commit message saved in .hg/last-message.txt
transaction abort!
rollback completed
- note: commit message saved in .hg/last-message.txt
abort: pretxncommit.unexpectedabort hook exited with status 1
[255]
$ cat .hg/last-message.txt
--- a/tests/test-mq-qpush-fail.t Sun Nov 15 22:18:48 2015 +0100
+++ b/tests/test-mq-qpush-fail.t Wed Nov 18 20:59:17 2015 -0600
@@ -444,7 +444,7 @@
$ hg st a
M a
$ echo b >> b
- $ hg --config mq.keepchanges=1 qpop --force
+ $ hg --config mq.keepchanges=1 qpop --force --config 'ui.origbackuppath=.hg/origbackups'
popping p3
now at: p2
$ hg st b
@@ -461,4 +461,10 @@
now at: p2
$ hg st a
+test previous qpop (with --force and --config) saved .orig files to where user
+wants them
+ $ ls .hg/origbackups
+ b.orig
+ $ rm -rf .hg/origbackups
+
$ cd ..
--- a/tests/test-mq-qrefresh-replace-log-message.t Sun Nov 15 22:18:48 2015 +0100
+++ b/tests/test-mq-qrefresh-replace-log-message.t Wed Nov 18 20:59:17 2015 -0600
@@ -185,9 +185,9 @@
HG: branch 'default'
HG: added file2
====
+ note: commit message saved in .hg/last-message.txt
transaction abort!
rollback completed
- note: commit message saved in .hg/last-message.txt
qrefresh interrupted while patch was popped! (revert --all, qpush to recover)
abort: pretxncommit.unexpectedabort hook exited with status 1
[255]
@@ -228,9 +228,9 @@
0:25e397dabed2
A file2
====
+ note: commit message saved in .hg/last-message.txt
transaction abort!
rollback completed
- note: commit message saved in .hg/last-message.txt
qrefresh interrupted while patch was popped! (revert --all, qpush to recover)
abort: pretxncommit.unexpectedabort hook exited with status 1
[255]
--- a/tests/test-mq.t Sun Nov 15 22:18:48 2015 +0100
+++ b/tests/test-mq.t Wed Nov 18 20:59:17 2015 -0600
@@ -1394,9 +1394,10 @@
apply force, should discard changes in hello, but not bye
- $ hg qpush -f --verbose
+ $ hg qpush -f --verbose --config 'ui.origbackuppath=.hg/origbackups'
applying empty
- saving current version of hello.txt as hello.txt.orig
+ creating directory: $TESTTMP/forcepush/.hg/origbackups (glob)
+ saving current version of hello.txt as $TESTTMP/forcepush/.hg/origbackups/hello.txt.orig (glob)
patching file hello.txt
committing files:
hello.txt
@@ -1405,7 +1406,6 @@
now at: empty
$ hg st
M bye.txt
- ? hello.txt.orig
$ hg diff --config diff.nodates=True
diff -r ba252371dbc1 bye.txt
--- a/bye.txt
@@ -1428,6 +1428,10 @@
+world
+universe
+test that the previous call to qpush with -f (--force) and --config actually put
+the orig files out of the working copy
+ $ ls .hg/origbackups
+ hello.txt.orig
test popping revisions not in working dir ancestry
--- a/tests/test-patchbomb.t Sun Nov 15 22:18:48 2015 +0100
+++ b/tests/test-patchbomb.t Wed Nov 18 20:59:17 2015 -0600
@@ -23,6 +23,8 @@
> print l,
> EOF
$ FILTERBOUNDARY="python `pwd`/prune-blank-after-boundary.py"
+ $ echo "[format]" >> $HGRCPATH
+ $ echo "usegeneraldelta=yes" >> $HGRCPATH
$ echo "[extensions]" >> $HGRCPATH
$ echo "patchbomb=" >> $HGRCPATH
@@ -347,21 +349,22 @@
Content-Disposition: attachment; filename="bundle.hg"
Content-Transfer-Encoding: base64
- SEcxMEJaaDkxQVkmU1nvR7I3AAAN////lFYQWj1/4HwRkdC/AywIAk0E4pfoSIIIgQCgGEQOcLAA
- 2tA1VPyp4mkeoG0EaaPU0GTT1GjRiNPIg9CZGBqZ6UbU9J+KFU09DNUaGgAAAAAANAGgAAAAA1U8
- oGgAADQGgAANNANAAAAAAZipFLz3XoakCEQB3PVPyHJVi1iYkAAKQAZQGpQGZESInRnCFMqLDla2
- Bx3qfRQeA2N4lnzKkAmP8kR2asievLLXXebVU8Vg4iEBqcJNJAxIapSU6SM4888ZAciRG6MYAIEE
- SlIBpFisgGkyRjX//TMtfcUAEsGu56+YnE1OlTZmzKm8BSu2rvo4rHAYYaadIFFuTy0LYgIkgLVD
- sgVa2F19D1tx9+hgbAygLgQwaIqcDdgA4BjQgIiz/AEP72++llgDKhKducqodGE4B0ETqF3JFOFC
- Q70eyNw=
- --===*=-- (glob)
+ SEcyMAAAAA5Db21wcmVzc2lvbj1CWkJaaDkxQVkmU1lCZFwPAAAKf//7nFYSWD1/4H7R09C/I70I
+ Ak0E4peoSIYIgQCgGUQOcLABGY2hqoAAAaBMTTAAAahgTCZoAAAAAMQaqn5GmapojQ00DEGI/VGJ
+ kDAJoGTDUAAyM0QaAEqalPTUaMhoyDIDR6IxAGEGmgAehMRhDRsoyB6TYTC8JyLN+jTGqitRAgRJ
+ b3SRlhd8/+VxlAUqAilLoKPEEyxFQkaEGo+DzItFeNiFAo8NMMweVtvXJFIMhjoKC18DeYwjLKBz
+ wrMcs86qJrctDNJorwBMuLcqvTVWHh1IlsIaaaYSUIP2IZsogT1+pSSZS+bSTJrgfKsO9go/f0HF
+ uW4Yr2vXpxDreOgSIAdK/xC8Yay48SLpxIuqc/BZ6rVZCgG21rr0zhCaEgXOTqNaYEvANvg0B0Qo
+ dgtqAs1FDcZgzYitwJh6ZAG0C4mA7FPrp9b7h0h/A44Xgd+0it1gvF0mFE/CCPwymXS+OisOOCAF
+ mDUDAC1pBvsXckU4UJBCZFwP
+ --===============*==-- (glob)
with a specific bundle type
(binary part must be different)
$ hg email --date '1970-1-1 0:3' -n -f quux -t foo \
> -c bar -s test -r tip -b --desc description \
- > --config patchbomb.bundletype=gzip | $FILTERBOUNDARY
+ > --config patchbomb.bundletype=gzip-v1 | $FILTERBOUNDARY
searching for changes
1 changesets found
--- a/tests/test-pathencode.py Sun Nov 15 22:18:48 2015 +0100
+++ b/tests/test-pathencode.py Wed Nov 18 20:59:17 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-pull-update.t Sun Nov 15 22:18:48 2015 +0100
+++ b/tests/test-pull-update.t Wed Nov 18 20:59:17 2015 -0600
@@ -25,8 +25,9 @@
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files (+1 heads)
- not updating: not a linear update
+ abort: not updating: not a linear update
(merge or update --check to force update)
+ [255]
$ cd ../tt
@@ -39,8 +40,9 @@
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files (+1 heads)
- not updating: not a linear update
+ abort: not updating: not a linear update
(merge or update --check to force update)
+ [255]
$ HGMERGE=true hg merge
merging foo
--- a/tests/test-push-cgi.t Sun Nov 15 22:18:48 2015 +0100
+++ b/tests/test-push-cgi.t Wed Nov 18 20:59:17 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-conflicts.t Sun Nov 15 22:18:48 2015 +0100
+++ b/tests/test-rebase-conflicts.t Wed Nov 18 20:59:17 2015 -0600
@@ -1,4 +1,6 @@
$ cat >> $HGRCPATH <<EOF
+ > [format]
+ > usegeneraldelta=yes
> [extensions]
> rebase=
>
@@ -275,13 +277,19 @@
list of changesets:
e31216eec445e44352c5f01588856059466a24c9
2f2496ddf49d69b5ef23ad8cf9fb2e0e4faf0ac2
+ bundle2-output-bundle: "HG20", (1 params) 1 parts total
+ bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
saved backup bundle to $TESTTMP/issue4041/.hg/strip-backup/e31216eec445-15f7a814-backup.hg (glob)
3 changesets found
list of changesets:
4c9fbe56a16f30c0d5dcc40ec1a97bbe3325209c
19c888675e133ab5dff84516926a65672eaf04d9
2a7f09cac94c7f4b73ebd5cd1a62d3b2e8e336bf
+ bundle2-output-bundle: "HG20", 1 parts total
+ bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
adding branch
+ bundle2-input-bundle: with-transaction
+ bundle2-input-part: "changegroup" (params: 1 mandatory) supported
adding changesets
add changeset 4c9fbe56a16f
add changeset 19c888675e13
@@ -290,6 +298,8 @@
adding file changes
adding f1.txt revisions
added 2 changesets with 2 changes to 1 files
+ bundle2-input-part: total payload size 1713
+ bundle2-input-bundle: 0 parts total
invalid branchheads cache (served): tip differs
rebase completed
updating the branch cache
--- a/tests/test-rebase-mq-skip.t Sun Nov 15 22:18:48 2015 +0100
+++ b/tests/test-rebase-mq-skip.t Wed Nov 18 20:59:17 2015 -0600
@@ -2,6 +2,8 @@
already has one local mq patch
$ cat >> $HGRCPATH <<EOF
+ > [format]
+ > usegeneraldelta=yes
> [extensions]
> rebase=
> mq=
@@ -68,17 +70,17 @@
$TESTTMP/a/.hg/patches/p0.patch (glob)
2 changesets found
uncompressed size of bundle content:
- 344 (changelog)
- 284 (manifests)
- 109 p0
- 109 p1
+ 384 (changelog)
+ 324 (manifests)
+ 129 p0
+ 129 p1
saved backup bundle to $TESTTMP/a/.hg/strip-backup/13a46ce44f60-5da6ecfb-backup.hg (glob)
2 changesets found
uncompressed size of bundle content:
- 399 (changelog)
- 284 (manifests)
- 109 p0
- 109 p1
+ 439 (changelog)
+ 324 (manifests)
+ 129 p0
+ 129 p1
adding branch
adding changesets
adding manifests
--- a/tests/test-rebase-newancestor.t Sun Nov 15 22:18:48 2015 +0100
+++ b/tests/test-rebase-newancestor.t Wed Nov 18 20:59:17 2015 -0600
@@ -1,4 +1,6 @@
$ cat >> $HGRCPATH <<EOF
+ > [format]
+ > usegeneraldelta=yes
> [extensions]
> rebase=
>
@@ -298,15 +300,15 @@
rebase merging completed
1 changesets found
uncompressed size of bundle content:
- 193 (changelog)
- 196 (manifests)
- 162 other
+ 213 (changelog)
+ 216 (manifests)
+ 182 other
saved backup bundle to $TESTTMP/parentorder/.hg/strip-backup/4c5f12f25ebe-f46990e5-backup.hg (glob)
1 changesets found
uncompressed size of bundle content:
- 252 (changelog)
- 147 (manifests)
- 162 other
+ 272 (changelog)
+ 167 (manifests)
+ 182 other
adding branch
adding changesets
adding manifests
--- a/tests/test-rebase-obsolete.t Sun Nov 15 22:18:48 2015 +0100
+++ b/tests/test-rebase-obsolete.t Wed Nov 18 20:59:17 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-rename-merge1.t Sun Nov 15 22:18:48 2015 +0100
+++ b/tests/test-rename-merge1.t Wed Nov 18 20:59:17 2015 -0600
@@ -36,6 +36,9 @@
resolving manifests
branchmerge: True, force: False, partial: False
ancestor: af1939970a1c, local: 044f8520aeeb+, remote: 85c198ef2f6c
+ note: possible conflict - a2 was renamed multiple times to:
+ c2
+ b2
preserving a for resolve of b
removing a
b2: remote created -> g
@@ -45,9 +48,6 @@
merging a and b to b
my b@044f8520aeeb+ other b@85c198ef2f6c ancestor a@af1939970a1c
premerge successful
- note: possible conflict - a2 was renamed multiple times to:
- c2
- b2
1 files updated, 1 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)
@@ -177,10 +177,10 @@
resolving manifests
branchmerge: True, force: False, partial: False
ancestor: 19d7f95df299, local: 0084274f6b67+, remote: 5d32493049f0
+ note: possible conflict - file was deleted and renamed to:
+ newfile
newfile: remote created -> g
getting newfile
- note: possible conflict - file was deleted and renamed to:
- newfile
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)
$ hg status
--- a/tests/test-rename-merge2.t Sun Nov 15 22:18:48 2015 +0100
+++ b/tests/test-rename-merge2.t Wed Nov 18 20:59:17 2015 -0600
@@ -411,6 +411,9 @@
resolving manifests
branchmerge: True, force: False, partial: False
ancestor: 924404dff337, local: 02963e448370+, remote: fe905ef2c33e
+ note: possible conflict - a was renamed multiple times to:
+ b
+ c
preserving rev for resolve of rev
c: remote created -> g
getting c
@@ -423,9 +426,6 @@
my rev@02963e448370+ other rev@fe905ef2c33e ancestor rev@924404dff337
launching merge tool: python ../merge *$TESTTMP/t/t/rev* * * (glob)
merge tool returned: 0
- note: possible conflict - a was renamed multiple times to:
- b
- c
1 files updated, 1 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)
--------------
@@ -922,7 +922,7 @@
$ mkdir 7 8
$ echo m > 7/f
$ echo m > 8/f
- $ hg merge -f --tool internal:dump -v --debug -r2 | sed '/^ 0\/f: both created -> m/,$d' 2> /dev/null
+ $ hg merge -f --tool internal:dump -v --debug -r2 | sed '/^resolving manifests/,$d' 2> /dev/null
searching for copies back to rev 1
unmatched files in local:
5/g
@@ -940,24 +940,6 @@
src: '5/f' -> dst: '5/g' *
src: '6/f' -> dst: '6/g' *
checking for directory renames
- resolving manifests
- branchmerge: True, force: True, partial: False
- ancestor: e6cb3cf11019, local: ec44bf929ab5+, remote: c62e34d0b898
- remote changed 8/f which local deleted
- use (c)hanged version or leave (d)eleted? c
- preserving 0/f for resolve of 0/f
- preserving 1/g for resolve of 1/g
- preserving 2/f for resolve of 2/f
- preserving 3/f for resolve of 3/f
- preserving 3/f for resolve of 3/g
- preserving 4/f for resolve of 4/g
- preserving 5/f for resolve of 5/f
- preserving 5/g for resolve of 5/g
- preserving 6/g for resolve of 6/g
- preserving 7/f for resolve of 7/f
- removing 4/f
- 8/f: prompt recreating -> g
- getting 8/f
$ hg mani
0/f
1/g
--- a/tests/test-resolve.t Sun Nov 15 22:18:48 2015 +0100
+++ b/tests/test-resolve.t Wed Nov 18 20:59:17 2015 -0600
@@ -66,7 +66,7 @@
> def markdriver(ui, repo, *pats, **opts):
> wlock = repo.wlock()
> try:
- > ms = merge.mergestate(repo)
+ > ms = merge.mergestate.read(repo)
> m = scmutil.match(repo[None], pats, opts)
> for f in ms:
> if not m(f):
@@ -197,6 +197,18 @@
$ cat file2.orig
foo
baz
+
+.orig files should exists where specified
+ $ hg resolve --all --verbose --config 'ui.origbackuppath=.hg/origbackups'
+ merging file1
+ creating directory: $TESTTMP/repo/.hg/origbackups (glob)
+ merging file2
+ warning: conflicts while merging file1! (edit, then use 'hg resolve --mark')
+ warning: conflicts while merging file2! (edit, then use 'hg resolve --mark')
+ [1]
+ $ ls .hg/origbackups
+ file1.orig
+ file2.orig
$ grep '<<<' file1 > /dev/null
$ grep '<<<' file2 > /dev/null
--- a/tests/test-revert.t Sun Nov 15 22:18:48 2015 +0100
+++ b/tests/test-revert.t Wed Nov 18 20:59:17 2015 -0600
@@ -86,6 +86,16 @@
saving current version of e as e.orig
reverting e
+Test creation of backup (.orig) file in configured file location
+----------------------------------------------------------------
+
+ $ echo z > e
+ $ hg revert --all -v --config 'ui.origbackuppath=.hg/origbackups'
+ creating directory: $TESTTMP/repo/.hg/origbackups (glob)
+ saving current version of e as $TESTTMP/repo/.hg/origbackups/e.orig (glob)
+ reverting e
+ $ rm -rf .hg/origbackups
+
revert on clean file (no change)
--------------------------------
--- a/tests/test-rollback.t Sun Nov 15 22:18:48 2015 +0100
+++ b/tests/test-rollback.t Wed Nov 18 20:59:17 2015 -0600
@@ -113,9 +113,9 @@
> echo "another precious commit message" > "$1"
> __EOF__
$ HGEDITOR="\"sh\" \"`pwd`/editor.sh\"" hg --config hooks.pretxncommit=false commit 2>&1
+ note: commit message saved in .hg/last-message.txt
transaction abort!
rollback completed
- note: commit message saved in .hg/last-message.txt
abort: pretxncommit hook exited with status * (glob)
[255]
$ cat .hg/last-message.txt
--- a/tests/test-shelve.t Sun Nov 15 22:18:48 2015 +0100
+++ b/tests/test-shelve.t Wed Nov 18 20:59:17 2015 -0600
@@ -971,7 +971,7 @@
no general delta
- $ hg clone --pull repo bundle1 --config format.generaldelta=0
+ $ hg clone --pull repo bundle1 --config format.usegeneraldelta=0
requesting all changes
adding changesets
adding manifests
@@ -991,7 +991,7 @@
with general delta
- $ hg clone --pull repo bundle2 --config format.generaldelta=1
+ $ hg clone --pull repo bundle2 --config format.usegeneraldelta=1
requesting all changes
adding changesets
adding manifests
@@ -1135,7 +1135,7 @@
$ cd ..
-test Abort unshelve always gets user out of the unshelved state
+test .orig files go where the user wants them to
---------------------------------------------------------------
$ hg init salvage
$ cd salvage
@@ -1144,15 +1144,21 @@
$ echo '' > root
$ hg shelve -q
$ echo 'contADDent' > root
- $ hg unshelve -q
+ $ hg unshelve -q --config 'ui.origbackuppath=.hg/origbackups'
warning: conflicts while merging root! (edit, then use 'hg resolve --mark')
unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
[1]
+ $ ls .hg/origbackups
+ root.orig
+ $ rm -rf .hg/origbackups
+
+test Abort unshelve always gets user out of the unshelved state
+---------------------------------------------------------------
Wreak havoc on the unshelve process
$ rm .hg/unshelverebasestate
$ hg unshelve --abort
unshelve of 'default' aborted
- abort: No such file or directory
+ abort: (No such file or directory|The system cannot find the file specified) (re)
[255]
Can the user leave the current state?
$ hg up -C .
--- a/tests/test-ssh-bundle1.t Sun Nov 15 22:18:48 2015 +0100
+++ b/tests/test-ssh-bundle1.t Wed Nov 18 20:59:17 2015 -0600
@@ -5,6 +5,8 @@
> [experimental]
> # This test is dedicated to interaction through old bundle
> bundle2-exp = False
+ > [format] # temporary settings
+ > usegeneraldelta=yes
> EOF
@@ -460,8 +462,8 @@
running python ".*/dummyssh" user@dummy ('|")hg -R remote serve --stdio('|") (re)
sending hello command
sending between command
- remote: 345
- remote: capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch stream bundle2=HG20%0Achangegroup%3D01%2C02%0Adigests%3Dmd5%2Csha1%2Csha512%0Aerror%3Dabort%2Cunsupportedcontent%2Cpushraced%2Cpushkey%0Ahgtagsfnodes%0Alistkeys%0Apushkey%0Aremote-changegroup%3Dhttp%2Chttps unbundle=HG10GZ,HG10BZ,HG10UN httpheader=1024
+ remote: 371
+ remote: capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 bundle2=HG20%0Achangegroup%3D01%2C02%0Adigests%3Dmd5%2Csha1%2Csha512%0Aerror%3Dabort%2Cunsupportedcontent%2Cpushraced%2Cpushkey%0Ahgtagsfnodes%0Alistkeys%0Apushkey%0Aremote-changegroup%3Dhttp%2Chttps unbundle=HG10GZ,HG10BZ,HG10UN httpheader=1024
remote: 1
preparing listkeys for "bookmarks"
sending listkeys command
--- a/tests/test-ssh.t Sun Nov 15 22:18:48 2015 +0100
+++ b/tests/test-ssh.t Wed Nov 18 20:59:17 2015 -0600
@@ -1,6 +1,11 @@
This test tries to exercise the ssh functionality with a dummy script
+ $ cat <<EOF >> $HGRCPATH
+ > [format]
+ > usegeneraldelta=yes
+ > EOF
+
creating 'remote' repo
$ hg init remote
@@ -449,8 +454,8 @@
running python ".*/dummyssh" user@dummy ('|")hg -R remote serve --stdio('|") (re)
sending hello command
sending between command
- remote: 345
- remote: capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch stream bundle2=HG20%0Achangegroup%3D01%2C02%0Adigests%3Dmd5%2Csha1%2Csha512%0Aerror%3Dabort%2Cunsupportedcontent%2Cpushraced%2Cpushkey%0Ahgtagsfnodes%0Alistkeys%0Apushkey%0Aremote-changegroup%3Dhttp%2Chttps unbundle=HG10GZ,HG10BZ,HG10UN httpheader=1024
+ remote: 371
+ remote: capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 bundle2=HG20%0Achangegroup%3D01%2C02%0Adigests%3Dmd5%2Csha1%2Csha512%0Aerror%3Dabort%2Cunsupportedcontent%2Cpushraced%2Cpushkey%0Ahgtagsfnodes%0Alistkeys%0Apushkey%0Aremote-changegroup%3Dhttp%2Chttps unbundle=HG10GZ,HG10BZ,HG10UN httpheader=1024
remote: 1
query 1; heads
sending batch command
--- a/tests/test-strip.t Sun Nov 15 22:18:48 2015 +0100
+++ b/tests/test-strip.t Wed Nov 18 20:59:17 2015 -0600
@@ -1,3 +1,5 @@
+ $ echo "[format]" >> $HGRCPATH
+ $ echo "usegeneraldelta=yes" >> $HGRCPATH
$ echo "[extensions]" >> $HGRCPATH
$ echo "strip=" >> $HGRCPATH
@@ -208,7 +210,9 @@
summary: b
$ hg debugbundle .hg/strip-backup/*
- 264128213d290d868c54642d13aeaa3675551a78
+ Stream params: {'Compression': 'BZ'}
+ changegroup -- "{'version': '02'}"
+ 264128213d290d868c54642d13aeaa3675551a78
$ hg pull .hg/strip-backup/*
pulling from .hg/strip-backup/264128213d29-0b39d6bf-backup.hg
searching for changes
@@ -751,6 +755,8 @@
list of changesets:
6625a516847449b6f0fa3737b9ba56e9f0f3032c
d8db9d1372214336d2b5570f20ee468d2c72fa8b
+ bundle2-output-bundle: "HG20", (1 params) 1 parts total
+ bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
saved backup bundle to $TESTTMP/issue4736/.hg/strip-backup/6625a5168474-345bb43d-backup.hg (glob)
invalid branchheads cache (served): tip differs
truncating cache/rbc-revs-v1 to 24
--- a/tests/test-subrepo-git.t Sun Nov 15 22:18:48 2015 +0100
+++ b/tests/test-subrepo-git.t Wed Nov 18 20:59:17 2015 -0600
@@ -875,6 +875,16 @@
$ hg status --subrepos
? s/barfoo
+revert moves orig files to the right place
+ $ echo 'bloop' > s/foobar
+ $ hg revert --all --verbose --config 'ui.origbackuppath=.hg/origbackups'
+ reverting subrepo ../gitroot
+ creating directory: $TESTTMP/tc/.hg/origbackups (glob)
+ saving current version of foobar as $TESTTMP/tc/.hg/origbackups/foobar.orig (glob)
+ $ ls .hg/origbackups
+ foobar.orig
+ $ rm -rf .hg/origbackups
+
show file at specific revision
$ cat > s/foobar << EOF
> woop woop
--- a/tests/test-tag.t Sun Nov 15 22:18:48 2015 +0100
+++ b/tests/test-tag.t Wed Nov 18 20:59:17 2015 -0600
@@ -272,9 +272,9 @@
HG: branch 'tag-and-branch-same-name'
HG: changed .hgtags
====
+ note: commit message saved in .hg/last-message.txt
transaction abort!
rollback completed
- note: commit message saved in .hg/last-message.txt
abort: pretxncommit.unexpectedabort hook exited with status 1
[255]
$ cat .hg/last-message.txt
--- a/tests/test-template-engine.t Sun Nov 15 22:18:48 2015 +0100
+++ b/tests/test-template-engine.t Wed Nov 18 20:59:17 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 ..
--- a/tests/test-tools.t Sun Nov 15 22:18:48 2015 +0100
+++ b/tests/test-tools.t Wed Nov 18 20:59:17 2015 -0600
@@ -43,7 +43,13 @@
foo: mode=644
#endif
+#if no-windows
$ python $TESTDIR/seq.py 10 > bar
+#else
+Convert CRLF -> LF for consistency
+ $ python $TESTDIR/seq.py 10 | sed "s/$//" > bar
+#endif
+
#if unix-permissions symlink
$ chmod +x bar
$ f bar --newer foo --mode --type --size --dump --links --bytes 7
--- a/tests/test-treemanifest.t Sun Nov 15 22:18:48 2015 +0100
+++ b/tests/test-treemanifest.t Wed Nov 18 20:59:17 2015 -0600
@@ -1,3 +1,7 @@
+ $ cat << EOF >> $HGRCPATH
+ > [format]
+ > usegeneraldelta=yes
+ > EOF
Set up repo
@@ -118,13 +122,13 @@
$ cat dir1/b
6
$ hg debugindex --dir dir1
- rev offset length base linkrev nodeid p1 p2
- 0 0 54 0 1 8b3ffd73f901 000000000000 000000000000
+ rev offset length delta linkrev nodeid p1 p2
+ 0 0 54 -1 1 8b3ffd73f901 000000000000 000000000000
1 54 68 0 2 b66d046c644f 8b3ffd73f901 000000000000
- 2 122 12 0 4 b87265673c8a b66d046c644f 000000000000
- 3 134 95 0 5 aa5d3adcec72 b66d046c644f 000000000000
- 4 229 81 0 6 e29b066b91ad b66d046c644f 000000000000
- 5 310 107 5 7 a120ce2b83f5 e29b066b91ad aa5d3adcec72
+ 2 122 12 1 4 b87265673c8a b66d046c644f 000000000000
+ 3 134 55 1 5 aa5d3adcec72 b66d046c644f 000000000000
+ 4 189 55 1 6 e29b066b91ad b66d046c644f 000000000000
+ 5 244 55 4 7 a120ce2b83f5 e29b066b91ad aa5d3adcec72
Merge keeping directory from parent 1 does not create revlog entry. (Note that
dir1's manifest does change, but only because dir1/a's filelog changes.)
@@ -250,13 +254,13 @@
Parent of tree root manifest should be flat manifest, and two for merge
$ hg debugindex -m
- rev offset length base linkrev nodeid p1 p2
- 0 0 80 0 0 40536115ed9e 000000000000 000000000000
+ rev offset length delta linkrev nodeid p1 p2
+ 0 0 80 -1 0 40536115ed9e 000000000000 000000000000
1 80 83 0 1 f3376063c255 40536115ed9e 000000000000
- 2 163 103 0 2 5d9b9da231a2 40536115ed9e 000000000000
- 3 266 83 0 3 d17d663cbd8a 5d9b9da231a2 f3376063c255
- 4 349 132 4 4 c05a51345f86 f3376063c255 000000000000
- 5 481 110 4 5 82594b1f557d 5d9b9da231a2 f3376063c255
+ 2 163 89 0 2 5d9b9da231a2 40536115ed9e 000000000000
+ 3 252 83 2 3 d17d663cbd8a 5d9b9da231a2 f3376063c255
+ 4 335 124 1 4 c05a51345f86 f3376063c255 000000000000
+ 5 459 124 2 5 82594b1f557d 5d9b9da231a2 f3376063c255
Status across flat/tree boundary should work
@@ -270,16 +274,16 @@
Turning off treemanifest config has no effect
$ hg debugindex .hg/store/meta/dir1/00manifest.i
- rev offset length base linkrev nodeid p1 p2
- 0 0 125 0 4 63c9c0557d24 000000000000 000000000000
- 1 125 109 0 5 23d12a1f6e0e 000000000000 000000000000
+ rev offset length delta linkrev nodeid p1 p2
+ 0 0 125 -1 4 63c9c0557d24 000000000000 000000000000
+ 1 125 131 -1 5 23d12a1f6e0e 000000000000 000000000000
$ echo 2 > dir1/a
$ hg --config experimental.treemanifest=False ci -qm 'modify dir1/a'
$ hg debugindex .hg/store/meta/dir1/00manifest.i
- rev offset length base linkrev nodeid p1 p2
- 0 0 125 0 4 63c9c0557d24 000000000000 000000000000
- 1 125 109 0 5 23d12a1f6e0e 000000000000 000000000000
- 2 234 55 0 6 3cb2d87b4250 23d12a1f6e0e 000000000000
+ rev offset length delta linkrev nodeid p1 p2
+ 0 0 125 -1 4 63c9c0557d24 000000000000 000000000000
+ 1 125 131 -1 5 23d12a1f6e0e 000000000000 000000000000
+ 2 256 55 1 6 3cb2d87b4250 23d12a1f6e0e 000000000000
Create deeper repo with tree manifests.