Mercurial > hg
changeset 27010:f4fec0940278
merge with stable
author | Matt Mackall <mpm@selenic.com> |
---|---|
date | Wed, 18 Nov 2015 20:59:17 -0600 |
parents | f5faef7e9119 (diff) 6979fe2a6d75 (current diff) |
children | 53c668dc6b16 |
files | hgext/rebase.py mercurial/commands.py tests/test-resolve.t |
diffstat | 110 files changed, 1604 insertions(+), 762 deletions(-) [+] |
line wrap: on
line diff
--- 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.