Mercurial > hg
changeset 22173:d3702a822241
merge with stable
author | Matt Mackall <mpm@selenic.com> |
---|---|
date | Thu, 14 Aug 2014 16:25:47 -0500 |
parents | 3ddfb9b3fdc6 (diff) 989c16c1b050 (current diff) |
children | 0cc2db64c335 |
files | hgext/largefiles/overrides.py mercurial/cmdutil.py tests/test-run-tests.t |
diffstat | 186 files changed, 3426 insertions(+), 1404 deletions(-) [+] |
line wrap: on
line diff
--- a/contrib/check-code.py Thu Aug 14 16:18:45 2014 -0500 +++ b/contrib/check-code.py Thu Aug 14 16:25:47 2014 -0500 @@ -94,7 +94,7 @@ (r'sed.*-i', "don't use 'sed -i', use a temporary file"), (r'\becho\b.*\\n', "don't use 'echo \\n', use printf"), (r'echo -n', "don't use 'echo -n', use printf"), - (r'(^| )wc[^|]*$\n(?!.*\(re\))', "filter wc output"), + (r'(^| )\bwc\b[^|]*$\n(?!.*\(re\))', "filter wc output"), (r'head -c', "don't use 'head -c', use 'dd'"), (r'tail -n', "don't use the '-n' option to tail, just use '-<num>'"), (r'sha1sum', "don't use sha1sum, use $TESTDIR/md5sum.py"), @@ -179,12 +179,14 @@ ] for i in [0, 1]: - for p, m in testpats[i]: + for tp in testpats[i]: + p = tp[0] + m = tp[1] if p.startswith(r'^'): p = r"^ [$>] (%s)" % p[1:] else: p = r"^ [$>] .*(%s)" % p - utestpats[i].append((p, m)) + utestpats[i].append((p, m) + tp[2:]) utestfilters = [ (r"<<(\S+)((.|\n)*?\n > \1)", rephere),
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/contrib/check-commit Thu Aug 14 16:25:47 2014 -0500 @@ -0,0 +1,55 @@ +#!/usr/bin/env python +# +# Copyright 2014 Matt Mackall <mpm@selenic.com> +# +# A tool/hook to run basic sanity checks on commits/patches for +# submission to Mercurial. Install by adding the following to your +# .hg/hgrc: +# +# [hooks] +# pretxncommit = contrib/check-commit +# +# The hook can be temporarily bypassed with: +# +# $ BYPASS= hg commit +# +# See also: http://mercurial.selenic.com/wiki/ContributingChanges + +import re, sys, os + +errors = [ + (r"[(]bc[)]", "(BC) needs to be uppercase"), + (r"[(]issue \d\d\d", "no space allowed between issue and number"), + (r"[(]bug", "use (issueDDDD) instead of bug"), + (r"^# User [^@\n]+$", "username is not an email address"), + (r"^# .*\n(?!merge with )[^#]\S+[^:] ", + "summary line doesn't start with 'topic: '"), + (r"^# .*\n[A-Z][a-z]\S+", "don't capitalize summary lines"), + (r"^# .*\n.*\.\s+$", "don't add trailing period on summary line"), + (r"^# .*\n.{78,}", "summary line too long"), + (r"^\+\n \n", "adds double empty line"), + (r"\+\s+def [a-z]+_[a-z]", "adds a function with foo_bar naming"), +] + +node = os.environ.get("HG_NODE") + +if node: + commit = os.popen("hg export %s" % node).read() +else: + commit = sys.stdin.read() + +exitcode = 0 +for exp, msg in errors: + m = re.search(exp, commit, re.MULTILINE) + if m: + pos = 0 + for n, l in enumerate(commit.splitlines(True)): + pos += len(l) + if pos >= m.end(): + print "%d: %s" % (n, msg) + print " %s" % l[:-1] + if "BYPASS" not in os.environ: + exitcode = 1 + break + +sys.exit(exitcode)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/contrib/hg-test-mode.el Thu Aug 14 16:25:47 2014 -0500 @@ -0,0 +1,56 @@ +;; hg-test-mode.el - Major mode for editing Mercurial tests +;; +;; Copyright 2014 Matt Mackall <mpm@selenic.com> +;; "I have no idea what I'm doing" +;; +;; This software may be used and distributed according to the terms of the +;; GNU General Public License version 2 or any later version. +;; +;; To enable, add something like the following to your .emacs: +;; +;; (if (file-exists-p "~/hg/contrib/hg-test-mode.el") +;; (load "~/hg/contrib/hg-test-mode.el")) + +(defvar hg-test-mode-hook nil) + +(defvar hg-test-mode-map + (let ((map (make-keymap))) + (define-key map "\C-j" 'newline-and-indent) + map) + "Keymap for hg test major mode") + +(add-to-list 'auto-mode-alist '("\\.t\\'" . hg-test-mode)) + +(defconst hg-test-font-lock-keywords-1 + (list + '("^ \\(\\$\\|>>>\\) " 1 font-lock-builtin-face) + '("^ \\(>\\|\\.\\.\\.\\) " 1 font-lock-constant-face) + '("^ \\([[][0-9]+[]]\\)$" 1 font-lock-warning-face) + '("^ \\(.*?\\)\\(\\( [(][-a-z]+[)]\\)*\\)$" 1 font-lock-string-face) + '("\\$?\\(HG\\|TEST\\)\\w+=?" . font-lock-variable-name-face) + '("^ \\(.*?\\)\\(\\( [(][-a-z]+[)]\\)+\\)$" 2 font-lock-type-face) + '("^#.*" . font-lock-preprocessor-face) + '("^\\([^ ].*\\)$" 1 font-lock-comment-face) + ) + "Minimal highlighting expressions for hg-test mode") + +(defvar hg-test-font-lock-keywords hg-test-font-lock-keywords-1 + "Default highlighting expressions for hg-test mode") + +(defvar hg-test-mode-syntax-table + (let ((st (make-syntax-table))) + (modify-syntax-entry ?\" "w" st) ;; disable standard quoting + st) +"Syntax table for hg-test mode") + +(defun hg-test-mode () + (interactive) + (kill-all-local-variables) + (use-local-map hg-test-mode-map) + (set-syntax-table hg-test-mode-syntax-table) + (set (make-local-variable 'font-lock-defaults) '(hg-test-font-lock-keywords)) + (setq major-mode 'hg-test-mode) + (setq mode-name "hg-test") + (run-hooks 'hg-test-mode-hook)) + +(provide 'hg-test-mode)
--- a/contrib/revsetbenchmarks.py Thu Aug 14 16:18:45 2014 -0500 +++ b/contrib/revsetbenchmarks.py Thu Aug 14 16:25:47 2014 -0500 @@ -19,8 +19,6 @@ # cannot use argparse, python 2.7 only from optparse import OptionParser - - def check_output(*args, **kwargs): kwargs.setdefault('stderr', PIPE) kwargs.setdefault('stdout', PIPE)
--- a/contrib/simplemerge Thu Aug 14 16:18:45 2014 -0500 +++ b/contrib/simplemerge Thu Aug 14 16:25:47 2014 -0500 @@ -11,8 +11,7 @@ ('a', 'text', None, _('treat all files as text')), ('p', 'print', None, _('print results instead of overwriting LOCAL')), - ('', 'no-minimal', None, - _('do not try to minimize conflict regions')), + ('', 'no-minimal', None, _('no effect (DEPRECATED)')), ('h', 'help', None, _('display help and exit')), ('q', 'quiet', None, _('suppress output'))]
--- a/hgext/fetch.py Thu Aug 14 16:18:45 2014 -0500 +++ b/hgext/fetch.py Thu Aug 14 16:25:47 2014 -0500 @@ -143,8 +143,8 @@ ('Automated merge with %s' % util.removeauth(other.url()))) editopt = opts.get('edit') or opts.get('force_editor') - n = repo.commit(message, opts['user'], opts['date'], - editor=cmdutil.getcommiteditor(edit=editopt)) + editor = cmdutil.getcommiteditor(edit=editopt, editform='fetch') + n = repo.commit(message, opts['user'], opts['date'], editor=editor) ui.status(_('new changeset %d:%s merges remote changes ' 'with local\n') % (repo.changelog.rev(n), short(n)))
--- a/hgext/gpg.py Thu Aug 14 16:18:45 2014 -0500 +++ b/hgext/gpg.py Thu Aug 14 16:25:47 2014 -0500 @@ -277,8 +277,9 @@ % hgnode.short(n) for n in nodes]) try: + editor = cmdutil.getcommiteditor(editform='gpg.sign', **opts) repo.commit(message, opts['user'], opts['date'], match=msigs, - editor=cmdutil.getcommiteditor(**opts)) + editor=editor) except ValueError, inst: raise util.Abort(str(inst))
--- a/hgext/histedit.py Thu Aug 14 16:18:45 2014 -0500 +++ b/hgext/histedit.py Thu Aug 14 16:25:47 2014 -0500 @@ -36,6 +36,7 @@ # p, pick = use commit # e, edit = use commit, but stop for amending # f, fold = use commit, but combine it with the one above + # r, roll = like fold, but discard this commit's description # d, drop = remove commit from history # m, mess = edit message without changing commit content # @@ -57,6 +58,7 @@ # p, pick = use commit # e, edit = use commit, but stop for amending # f, fold = use commit, but combine it with the one above + # r, roll = like fold, but discard this commit's description # d, drop = remove commit from history # m, mess = edit message without changing commit content # @@ -179,6 +181,7 @@ # p, pick = use commit # e, edit = use commit, but stop for amending # f, fold = use commit, but combine it with the one above +# r, roll = like fold, but discard this commit's description # d, drop = remove commit from history # m, mess = edit message without changing commit content # @@ -208,8 +211,6 @@ repo.ui.restoreconfig(phasebackup) return commitfunc - - def applychanges(ui, repo, ctx, opts): """Merge changeset from ctx (only) in the current working directory""" wcpar = repo.dirstate.parents()[0] @@ -293,6 +294,9 @@ extra = commitopts.get('extra') parents = (first.p1().node(), first.p2().node()) + editor = None + if not commitopts.get('rollup'): + editor = cmdutil.getcommiteditor(edit=True, editform='histedit.fold') new = context.memctx(repo, parents=parents, text=message, @@ -301,7 +305,7 @@ user=user, date=date, extra=extra, - editor=cmdutil.getcommiteditor(edit=True)) + editor=editor) return repo.commitctx(new) def pick(ui, repo, ctx, ha, opts): @@ -334,6 +338,11 @@ _('Make changes as needed, you may commit or record as needed now.\n' 'When you are finished, run hg histedit --continue to resume.')) +def rollup(ui, repo, ctx, ha, opts): + rollupopts = opts.copy() + rollupopts['rollup'] = True + return fold(ui, repo, ctx, ha, rollupopts) + def fold(ui, repo, ctx, ha, opts): oldctx = repo[ha] hg.update(repo, ctx.node()) @@ -356,10 +365,13 @@ commitopts = opts.copy() commitopts['user'] = ctx.user() # commit message - newmessage = '\n***\n'.join( - [ctx.description()] + - [repo[r].description() for r in internalchanges] + - [oldctx.description()]) + '\n' + if opts.get('rollup'): + newmessage = ctx.description() + else: + newmessage = '\n***\n'.join( + [ctx.description()] + + [repo[r].description() for r in internalchanges] + + [oldctx.description()]) + '\n' commitopts['message'] = newmessage # date commitopts['date'] = max(ctx.date(), oldctx.date()) @@ -400,9 +412,10 @@ _('Fix up the change and run hg histedit --continue')) message = oldctx.description() commit = commitfuncfor(repo, oldctx) + editor = cmdutil.getcommiteditor(edit=True, editform='histedit.mess') new = commit(text=message, user=oldctx.user(), date=oldctx.date(), extra=oldctx.extra(), - editor=cmdutil.getcommiteditor(edit=True)) + editor=editor) newctx = repo[new] if oldctx.node() != newctx.node(): return newctx, [(oldctx.node(), (new,))] @@ -439,6 +452,8 @@ 'edit': edit, 'f': fold, 'fold': fold, + 'r': rollup, + 'roll': rollup, 'd': drop, 'drop': drop, 'm': message, @@ -674,12 +689,14 @@ m, a, r, d = repo.status()[:4] if m or a or r or d: # prepare the message for the commit to comes - if action in ('f', 'fold'): + if action in ('f', 'fold', 'r', 'roll'): message = 'fold-temp-revision %s' % currentnode else: message = ctx.description() editopt = action in ('e', 'edit', 'm', 'mess') - editor = cmdutil.getcommiteditor(edit=editopt) + canonaction = {'e': 'edit', 'm': 'mess', 'p': 'pick'} + editform = 'histedit.%s' % canonaction.get(action, action) + editor = cmdutil.getcommiteditor(edit=editopt, editform=editform) commit = commitfuncfor(repo, ctx) new = commit(text=message, user=ctx.user(), date=ctx.date(), extra=ctx.extra(), @@ -695,15 +712,19 @@ # to parent. replacements.append((ctx.node(), tuple(newchildren))) - if action in ('f', 'fold'): + if action in ('f', 'fold', 'r', 'roll'): if newchildren: # finalize fold operation if applicable if new is None: new = newchildren[-1] else: newchildren.pop() # remove new from internal changes - parentctx, repl = finishfold(ui, repo, parentctx, ctx, new, opts, - newchildren) + foldopts = opts + if action in ('r', 'roll'): + foldopts = foldopts.copy() + foldopts['rollup'] = True + parentctx, repl = finishfold(ui, repo, parentctx, ctx, new, + foldopts, newchildren) replacements.extend(repl) else: # newchildren is empty if the fold did not result in any commit
--- a/hgext/keyword.py Thu Aug 14 16:18:45 2014 -0500 +++ b/hgext/keyword.py Thu Aug 14 16:25:47 2014 -0500 @@ -1,6 +1,6 @@ # keyword.py - $Keyword$ expansion for Mercurial # -# Copyright 2007-2012 Christian Ebert <blacktrash@gmx.net> +# Copyright 2007-2014 Christian Ebert <blacktrash@gmx.net> # # This software may be used and distributed according to the terms of the # GNU General Public License version 2 or any later version. @@ -87,7 +87,7 @@ from mercurial import scmutil, pathutil from mercurial.hgweb import webcommands from mercurial.i18n import _ -import os, re, shutil, tempfile +import os, re, tempfile cmdtable = {} command = cmdutil.command(cmdtable) @@ -450,7 +450,12 @@ repo.commit(text=msg) ui.status(_('\n\tkeywords expanded\n')) ui.write(repo.wread(fn)) - shutil.rmtree(tmpdir, ignore_errors=True) + for root, dirs, files in os.walk(tmpdir, topdown=False): + for f in files: + util.unlink(os.path.join(root, f)) + for d in dirs: + os.rmdir(os.path.join(root, d)) + os.rmdir(tmpdir) @command('kwexpand', commands.walkopts,
--- a/hgext/largefiles/lfcommands.py Thu Aug 14 16:18:45 2014 -0500 +++ b/hgext/largefiles/lfcommands.py Thu Aug 14 16:25:47 2014 -0500 @@ -510,26 +510,7 @@ updated += update1 - standin = lfutil.standin(lfile) - if standin in repo.dirstate: - stat = repo.dirstate._map[standin] - state, mtime = stat[0], stat[3] - else: - state, mtime = '?', -1 - if state == 'n': - if normallookup or mtime < 0: - # state 'n' doesn't ensure 'clean' in this case - lfdirstate.normallookup(lfile) - else: - lfdirstate.normal(lfile) - elif state == 'm': - lfdirstate.normallookup(lfile) - elif state == 'r': - lfdirstate.remove(lfile) - elif state == 'a': - lfdirstate.add(lfile) - elif state == '?': - lfdirstate.drop(lfile) + lfutil.synclfdirstate(repo, lfdirstate, lfile, normallookup) lfdirstate.write() if printmessage and lfiles:
--- a/hgext/largefiles/lfutil.py Thu Aug 14 16:18:45 2014 -0500 +++ b/hgext/largefiles/lfutil.py Thu Aug 14 16:25:47 2014 -0500 @@ -363,6 +363,28 @@ standins.append((lfile, hash)) return standins +def synclfdirstate(repo, lfdirstate, lfile, normallookup): + lfstandin = standin(lfile) + if lfstandin in repo.dirstate: + stat = repo.dirstate._map[lfstandin] + state, mtime = stat[0], stat[3] + else: + state, mtime = '?', -1 + if state == 'n': + if normallookup or mtime < 0: + # state 'n' doesn't ensure 'clean' in this case + lfdirstate.normallookup(lfile) + else: + lfdirstate.normal(lfile) + elif state == 'm': + lfdirstate.normallookup(lfile) + elif state == 'r': + lfdirstate.remove(lfile) + elif state == 'a': + lfdirstate.add(lfile) + elif state == '?': + lfdirstate.drop(lfile) + def getlfilestoupdate(oldstandins, newstandins): changedstandins = set(oldstandins).symmetric_difference(set(newstandins)) filelist = []
--- a/hgext/largefiles/overrides.py Thu Aug 14 16:18:45 2014 -0500 +++ b/hgext/largefiles/overrides.py Thu Aug 14 16:25:47 2014 -0500 @@ -1157,19 +1157,20 @@ repo.status = oldstatus def overriderollback(orig, ui, repo, **opts): - result = orig(ui, repo, **opts) - merge.update(repo, node=None, branchmerge=False, force=True, - partial=lfutil.isstandin) wlock = repo.wlock() try: + result = orig(ui, repo, **opts) + merge.update(repo, node=None, branchmerge=False, force=True, + partial=lfutil.isstandin) + lfdirstate = lfutil.openlfdirstate(ui, repo) + orphans = set(lfdirstate) lfiles = lfutil.listlfiles(repo) - oldlfiles = lfutil.listlfiles(repo, repo[None].parents()[0].rev()) for file in lfiles: - if file in oldlfiles: - lfdirstate.normallookup(file) - else: - lfdirstate.add(file) + lfutil.synclfdirstate(repo, lfdirstate, file, True) + orphans.discard(file) + for lfile in orphans: + lfdirstate.drop(lfile) lfdirstate.write() finally: wlock.release()
--- a/hgext/largefiles/reposetup.py Thu Aug 14 16:18:45 2014 -0500 +++ b/hgext/largefiles/reposetup.py Thu Aug 14 16:25:47 2014 -0500 @@ -285,6 +285,16 @@ printmessage=False) result = orig(text=text, user=user, date=date, match=match, force=force, editor=editor, extra=extra) + + if result: + lfdirstate = lfutil.openlfdirstate(ui, self) + for f in self[result].files(): + if lfutil.isstandin(f): + lfile = lfutil.splitstandin(f) + lfutil.synclfdirstate(self, lfdirstate, lfile, + False) + lfdirstate.write() + return result # Case 1: user calls commit with no specific files or # include/exclude patterns: refresh and commit all files that
--- a/hgext/mq.py Thu Aug 14 16:18:45 2014 -0500 +++ b/hgext/mq.py Thu Aug 14 16:25:47 2014 -0500 @@ -621,7 +621,7 @@ # apply failed, strip away that rev and merge. hg.clean(repo, head) - strip(self.ui, repo, [n], update=False, backup='strip') + strip(self.ui, repo, [n], update=False, backup=False) ctx = repo[rev] ret = hg.merge(repo, rev) @@ -930,7 +930,12 @@ oldqbase = repo[qfinished[0]] tphase = repo.ui.config('phases', 'new-commit', phases.draft) if oldqbase.phase() > tphase and oldqbase.p1().phase() <= tphase: - phases.advanceboundary(repo, tphase, qfinished) + tr = repo.transaction('qfinish') + try: + phases.advanceboundary(repo, tr, tphase, qfinished) + tr.close() + finally: + tr.release() def delete(self, repo, patches, opts): if not patches and not opts.get('rev'): @@ -1025,6 +1030,7 @@ """ msg = opts.get('msg') edit = opts.get('edit') + editform = opts.get('editform', 'mq.qnew') user = opts.get('user') date = opts.get('date') if date: @@ -1079,7 +1085,7 @@ p.write("# Date %s %s\n\n" % date) defaultmsg = "[mq]: %s" % patchfn - editor = cmdutil.getcommiteditor() + editor = cmdutil.getcommiteditor(editform=editform) if edit: def finishdesc(desc): if desc.rstrip(): @@ -1089,7 +1095,8 @@ # i18n: this message is shown in editor with "HG: " prefix extramsg = _('Leave message empty to use default message.') editor = cmdutil.getcommiteditor(finishdesc=finishdesc, - extramsg=extramsg) + extramsg=extramsg, + editform=editform) commitmsg = msg else: commitmsg = msg or defaultmsg @@ -1456,7 +1463,7 @@ for patch in reversed(self.applied[start:end]): self.ui.status(_("popping %s\n") % patch.name) del self.applied[start:end] - strip(self.ui, repo, [rev], update=False, backup='strip') + strip(self.ui, repo, [rev], update=False, backup=False) for s, state in repo['.'].substate.items(): repo['.'].sub(s).get(state) if self.applied: @@ -1485,6 +1492,7 @@ return 1 msg = opts.get('msg', '').rstrip() edit = opts.get('edit') + editform = opts.get('editform', 'mq.qrefresh') newuser = opts.get('user') newdate = opts.get('date') if newdate: @@ -1645,7 +1653,7 @@ repo.setparents(*cparents) self.applied.pop() self.applieddirty = True - strip(self.ui, repo, [top], update=False, backup='strip') + strip(self.ui, repo, [top], update=False, backup=False) except: # re-raises repo.dirstate.invalidate() raise @@ -1654,7 +1662,7 @@ # might be nice to attempt to roll back strip after this defaultmsg = "[mq]: %s" % patchfn - editor = cmdutil.getcommiteditor() + editor = cmdutil.getcommiteditor(editform=editform) if edit: def finishdesc(desc): if desc.rstrip(): @@ -1664,7 +1672,8 @@ # i18n: this message is shown in editor with "HG: " prefix extramsg = _('Leave message empty to use default message.') editor = cmdutil.getcommiteditor(finishdesc=finishdesc, - extramsg=extramsg) + extramsg=extramsg, + editform=editform) message = msg or "\n".join(ph.message) elif not msg: if not ph.message: @@ -1842,7 +1851,7 @@ update = True else: update = False - strip(self.ui, repo, [rev], update=update, backup='strip') + strip(self.ui, repo, [rev], update=update, backup=False) if qpp: self.ui.warn(_("saved queue repository parents: %s %s\n") % (short(qpp[0]), short(qpp[1]))) @@ -1966,41 +1975,49 @@ lastparent = None diffopts = self.diffopts({'git': git}) - for r in rev: - if not repo[r].mutable(): - raise util.Abort(_('revision %d is not mutable') % r, - hint=_('see "hg help phases" for details')) - p1, p2 = repo.changelog.parentrevs(r) - n = repo.changelog.node(r) - if p2 != nullrev: - raise util.Abort(_('cannot import merge revision %d') % r) - if lastparent and lastparent != r: - raise util.Abort(_('revision %d is not the parent of %d') - % (r, lastparent)) - lastparent = p1 - - if not patchname: - patchname = normname('%d.diff' % r) - checkseries(patchname) - self.checkpatchname(patchname, force) - self.fullseries.insert(0, patchname) - - patchf = self.opener(patchname, "w") - cmdutil.export(repo, [n], fp=patchf, opts=diffopts) - patchf.close() - - se = statusentry(n, patchname) - self.applied.insert(0, se) - - self.added.append(patchname) - imported.append(patchname) - patchname = None - if rev and repo.ui.configbool('mq', 'secret', False): - # if we added anything with --rev, move the secret root - phases.retractboundary(repo, phases.secret, [n]) - self.parseseries() - self.applieddirty = True - self.seriesdirty = True + tr = repo.transaction('qimport') + try: + for r in rev: + if not repo[r].mutable(): + raise util.Abort(_('revision %d is not mutable') % r, + hint=_('see "hg help phases" ' + 'for details')) + p1, p2 = repo.changelog.parentrevs(r) + n = repo.changelog.node(r) + if p2 != nullrev: + raise util.Abort(_('cannot import merge revision %d') + % r) + if lastparent and lastparent != r: + raise util.Abort(_('revision %d is not the parent of ' + '%d') + % (r, lastparent)) + lastparent = p1 + + if not patchname: + patchname = normname('%d.diff' % r) + checkseries(patchname) + self.checkpatchname(patchname, force) + self.fullseries.insert(0, patchname) + + patchf = self.opener(patchname, "w") + cmdutil.export(repo, [n], fp=patchf, opts=diffopts) + patchf.close() + + se = statusentry(n, patchname) + self.applied.insert(0, se) + + self.added.append(patchname) + imported.append(patchname) + patchname = None + if rev and repo.ui.configbool('mq', 'secret', False): + # if we added anything with --rev, move the secret root + phases.retractboundary(repo, tr, phases.secret, [n]) + self.parseseries() + self.applieddirty = True + self.seriesdirty = True + tr.close() + finally: + tr.release() for i, filename in enumerate(files): if existing: @@ -2585,7 +2602,8 @@ diffopts = q.patchopts(q.diffopts(), *patches) wlock = repo.wlock() try: - q.refresh(repo, msg=message, git=diffopts.git, edit=opts.get('edit')) + q.refresh(repo, msg=message, git=diffopts.git, edit=opts.get('edit'), + editform='mq.qfold') q.delete(repo, patches, opts) q.savedirty() finally:
--- a/hgext/purge.py Thu Aug 14 16:18:45 2014 -0500 +++ b/hgext/purge.py Thu Aug 14 16:25:47 2014 -0500 @@ -26,7 +26,7 @@ from mercurial import util, commands, cmdutil, scmutil from mercurial.i18n import _ -import os, stat +import os cmdtable = {} command = cmdutil.command(cmdtable) @@ -95,17 +95,6 @@ else: ui.write('%s%s' % (name, eol)) - def removefile(path): - try: - os.remove(path) - except OSError: - # read-only files cannot be unlinked under Windows - s = os.stat(path) - if (s.st_mode & stat.S_IWRITE) != 0: - raise - os.chmod(path, stat.S_IMODE(s.st_mode) | stat.S_IWRITE) - os.remove(path) - directories = [] match = scmutil.match(repo[None], dirs, opts) match.explicitdir = match.traversedir = directories.append @@ -115,7 +104,7 @@ for f in sorted(status[4] + status[5]): if act: ui.note(_('removing file %s\n') % f) - remove(removefile, f) + remove(util.unlink, f) if removedirs: for f in sorted(directories, reverse=True):
--- a/hgext/rebase.py Thu Aug 14 16:18:45 2014 -0500 +++ b/hgext/rebase.py Thu Aug 14 16:25:47 2014 -0500 @@ -138,7 +138,7 @@ skipped = set() targetancestors = set() - editor = cmdutil.getcommiteditor(**opts) + editor = cmdutil.getcommiteditor(editform='rebase.normal', **opts) lock = wlock = None try: @@ -383,7 +383,8 @@ for rebased in state: if rebased not in skipped and state[rebased] > nullmerge: commitmsg += '\n* %s' % repo[rebased].description() - editor = cmdutil.getcommiteditor(edit=True) + editform = 'rebase.collapse' + editor = cmdutil.getcommiteditor(edit=True, editform=editform) newrev = concludenode(repo, rev, p1, external, commitmsg=commitmsg, extrafn=extrafn, editor=editor) for oldrev in state.iterkeys(): @@ -468,15 +469,18 @@ extra = {'rebase_source': ctx.hex()} if extrafn: extrafn(ctx, extra) - # Commit might fail if unresolved files exist - newrev = repo.commit(text=commitmsg, user=ctx.user(), - date=ctx.date(), extra=extra, editor=editor) + + backup = repo.ui.backupconfig('phases', 'new-commit') + try: + targetphase = max(ctx.phase(), phases.draft) + repo.ui.setconfig('phases', 'new-commit', targetphase, 'rebase') + # Commit might fail if unresolved files exist + newrev = repo.commit(text=commitmsg, user=ctx.user(), + date=ctx.date(), extra=extra, editor=editor) + finally: + repo.ui.restoreconfig(backup) + repo.dirstate.setbranch(repo[newrev].branch()) - targetphase = max(ctx.phase(), phases.draft) - # retractboundary doesn't overwrite upper phase inherited from parent - newnode = repo[newrev].node() - if newnode: - phases.retractboundary(repo, targetphase, [newnode]) return newrev except util.Abort: # Invalidate the previous setparents
--- a/hgext/shelve.py Thu Aug 14 16:18:45 2014 -0500 +++ b/hgext/shelve.py Thu Aug 14 16:25:47 2014 -0500 @@ -73,7 +73,8 @@ try: gen = exchange.readbundle(self.repo.ui, fp, self.fname, self.vfs) changegroup.addchangegroup(self.repo, gen, 'unshelve', - 'bundle:' + self.vfs.join(self.fname)) + 'bundle:' + self.vfs.join(self.fname), + targetphase=phases.secret) finally: fp.close() @@ -177,10 +178,14 @@ hasmq = util.safehasattr(repo, 'mq') if hasmq: saved, repo.mq.checkapplied = repo.mq.checkapplied, False + backup = repo.ui.backupconfig('phases', 'new-commit') try: + repo.ui. setconfig('phases', 'new-commit', phases.secret) + editor = cmdutil.getcommiteditor(editform='shelve.shelve', **opts) return repo.commit(message, user, opts.get('date'), match, - editor=cmdutil.getcommiteditor(**opts)) + editor=editor) finally: + repo.ui.restoreconfig(backup) if hasmq: repo.mq.checkapplied = saved @@ -234,8 +239,6 @@ ui.status(_("nothing changed\n")) return 1 - phases.retractboundary(repo, phases.secret, [node]) - fp = shelvedfile(repo, name, 'files').opener('wb') fp.write('\0'.join(shelvedfiles)) @@ -388,7 +391,7 @@ mergefiles(ui, repo, state.wctx, state.pendingctx) - repair.strip(ui, repo, state.stripnodes, backup='none', topic='shelve') + repair.strip(ui, repo, state.stripnodes, backup=False, topic='shelve') shelvedstate.clear(repo) ui.warn(_("unshelve of '%s' aborted\n") % state.name) finally: @@ -457,7 +460,7 @@ mergefiles(ui, repo, state.wctx, shelvectx) state.stripnodes.append(shelvectx.node()) - repair.strip(ui, repo, state.stripnodes, backup='none', topic='shelve') + repair.strip(ui, repo, state.stripnodes, backup=False, topic='shelve') shelvedstate.clear(repo) unshelvecleanup(ui, repo, state.name, opts) ui.status(_("unshelve of '%s' complete\n") % state.name) @@ -558,10 +561,13 @@ if hasmq: saved, repo.mq.checkapplied = repo.mq.checkapplied, False + backup = repo.ui.backupconfig('phases', 'new-commit') try: + repo.ui. setconfig('phases', 'new-commit', phases.secret) return repo.commit(message, 'shelve@localhost', opts.get('date'), match) finally: + repo.ui.restoreconfig(backup) if hasmq: repo.mq.checkapplied = saved @@ -574,8 +580,6 @@ ui.quiet = True shelvedfile(repo, basename, 'hg').applybundle() - nodes = [ctx.node() for ctx in repo.set('%d:', oldtiprev)] - phases.retractboundary(repo, phases.secret, nodes) ui.quiet = oldquiet
--- a/hgext/strip.py Thu Aug 14 16:18:45 2014 -0500 +++ b/hgext/strip.py Thu Aug 14 16:25:47 2014 -0500 @@ -42,7 +42,7 @@ raise util.Abort(_("local changed subrepos found" + excsuffix)) return m, a, r, d -def strip(ui, repo, revs, update=True, backup="all", force=None, bookmark=None): +def strip(ui, repo, revs, update=True, backup=True, force=None, bookmark=None): wlock = lock = None try: wlock = repo.wlock() @@ -114,11 +114,9 @@ Return 0 on success. """ - backup = 'all' - if opts.get('backup'): - backup = 'strip' - elif opts.get('no_backup') or opts.get('nobackup'): - backup = 'none' + backup = True + if opts.get('no_backup') or opts.get('nobackup'): + backup = False cl = repo.changelog revs = list(revs) + opts.get('rev')
--- a/hgext/transplant.py Thu Aug 14 16:18:45 2014 -0500 +++ b/hgext/transplant.py Thu Aug 14 16:25:47 2014 -0500 @@ -86,7 +86,7 @@ self.opener = scmutil.opener(self.path) self.transplants = transplants(self.path, 'transplants', opener=self.opener) - self.editor = cmdutil.getcommiteditor(**opts) + self.editor = cmdutil.getcommiteditor(editform='transplant', **opts) def applied(self, repo, node, parent): '''returns True if a node is already an ancestor of parent
--- a/mercurial/branchmap.py Thu Aug 14 16:18:45 2014 -0500 +++ b/mercurial/branchmap.py Thu Aug 14 16:25:47 2014 -0500 @@ -62,8 +62,6 @@ partial = None return partial - - ### Nearest subset relation # Nearest subset of filter X is a filter Y so that: # * Y is included in X,
--- a/mercurial/changegroup.py Thu Aug 14 16:18:45 2014 -0500 +++ b/mercurial/changegroup.py Thu Aug 14 16:25:47 2014 -0500 @@ -569,7 +569,8 @@ return revisions, files -def addchangegroup(repo, source, srctype, url, emptyok=False): +def addchangegroup(repo, source, srctype, url, emptyok=False, + targetphase=phases.draft): """Add the changegroup returned by source.read() to this repo. srctype is a string like 'push', 'pull', or 'unbundle'. url is the URL of the repo where this changegroup is coming from. @@ -699,15 +700,18 @@ # We should not use added here but the list of all change in # the bundle if publishing: - phases.advanceboundary(repo, phases.public, srccontent) + phases.advanceboundary(repo, tr, phases.public, srccontent) else: - phases.advanceboundary(repo, phases.draft, srccontent) - phases.retractboundary(repo, phases.draft, added) + # Those changesets have been pushed from the outside, their + # phases are going to be pushed alongside. Therefor + # `targetphase` is ignored. + phases.advanceboundary(repo, tr, phases.draft, srccontent) + phases.retractboundary(repo, tr, phases.draft, added) elif srctype != 'strip': # publishing only alter behavior during push # # strip should not touch boundary at all - phases.retractboundary(repo, phases.draft, added) + phases.retractboundary(repo, tr, targetphase, added) # make changelog see real files again cl.finalize(trp)
--- a/mercurial/cmdutil.py Thu Aug 14 16:18:45 2014 -0500 +++ b/mercurial/cmdutil.py Thu Aug 14 16:25:47 2014 -0500 @@ -109,7 +109,8 @@ (logfile, inst.strerror)) return message -def getcommiteditor(edit=False, finishdesc=None, extramsg=None, **opts): +def getcommiteditor(edit=False, finishdesc=None, extramsg=None, + editform='', **opts): """get appropriate commit message editor according to '--edit' option 'finishdesc' is a function to be called with edited commit message @@ -122,6 +123,9 @@ 'Leave message empty to abort commit' line. 'HG: ' prefix and EOL is automatically added. + 'editform' is a dot-separated list of names, to distinguish + the purpose of commit text editing. + 'getcommiteditor' returns 'commitforceeditor' regardless of 'edit', if one of 'finishdesc' or 'extramsg' is specified, because they are specific for usage in MQ. @@ -129,7 +133,10 @@ if edit or finishdesc or extramsg: return lambda r, c, s: commitforceeditor(r, c, s, finishdesc=finishdesc, - extramsg=extramsg) + extramsg=extramsg, + editform=editform) + elif editform: + return lambda r, c, s: commiteditor(r, c, s, editform=editform) else: return commiteditor @@ -586,7 +593,7 @@ tmpname, message, user, date, branch, nodeid, p1, p2 = \ patch.extract(ui, hunk) - editor = getcommiteditor(**opts) + editor = getcommiteditor(editform='import.normal', **opts) update = not opts.get('bypass') strip = opts["strip"] sim = float(opts.get('similarity') or 0) @@ -680,12 +687,13 @@ files, eolmode=None) except patch.PatchError, e: raise util.Abort(str(e)) + editor = getcommiteditor(editform='import.bypass') memctx = context.makememctx(repo, (p1.node(), p2.node()), message, opts.get('user') or user, opts.get('date') or date, branch, files, store, - editor=getcommiteditor()) + editor=editor) n = memctx.commit() finally: store.close() @@ -1574,8 +1582,14 @@ if not slowpath: for f in match.files(): if follow and f not in pctx: - raise util.Abort(_('cannot follow file not in parent ' - 'revision: "%s"') % f) + # If the file exists, it may be a directory, so let it + # take the slow path. + if os.path.exists(repo.wjoin(f)): + slowpath = True + continue + else: + raise util.Abort(_('cannot follow file not in parent ' + 'revision: "%s"') % f) filelog = repo.file(f) if not filelog: # A zero count may be a directory or deleted file, so @@ -1599,9 +1613,6 @@ if slowpath: # See walkchangerevs() slow path. # - if follow: - raise util.Abort(_('can only follow copies/renames for explicit ' - 'filenames')) # pats/include/exclude cannot be represented as separate # revset expressions as their filtering logic applies at file # level. For instance "-I a -X a" matches a revision touching @@ -1633,7 +1644,10 @@ filematcher = None if opts.get('patch') or opts.get('stat'): - if follow and not match.always(): + # When following files, track renames via a special matcher. + # If we're forced to take the slowpath it means we're following + # at least one pattern/directory, so don't bother with rename tracking. + if follow and not match.always() and not slowpath: # _makelogfilematcher expects its files argument to be relative to # the repo root, so use match.files(), not pats. filematcher = _makefollowlogfilematcher(repo, match.files(), @@ -2100,9 +2114,10 @@ user = opts.get('user') or old.user() date = opts.get('date') or old.date() - editor = getcommiteditor(**opts) + editform = 'commit.amend' + editor = getcommiteditor(editform=editform, **opts) if not message: - editor = getcommiteditor(edit=True) + editor = getcommiteditor(edit=True, editform=editform) message = old.description() pureextra = extra.copy() @@ -2176,17 +2191,24 @@ lockmod.release(lock, wlock) return newid -def commiteditor(repo, ctx, subs): +def commiteditor(repo, ctx, subs, editform=''): if ctx.description(): return ctx.description() - return commitforceeditor(repo, ctx, subs) + return commitforceeditor(repo, ctx, subs, editform=editform) -def commitforceeditor(repo, ctx, subs, finishdesc=None, extramsg=None): +def commitforceeditor(repo, ctx, subs, finishdesc=None, extramsg=None, + editform=''): if not extramsg: extramsg = _("Leave message empty to abort commit.") - tmpl = repo.ui.config('committemplate', 'changeset', '').strip() - if tmpl: - committext = buildcommittemplate(repo, ctx, subs, extramsg, tmpl) + + forms = [e for e in editform.split('.') if e] + forms.insert(0, 'changeset') + while forms: + tmpl = repo.ui.config('committemplate', '.'.join(forms)) + if tmpl: + committext = buildcommittemplate(repo, ctx, subs, extramsg, tmpl) + break + forms.pop() else: committext = buildcommittext(repo, ctx, subs, extramsg) @@ -2213,6 +2235,10 @@ except SyntaxError, inst: raise util.Abort(inst.args[0]) + for k, v in repo.ui.configitems('committemplate'): + if k != 'changeset': + t.t.cache[k] = v + if not extramsg: extramsg = '' # ensure that extramsg is string @@ -2347,17 +2373,37 @@ # get the list of subrepos that must be reverted targetsubs = sorted(s for s in ctx.substate if m(s)) - # Find status of all file in `names`. (Against working directory parent) + # Find status of all file in `names`. m = scmutil.matchfiles(repo, names) - changes = repo.status(node1=parent, match=m)[:4] - modified, added, removed, deleted = map(set, changes) + + changes = repo.status(node1=node, match=m, clean=True) + modified = set(changes[0]) + added = set(changes[1]) + removed = set(changes[2]) + deleted = set(changes[3]) + + # We need to account for the state of file in the dirstate + # + # Even, when we revert agains something else than parent. this will + # slightly alter the behavior of revert (doing back up or not, delete + # or just forget etc) + if parent == node: + dsmodified = modified + dsadded = added + dsremoved = removed + modified, added, removed = set(), set(), set() + else: + changes = repo.status(node1=parent, match=m) + dsmodified = set(changes[0]) + dsadded = set(changes[1]) + dsremoved = set(changes[2]) # if f is a rename, update `names` to also revert the source cwd = repo.getcwd() - for f in added: + for f in dsadded: src = repo.dirstate.copied(f) if src and src not in names and repo.dirstate[src] == 'r': - removed.add(src) + dsremoved.add(src) names[src] = (repo.pathto(src, cwd), True) ## computation of the action to performs on `names` content. @@ -2367,6 +2413,18 @@ return _('forgetting %s\n') return _('removing %s\n') + # split between files known in target manifest and the others + smf = set(mf) + + missingmodified = dsmodified - smf + dsmodified -= missingmodified + missingadded = dsadded - smf + dsadded -= missingadded + missingremoved = dsremoved - smf + dsremoved -= missingremoved + missingdeleted = deleted - smf + deleted -= missingdeleted + # action to be actually performed by revert # (<list of file>, message>) tuple actions = {'revert': ([], _('reverting %s\n')), @@ -2377,18 +2435,16 @@ disptable = ( # dispatch table: # file state - # action if in target manifest - # action if not in target manifest - # make backup if in target manifest - # make backup if not in target manifest - (modified, (actions['revert'], True), - (actions['remove'], True)), - (added, (actions['revert'], True), - (actions['remove'], False)), - (removed, (actions['undelete'], True), - (None, False)), - (deleted, (actions['revert'], False), - (actions['remove'], False)), + # action + # make backup + (dsmodified, (actions['revert'], True)), + (missingmodified, (actions['remove'], True)), + (dsadded, (actions['revert'], True)), + (missingadded, (actions['remove'], False)), + (dsremoved, (actions['undelete'], True)), + (missingremoved, (None, False)), + (deleted, (actions['revert'], False)), + (missingdeleted, (actions['remove'], False)), ) for abs, (rel, exact) in sorted(names.items()): @@ -2414,14 +2470,15 @@ # search the entry in the dispatch table. # if the file is in any of this sets, it was touched in the working # directory parent and we are sure it needs to be reverted. - for table, hit, miss in disptable: + for table, (action, backup) in disptable: if abs not in table: continue - # file has changed in dirstate - if mfentry: - handle(*hit) - elif miss[0] is not None: - handle(*miss) + if action is None: + if exact: + ui.warn(_('no changes needed to %s\n') % rel) + + else: + handle(action, backup) break else: # Not touched in current dirstate.
--- a/mercurial/commands.py Thu Aug 14 16:18:45 2014 -0500 +++ b/mercurial/commands.py Thu Aug 14 16:25:47 2014 -0500 @@ -505,11 +505,12 @@ def commitfunc(ui, repo, message, match, opts): - e = cmdutil.getcommiteditor(**opts) + editform = 'backout' + e = cmdutil.getcommiteditor(editform=editform, **opts) if not message: # we don't translate commit messages message = "Backed out changeset %s" % short(node) - e = cmdutil.getcommiteditor(edit=True) + e = cmdutil.getcommiteditor(edit=True, editform=editform) return repo.commit(message, opts.get('user'), opts.get('date'), match, editor=e) newnode = cmdutil.commit(ui, repo, commitfunc, [], opts) @@ -1385,9 +1386,6 @@ # Let --subrepos on the command line override config setting. ui.setconfig('ui', 'commitsubrepos', True, 'commit') - # Save this for restoring it later - oldcommitphase = ui.config('phases', 'new-commit') - cmdutil.checkunfinished(repo, commit=True) branch = repo[None].branch() @@ -1441,21 +1439,24 @@ newmarks.write() else: def commitfunc(ui, repo, message, match, opts): + backup = ui.backupconfig('phases', 'new-commit') + baseui = repo.baseui + basebackup = baseui.backupconfig('phases', 'new-commit') try: if opts.get('secret'): ui.setconfig('phases', 'new-commit', 'secret', 'commit') # Propagate to subrepos - repo.baseui.setconfig('phases', 'new-commit', 'secret', - 'commit') - + baseui.setconfig('phases', 'new-commit', 'secret', 'commit') + + editform = 'commit.normal' + editor = cmdutil.getcommiteditor(editform=editform, **opts) return repo.commit(message, opts.get('user'), opts.get('date'), match, - editor=cmdutil.getcommiteditor(**opts), + editor=editor, extra=extra) finally: - ui.setconfig('phases', 'new-commit', oldcommitphase, 'commit') - repo.baseui.setconfig('phases', 'new-commit', oldcommitphase, - 'commit') + ui.restoreconfig(backup) + repo.baseui.restoreconfig(basebackup) node = cmdutil.commit(ui, repo, commitfunc, pats, opts) @@ -3054,6 +3055,7 @@ ('c', 'continue', False, _('resume interrupted graft')), ('e', 'edit', False, _('invoke editor on commit messages')), ('', 'log', None, _('append graft info to log message')), + ('f', 'force', False, _('force graft')), ('D', 'currentdate', False, _('record the current date as commit date')), ('U', 'currentuser', False, @@ -3077,6 +3079,10 @@ (grafted from CHANGESETHASH) + If --force is specified, revisions will be grafted even if they + are already ancestors of or have been grafted to the destination. + This is useful when the revisions have since been backed out. + If a graft merge results in conflicts, the graft process is interrupted so that the current merge can be manually resolved. Once all conflicts are addressed, the graft process can be @@ -3084,7 +3090,8 @@ .. note:: - The -c/--continue option does not reapply earlier options. + The -c/--continue option does not reapply earlier options, except + for --force. .. container:: verbose @@ -3121,7 +3128,7 @@ if not opts.get('date') and opts.get('currentdate'): opts['date'] = "%d %d" % util.makedate() - editor = cmdutil.getcommiteditor(**opts) + editor = cmdutil.getcommiteditor(editform='graft', **opts) cont = False if opts['continue']: @@ -3150,52 +3157,59 @@ if not revs: return -1 - # check for ancestors of dest branch - crev = repo['.'].rev() - ancestors = repo.changelog.ancestors([crev], inclusive=True) - # Cannot use x.remove(y) on smart set, this has to be a list. - # XXX make this lazy in the future - revs = list(revs) - # don't mutate while iterating, create a copy - for rev in list(revs): - if rev in ancestors: - ui.warn(_('skipping ancestor revision %s\n') % rev) - # XXX remove on list is slow - revs.remove(rev) - if not revs: - return -1 - - # analyze revs for earlier grafts - ids = {} - for ctx in repo.set("%ld", revs): - ids[ctx.hex()] = ctx.rev() - n = ctx.extra().get('source') - if n: - ids[n] = ctx.rev() - - # check ancestors for earlier grafts - ui.debug('scanning for duplicate grafts\n') - - for rev in repo.changelog.findmissingrevs(revs, [crev]): - ctx = repo[rev] - n = ctx.extra().get('source') - if n in ids: - r = repo[n].rev() - if r in revs: - ui.warn(_('skipping revision %s (already grafted to %s)\n') - % (r, rev)) + # Don't check in the --continue case, in effect retaining --force across + # --continues. That's because without --force, any revisions we decided to + # skip would have been filtered out here, so they wouldn't have made their + # way to the graftstate. With --force, any revisions we would have otherwise + # skipped would not have been filtered out, and if they hadn't been applied + # already, they'd have been in the graftstate. + if not (cont or opts.get('force')): + # check for ancestors of dest branch + crev = repo['.'].rev() + ancestors = repo.changelog.ancestors([crev], inclusive=True) + # Cannot use x.remove(y) on smart set, this has to be a list. + # XXX make this lazy in the future + revs = list(revs) + # don't mutate while iterating, create a copy + for rev in list(revs): + if rev in ancestors: + ui.warn(_('skipping ancestor revision %s\n') % rev) + # XXX remove on list is slow + revs.remove(rev) + if not revs: + return -1 + + # analyze revs for earlier grafts + ids = {} + for ctx in repo.set("%ld", revs): + ids[ctx.hex()] = ctx.rev() + n = ctx.extra().get('source') + if n: + ids[n] = ctx.rev() + + # check ancestors for earlier grafts + ui.debug('scanning for duplicate grafts\n') + + for rev in repo.changelog.findmissingrevs(revs, [crev]): + ctx = repo[rev] + n = ctx.extra().get('source') + if n in ids: + r = repo[n].rev() + if r in revs: + ui.warn(_('skipping revision %s (already grafted to %s)\n') + % (r, rev)) + revs.remove(r) + elif ids[n] in revs: + ui.warn(_('skipping already grafted revision %s ' + '(%s also has origin %d)\n') % (ids[n], rev, r)) + revs.remove(ids[n]) + elif ctx.hex() in ids: + r = ids[ctx.hex()] + ui.warn(_('skipping already grafted revision %s ' + '(was grafted from %d)\n') % (r, rev)) revs.remove(r) - elif ids[n] in revs: - ui.warn(_('skipping already grafted revision %s ' - '(%s also has origin %d)\n') % (ids[n], rev, r)) - revs.remove(ids[n]) - elif ctx.hex() in ids: - r = ids[ctx.hex()] - ui.warn(_('skipping already grafted revision %s ' - '(was grafted from %d)\n') % (r, rev)) - revs.remove(r) - if not revs: - return -1 + if not revs: + return -1 wlock = repo.wlock() try: @@ -4027,11 +4041,11 @@ rev = scmutil.revsingle(repo, opts.get('rev'), None).node() ret = 1 - m = scmutil.match(repo[rev], pats, opts, default='relglob') + ctx = repo[rev] + m = scmutil.match(ctx, pats, opts, default='relglob') m.bad = lambda x, y: False - for abs in repo[rev].walk(m): - if not rev and abs not in repo.dirstate: - continue + + for abs in ctx.matches(m): if opts.get('fullpath'): ui.write(repo.wjoin(abs), end) else: @@ -4560,17 +4574,22 @@ ctx = repo[r] ui.write('%i: %s\n' % (ctx.rev(), ctx.phasestr())) else: + tr = None lock = repo.lock() try: + tr = repo.transaction("phase") # set phase if not revs: raise util.Abort(_('empty revision set')) nodes = [repo[r].node() for r in revs] olddata = repo._phasecache.getphaserevs(repo)[:] - phases.advanceboundary(repo, targetphase, nodes) + phases.advanceboundary(repo, tr, targetphase, nodes) if opts['force']: - phases.retractboundary(repo, targetphase, nodes) + phases.retractboundary(repo, tr, targetphase, nodes) + tr.close() finally: + if tr is not None: + tr.release() lock.release() # moving revision from public to draft may hide them # We have to check result on an unfiltered repository @@ -5785,7 +5804,11 @@ if date: date = util.parsedate(date) - editor = cmdutil.getcommiteditor(**opts) + if opts.get('remove'): + editform = 'tag.remove' + else: + editform = 'tag.add' + editor = cmdutil.getcommiteditor(editform=editform, **opts) # don't allow tagging the null rev if (not opts.get('remove') and
--- a/mercurial/config.py Thu Aug 14 16:18:45 2014 -0500 +++ b/mercurial/config.py Thu Aug 14 16:25:47 2014 -0500 @@ -76,7 +76,7 @@ # no data before, remove everything section, item = data if section in self._data: - del self._data[section][item] + self._data[section].pop(item, None) self._source.pop((section, item), None) def parse(self, src, data, sections=None, remap=None, include=None):
--- a/mercurial/context.py Thu Aug 14 16:18:45 2014 -0500 +++ b/mercurial/context.py Thu Aug 14 16:25:47 2014 -0500 @@ -276,7 +276,7 @@ def dirs(self): return self._dirs - def dirty(self): + def dirty(self, missing=False, merge=True, branch=True): return False def status(self, other=None, match=None, listignored=False, @@ -598,6 +598,9 @@ continue match.bad(fn, _('no such file in rev %s') % self) + def matches(self, match): + return self.walk(match) + class basefilectx(object): """A filecontext object represents the common logic for its children: filectx: read-only access to a filerevision that is already present @@ -711,6 +714,10 @@ return util.binary(self.data()) except IOError: return False + def isexec(self): + return 'x' in self.flags() + def islink(self): + return 'l' in self.flags() def cmp(self, fctx): """compare with other file context @@ -1144,6 +1151,9 @@ return sorted(self._repo.dirstate.walk(match, sorted(self.substate), True, False)) + def matches(self, match): + return sorted(self._repo.dirstate.matches(match)) + def ancestors(self): for a in self._repo.changelog.ancestors( [p.rev() for p in self._parents]): @@ -1546,6 +1556,14 @@ # invert comparison to reuse the same code path return fctx.cmp(self) + def remove(self, ignoremissing=False): + """wraps unlink for a repo's working directory""" + util.unlinkpath(self._repo.wjoin(self._path), ignoremissing) + + def write(self, data, flags): + """wraps repo.wwrite""" + self._repo.wwrite(self._path, data, flags) + class memctx(committablectx): """Use memctx to perform in-memory commits via localrepo.commitctx(). @@ -1586,6 +1604,20 @@ self._filectxfn = filectxfn self.substate = {} + # if store is not callable, wrap it in a function + if not callable(filectxfn): + def getfilectx(repo, memctx, path): + fctx = filectxfn[path] + # this is weird but apparently we only keep track of one parent + # (why not only store that instead of a tuple?) + copied = fctx.renamed() + if copied: + copied = copied[0] + return memfilectx(repo, path, fctx.data(), + islink=fctx.islink(), isexec=fctx.isexec(), + copied=copied, memctx=memctx) + self._filectxfn = getfilectx + self._extra = extra and extra.copy() or {} if self._extra.get('branch', '') == '': self._extra['branch'] = 'default' @@ -1613,7 +1645,7 @@ for f, fnode in man.iteritems(): p1node = nullid p2node = nullid - p = pctx[f].parents() + p = pctx[f].parents() # if file isn't in pctx, check p2? if len(p) > 0: p1node = p[0].node() if len(p) > 1: @@ -1650,9 +1682,14 @@ return len(self.data()) def flags(self): return self._flags - def isexec(self): - return 'x' in self._flags - def islink(self): - return 'l' in self._flags def renamed(self): return self._copied + + def remove(self, ignoremissing=False): + """wraps unlink for a repo's working directory""" + # need to figure out what to do here + del self._changectx[self._path] + + def write(self, data, flags): + """wraps repo.wwrite""" + self._data = data
--- a/mercurial/dirstate.py Thu Aug 14 16:18:45 2014 -0500 +++ b/mercurial/dirstate.py Thu Aug 14 16:25:47 2014 -0500 @@ -873,3 +873,21 @@ return (lookup, modified, added, removed, deleted, unknown, ignored, clean) + + def matches(self, match): + ''' + return files in the dirstate (in whatever state) filtered by match + ''' + dmap = self._map + if match.always(): + return dmap.keys() + files = match.files() + if match.matchfn == match.exact: + # fast path -- filter the other way around, since typically files is + # much smaller than dmap + return [f for f in files if f in dmap] + if not match.anypats() and util.all(fn in dmap for fn in files): + # fast path -- all the values are known to be files, so just return + # that + return list(files) + return [f for f in dmap if match(f)]
--- a/mercurial/dispatch.py Thu Aug 14 16:18:45 2014 -0500 +++ b/mercurial/dispatch.py Thu Aug 14 16:25:47 2014 -0500 @@ -331,17 +331,40 @@ args = shlex.split(cmd) return args + givenargs +def aliasinterpolate(name, args, cmd): + '''interpolate args into cmd for shell aliases + + This also handles $0, $@ and "$@". + ''' + # util.interpolate can't deal with "$@" (with quotes) because it's only + # built to match prefix + patterns. + replacemap = dict(('$%d' % (i + 1), arg) for i, arg in enumerate(args)) + replacemap['$0'] = name + replacemap['$$'] = '$' + replacemap['$@'] = ' '.join(args) + # Typical Unix shells interpolate "$@" (with quotes) as all the positional + # parameters, separated out into words. Emulate the same behavior here by + # quoting the arguments individually. POSIX shells will then typically + # tokenize each argument into exactly one word. + replacemap['"$@"'] = ' '.join(util.shellquote(arg) for arg in args) + # escape '\$' for regex + regex = '|'.join(replacemap.keys()).replace('$', r'\$') + r = re.compile(regex) + return r.sub(lambda x: replacemap[x.group()], cmd) + class cmdalias(object): def __init__(self, name, definition, cmdtable): self.name = self.cmd = name self.cmdname = '' self.definition = definition + self.fn = None self.args = [] self.opts = [] self.help = '' self.norepo = True self.optionalrepo = False - self.badalias = False + self.badalias = None + self.unknowncmd = False try: aliases, entry = cmdutil.findcmd(self.name, cmdtable) @@ -354,11 +377,7 @@ self.shadows = False if not self.definition: - def fn(ui, *args): - ui.warn(_("no definition for alias '%s'\n") % self.name) - return -1 - self.fn = fn - self.badalias = True + self.badalias = _("no definition for alias '%s'") % self.name return if self.definition.startswith('!'): @@ -376,10 +395,7 @@ % (int(m.groups()[0]), self.name)) return '' cmd = re.sub(r'\$(\d+|\$)', _checkvar, self.definition[1:]) - replace = dict((str(i + 1), arg) for i, arg in enumerate(args)) - replace['0'] = self.name - replace['@'] = ' '.join(args) - cmd = util.interpolate(r'\$', replace, cmd, escape_prefix=True) + cmd = aliasinterpolate(self.name, args, cmd) return util.system(cmd, environ=env, out=ui.fout) self.fn = fn return @@ -387,26 +403,17 @@ try: args = shlex.split(self.definition) except ValueError, inst: - def fn(ui, *args): - ui.warn(_("error in definition for alias '%s': %s\n") - % (self.name, inst)) - return -1 - self.fn = fn - self.badalias = True + self.badalias = (_("error in definition for alias '%s': %s") + % (self.name, inst)) return self.cmdname = cmd = args.pop(0) args = map(util.expandpath, args) for invalidarg in ("--cwd", "-R", "--repository", "--repo", "--config"): if _earlygetopt([invalidarg], args): - def fn(ui, *args): - ui.warn(_("error in definition for alias '%s': %s may only " - "be given on the command line\n") - % (self.name, invalidarg)) - return -1 - - self.fn = fn - self.badalias = True + self.badalias = (_("error in definition for alias '%s': %s may " + "only be given on the command line") + % (self.name, invalidarg)) return try: @@ -427,26 +434,24 @@ self.__doc__ = self.fn.__doc__ except error.UnknownCommand: - def fn(ui, *args): - ui.warn(_("alias '%s' resolves to unknown command '%s'\n") \ - % (self.name, cmd)) + self.badalias = (_("alias '%s' resolves to unknown command '%s'") + % (self.name, cmd)) + self.unknowncmd = True + except error.AmbiguousCommand: + self.badalias = (_("alias '%s' resolves to ambiguous command '%s'") + % (self.name, cmd)) + + def __call__(self, ui, *args, **opts): + if self.badalias: + hint = None + if self.unknowncmd: try: # check if the command is in a disabled extension - commands.help_(ui, cmd, unknowncmd=True) + cmd, ext = extensions.disabledcmd(ui, self.cmdname)[:2] + hint = _("'%s' is provided by '%s' extension") % (cmd, ext) except error.UnknownCommand: pass - return -1 - self.fn = fn - self.badalias = True - except error.AmbiguousCommand: - def fn(ui, *args): - ui.warn(_("alias '%s' resolves to ambiguous command '%s'\n") \ - % (self.name, cmd)) - return -1 - self.fn = fn - self.badalias = True - - def __call__(self, ui, *args, **opts): + raise util.Abort(self.badalias, hint=hint) if self.shadows: ui.debug("alias '%s' shadows command '%s'\n" % (self.name, self.cmdname))
--- a/mercurial/exchange.py Thu Aug 14 16:18:45 2014 -0500 +++ b/mercurial/exchange.py Thu Aug 14 16:25:47 2014 -0500 @@ -77,8 +77,57 @@ self.remoteheads = None # testable as a boolean indicating if any nodes are missing locally. self.incoming = None - # set of all heads common after changeset bundle push - self.commonheads = None + # phases changes that must be pushed along side the changesets + self.outdatedphases = None + # phases changes that must be pushed if changeset push fails + self.fallbackoutdatedphases = None + # outgoing obsmarkers + self.outobsmarkers = set() + + @util.propertycache + def futureheads(self): + """future remote heads if the changeset push succeeds""" + return self.outgoing.missingheads + + @util.propertycache + def fallbackheads(self): + """future remote heads if the changeset push fails""" + if self.revs is None: + # not target to push, all common are relevant + return self.outgoing.commonheads + unfi = self.repo.unfiltered() + # I want cheads = heads(::missingheads and ::commonheads) + # (missingheads is revs with secret changeset filtered out) + # + # This can be expressed as: + # cheads = ( (missingheads and ::commonheads) + # + (commonheads and ::missingheads))" + # ) + # + # while trying to push we already computed the following: + # common = (::commonheads) + # missing = ((commonheads::missingheads) - commonheads) + # + # We can pick: + # * missingheads part of common (::commonheads) + common = set(self.outgoing.common) + nm = self.repo.changelog.nodemap + cheads = [node for node in self.revs if nm[node] in common] + # and + # * commonheads parents on missing + revset = unfi.set('%ln and parents(roots(%ln))', + self.outgoing.commonheads, + self.outgoing.missing) + cheads.extend(c.node() for c in revset) + return cheads + + @property + def commonheads(self): + """set of all common heads after changeset bundle push""" + if self.ret: + return self.futureheads + else: + return self.fallbackheads def push(repo, remote, force=False, revs=None, newbranch=False): '''Push outgoing changesets (limited by revs) from a local @@ -136,7 +185,6 @@ and pushop.remote.capable('bundle2-exp')): _pushbundle2(pushop) _pushchangeset(pushop) - _pushcomputecommonheads(pushop) _pushsyncphase(pushop) _pushobsolete(pushop) finally: @@ -149,8 +197,39 @@ _pushbookmark(pushop) return pushop.ret +# list of steps to perform discovery before push +pushdiscoveryorder = [] + +# Mapping between step name and function +# +# This exists to help extensions wrap steps if necessary +pushdiscoverymapping = {} + +def pushdiscovery(stepname): + """decorator for function performing discovery before push + + The function is added to the step -> function mapping and appended to the + list of steps. Beware that decorated function will be added in order (this + may matter). + + You can only use this decorator for a new step, if you want to wrap a step + from an extension, change the pushdiscovery dictionary directly.""" + def dec(func): + assert stepname not in pushdiscoverymapping + pushdiscoverymapping[stepname] = func + pushdiscoveryorder.append(stepname) + return func + return dec + def _pushdiscovery(pushop): - # discovery + """Run all discovery steps""" + for stepname in pushdiscoveryorder: + step = pushdiscoverymapping[stepname] + step(pushop) + +@pushdiscovery('changeset') +def _pushdiscoverychangeset(pushop): + """discover the changeset that need to be pushed""" unfi = pushop.repo.unfiltered() fci = discovery.findcommonincoming commoninc = fci(unfi, pushop.remote, force=pushop.force) @@ -162,6 +241,45 @@ pushop.remoteheads = remoteheads pushop.incoming = inc +@pushdiscovery('phase') +def _pushdiscoveryphase(pushop): + """discover the phase that needs to be pushed + + (computed for both success and failure case for changesets push)""" + outgoing = pushop.outgoing + unfi = pushop.repo.unfiltered() + remotephases = pushop.remote.listkeys('phases') + publishing = remotephases.get('publishing', False) + ana = phases.analyzeremotephases(pushop.repo, + pushop.fallbackheads, + remotephases) + pheads, droots = ana + extracond = '' + if not publishing: + extracond = ' and public()' + revset = 'heads((%%ln::%%ln) %s)' % extracond + # Get the list of all revs draft on remote by public here. + # XXX Beware that revset break if droots is not strictly + # XXX root we may want to ensure it is but it is costly + fallback = list(unfi.set(revset, droots, pushop.fallbackheads)) + if not outgoing.missing: + future = fallback + else: + # adds changeset we are going to push as draft + # + # should not be necessary for pushblishing server, but because of an + # issue fixed in xxxxx we have to do it anyway. + fdroots = list(unfi.set('roots(%ln + %ln::)', + outgoing.missing, droots)) + fdroots = [f.node() for f in fdroots] + future = list(unfi.set(revset, fdroots, pushop.futureheads)) + pushop.outdatedphases = future + pushop.fallbackoutdatedphases = fallback + +@pushdiscovery('obsmarker') +def _pushdiscoveryobsmarkers(pushop): + pushop.outobsmarkers = pushop.repo.obsstore + def _pushcheckoutgoing(pushop): outgoing = pushop.outgoing unfi = pushop.repo.unfiltered() @@ -201,6 +319,31 @@ newbm) return True +# List of names of steps to perform for an outgoing bundle2, order matters. +b2partsgenorder = [] + +# Mapping between step name and function +# +# This exists to help extensions wrap steps if necessary +b2partsgenmapping = {} + +def b2partsgenerator(stepname): + """decorator for function generating bundle2 part + + The function is added to the step -> function mapping and appended to the + list of steps. Beware that decorated functions will be added in order + (this may matter). + + You can only use this decorator for new steps, if you want to wrap a step + from an extension, attack the b2partsgenmapping dictionary directly.""" + def dec(func): + assert stepname not in b2partsgenmapping + b2partsgenmapping[stepname] = func + b2partsgenorder.append(stepname) + return func + return dec + +@b2partsgenerator('changeset') def _pushb2ctx(pushop, bundler): """handle changegroup push through bundle2 @@ -227,8 +370,37 @@ pushop.ret = cgreplies['changegroup'][0]['return'] return handlereply -# list of function that may decide to add parts to an outgoing bundle2 -bundle2partsgenerators = [_pushb2ctx] +@b2partsgenerator('phase') +def _pushb2phases(pushop, bundler): + """handle phase push through bundle2""" + if 'phases' in pushop.stepsdone: + return + b2caps = bundle2.bundle2caps(pushop.remote) + if not 'b2x:pushkey' in b2caps: + return + pushop.stepsdone.add('phases') + part2node = [] + enc = pushkey.encode + for newremotehead in pushop.outdatedphases: + part = bundler.newpart('b2x:pushkey') + part.addparam('namespace', enc('phases')) + part.addparam('key', enc(newremotehead.hex())) + part.addparam('old', enc(str(phases.draft))) + part.addparam('new', enc(str(phases.public))) + part2node.append((part.id, newremotehead)) + def handlereply(op): + for partid, node in part2node: + partrep = op.records.getreplies(partid) + results = partrep['pushkey'] + assert len(results) <= 1 + msg = None + if not results: + msg = _('server ignored update of %s to public!\n') % node + elif not int(results[0]['return']): + msg = _('updating %s to public failed!\n') % node + if msg is not None: + pushop.ui.warn(msg) + return handlereply def _pushbundle2(pushop): """push data to the remote using bundle2 @@ -240,7 +412,8 @@ capsblob = bundle2.encodecaps(pushop.repo.bundle2caps) bundler.newpart('b2x:replycaps', data=capsblob) replyhandlers = [] - for partgen in bundle2partsgenerators: + for partgenname in b2partsgenorder: + partgen = b2partsgenmapping[partgenname] ret = partgen(pushop, bundler) if callable(ret): replyhandlers.append(ret) @@ -307,43 +480,8 @@ # change pushop.ret = pushop.remote.addchangegroup(cg, 'push', pushop.repo.url()) -def _pushcomputecommonheads(pushop): - unfi = pushop.repo.unfiltered() - if pushop.ret: - # push succeed, synchronize target of the push - cheads = pushop.outgoing.missingheads - elif pushop.revs is None: - # All out push fails. synchronize all common - cheads = pushop.outgoing.commonheads - else: - # I want cheads = heads(::missingheads and ::commonheads) - # (missingheads is revs with secret changeset filtered out) - # - # This can be expressed as: - # cheads = ( (missingheads and ::commonheads) - # + (commonheads and ::missingheads))" - # ) - # - # while trying to push we already computed the following: - # common = (::commonheads) - # missing = ((commonheads::missingheads) - commonheads) - # - # We can pick: - # * missingheads part of common (::commonheads) - common = set(pushop.outgoing.common) - nm = pushop.repo.changelog.nodemap - cheads = [node for node in pushop.revs if nm[node] in common] - # and - # * commonheads parents on missing - revset = unfi.set('%ln and parents(roots(%ln))', - pushop.outgoing.commonheads, - pushop.outgoing.missing) - cheads.extend(c.node() for c in revset) - pushop.commonheads = cheads - def _pushsyncphase(pushop): """synchronise phase information locally and remotely""" - unfi = pushop.repo.unfiltered() cheads = pushop.commonheads # even when we don't push, exchanging phase data is useful remotephases = pushop.remote.listkeys('phases') @@ -376,12 +514,18 @@ _localphasemove(pushop, cheads, phases.draft) ### Apply local phase on remote - # Get the list of all revs draft on remote by public here. - # XXX Beware that revset break if droots is not strictly - # XXX root we may want to ensure it is but it is costly - outdated = unfi.set('heads((%ln::%ln) and public())', - droots, cheads) + if pushop.ret: + if 'phases' in pushop.stepsdone: + # phases already pushed though bundle2 + return + outdated = pushop.outdatedphases + else: + outdated = pushop.fallbackoutdatedphases + pushop.stepsdone.add('phases') + + # filter heads already turned public by the push + outdated = [c for c in outdated if c.node() not in pheads] b2caps = bundle2.bundle2caps(pushop.remote) if 'b2x:pushkey' in b2caps: # server supports bundle2, let's do a batched push through it @@ -431,7 +575,12 @@ def _localphasemove(pushop, nodes, phase=phases.public): """move <nodes> to <phase> in the local source repo""" if pushop.locallocked: - phases.advanceboundary(pushop.repo, phase, nodes) + tr = pushop.repo.transaction('push-phase-sync') + try: + phases.advanceboundary(pushop.repo, tr, phase, nodes) + tr.close() + finally: + tr.release() else: # repo is not locked, do not change any phases! # Informs the user that phases should have been moved when @@ -444,13 +593,16 @@ def _pushobsolete(pushop): """utility function to push obsolete markers to a remote""" + if 'obsmarkers' in pushop.stepsdone: + return pushop.ui.debug('try to push obsolete markers to remote\n') repo = pushop.repo remote = pushop.remote + pushop.stepsdone.add('obsmarkers') if (obsolete._enabled and repo.obsstore and 'obsolete' in remote.listkeys('namespaces')): rslts = [] - remotedata = repo.listkeys('obsolete') + remotedata = obsolete._pushkeyescape(pushop.outobsmarkers) for key in sorted(remotedata, reverse=True): # reverse sort to ensure we end with dump0 data = remotedata[key] @@ -673,14 +825,29 @@ pheads, _dr = phases.analyzeremotephases(pullop.repo, pullop.pulledsubset, remotephases) - phases.advanceboundary(pullop.repo, phases.public, pheads) - phases.advanceboundary(pullop.repo, phases.draft, - pullop.pulledsubset) + dheads = pullop.pulledsubset else: # Remote is old or publishing all common changesets # should be seen as public - phases.advanceboundary(pullop.repo, phases.public, - pullop.pulledsubset) + pheads = pullop.pulledsubset + dheads = [] + unfi = pullop.repo.unfiltered() + phase = unfi._phasecache.phase + rev = unfi.changelog.nodemap.get + public = phases.public + draft = phases.draft + + # exclude changesets already public locally and update the others + pheads = [pn for pn in pheads if phase(unfi, rev(pn)) > public] + if pheads: + tr = pullop.gettransaction() + phases.advanceboundary(pullop.repo, tr, public, pheads) + + # exclude changesets already draft locally and update the others + dheads = [pn for pn in dheads if phase(unfi, rev(pn)) > draft] + if dheads: + tr = pullop.gettransaction() + phases.advanceboundary(pullop.repo, tr, draft, dheads) def _pullobsolete(pullop): """utility function to pull obsolete markers from a remote @@ -726,9 +893,13 @@ The implementation is at a very early stage and will get massive rework when the API of bundle is refined. """ - # build changegroup bundle here. - cg = changegroup.getbundle(repo, source, heads=heads, - common=common, bundlecaps=bundlecaps) + cg = None + if kwargs.get('cg', True): + # build changegroup bundle here. + cg = changegroup.getbundle(repo, source, heads=heads, + common=common, bundlecaps=bundlecaps) + elif 'HG2X' not in bundlecaps: + raise ValueError(_('request for bundle10 must include changegroup')) if bundlecaps is None or 'HG2X' not in bundlecaps: if kwargs: raise ValueError(_('unsupported getbundle arguments: %s')
--- a/mercurial/filemerge.py Thu Aug 14 16:18:45 2014 -0500 +++ b/mercurial/filemerge.py Thu Aug 14 16:25:47 2014 -0500 @@ -178,24 +178,30 @@ ui = repo.ui + validkeep = ['keep', 'keep-merge3'] + # do we attempt to simplemerge first? try: premerge = _toolbool(ui, tool, "premerge", not binary) except error.ConfigError: premerge = _toolstr(ui, tool, "premerge").lower() - valid = 'keep'.split() - if premerge not in valid: - _valid = ', '.join(["'" + v + "'" for v in valid]) + if premerge not in validkeep: + _valid = ', '.join(["'" + v + "'" for v in validkeep]) raise error.ConfigError(_("%s.premerge not valid " "('%s' is neither boolean nor %s)") % (tool, premerge, _valid)) if premerge: + if premerge == 'keep-merge3': + if not labels: + labels = _defaultconflictlabels + if len(labels) < 3: + labels.append('base') r = simplemerge.simplemerge(ui, a, b, c, quiet=True, label=labels) if not r: ui.debug(" premerge successful\n") return 0 - if premerge != 'keep': + if premerge not in validkeep: util.copyfile(back, a) # restore from backup and try again return 1 # continue merging @@ -206,7 +212,8 @@ """ Uses the internal non-interactive simple merge algorithm for merging files. It will fail if there are any conflicts and leave markers in - the partially merged file.""" + the partially merged file. Markers will have two sections, one for each side + of merge.""" tool, toolpath, binary, symlink = toolconf if symlink: repo.ui.warn(_('warning: internal:merge cannot merge symlinks ' @@ -218,10 +225,25 @@ ui = repo.ui - r = simplemerge.simplemerge(ui, a, b, c, label=labels, no_minimal=True) + r = simplemerge.simplemerge(ui, a, b, c, label=labels) return True, r return False, 0 +@internaltool('merge3', True, + _("merging %s incomplete! " + "(edit conflicts, then use 'hg resolve --mark')\n")) +def _imerge3(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels=None): + """ + Uses the internal non-interactive simple merge algorithm for merging + files. It will fail if there are any conflicts and leave markers in + the partially merged file. Marker will have three sections, one from each + side of the merge and one for the base content.""" + if not labels: + labels = _defaultconflictlabels + if len(labels) < 3: + labels.append('base') + return _imerge(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels) + @internaltool('tagmerge', True, _("automatic tag merging of %s failed! " "(use 'hg resolve --tool internal:merge' or another merge " @@ -312,23 +334,27 @@ _defaultconflictlabels = ['local', 'other'] -def _formatlabels(repo, fcd, fco, labels): +def _formatlabels(repo, fcd, fco, fca, labels): """Formats the given labels using the conflict marker template. Returns a list of formatted labels. """ cd = fcd.changectx() co = fco.changectx() + ca = fca.changectx() ui = repo.ui template = ui.config('ui', 'mergemarkertemplate', _defaultconflictmarker) template = templater.parsestring(template, quoted=False) - tmpl = templater.templater(None, cache={ 'conflictmarker' : template }) + tmpl = templater.templater(None, cache={'conflictmarker': template}) + + pad = max(len(l) for l in labels) - pad = max(len(labels[0]), len(labels[1])) - - return [_formatconflictmarker(repo, cd, tmpl, labels[0], pad), - _formatconflictmarker(repo, co, tmpl, labels[1], pad)] + newlabels = [_formatconflictmarker(repo, cd, tmpl, labels[0], pad), + _formatconflictmarker(repo, co, tmpl, labels[1], pad)] + if len(labels) > 2: + newlabels.append(_formatconflictmarker(repo, ca, tmpl, labels[2], pad)) + return newlabels def filemerge(repo, mynode, orig, fcd, fco, fca, labels=None): """perform a 3-way merge in the working directory @@ -388,16 +414,13 @@ ui.debug("my %s other %s ancestor %s\n" % (fcd, fco, fca)) markerstyle = ui.config('ui', 'mergemarkers', 'basic') - if markerstyle == 'basic': - formattedlabels = _defaultconflictlabels - else: - if not labels: - labels = _defaultconflictlabels - - formattedlabels = _formatlabels(repo, fcd, fco, labels) + if not labels: + labels = _defaultconflictlabels + if markerstyle != 'basic': + labels = _formatlabels(repo, fcd, fco, fca, labels) needcheck, r = func(repo, mynode, orig, fcd, fco, fca, toolconf, - (a, b, c, back), labels=formattedlabels) + (a, b, c, back), labels=labels) if not needcheck: if r: if onfailure:
--- a/mercurial/help.py Thu Aug 14 16:18:45 2014 -0500 +++ b/mercurial/help.py Thu Aug 14 16:25:47 2014 -0500 @@ -31,7 +31,7 @@ doc = ''.join(rst) return doc -def optrst(options, verbose): +def optrst(header, options, verbose): data = [] multioccur = False for option in options: @@ -59,10 +59,11 @@ data.append((so, lo, desc)) - rst = minirst.maketable(data, 1) + if multioccur: + header += (_(" ([+] can be repeated)")) - if multioccur: - rst.append(_("\n[+] marked option can be specified multiple times\n")) + rst = ['\n%s:\n\n' % header] + rst.extend(minirst.maketable(data, 1)) return ''.join(rst) @@ -234,11 +235,13 @@ rst = [] # check if it's an invalid alias and display its error if it is - if getattr(entry[0], 'badalias', False): - if not unknowncmd: - ui.pushbuffer() - entry[0](ui) - rst.append(ui.popbuffer()) + if getattr(entry[0], 'badalias', None): + rst.append(entry[0].badalias + '\n') + if entry[0].unknowncmd: + try: + rst.extend(helpextcmd(entry[0].cmdname)) + except error.UnknownCommand: + pass return rst # synopsis @@ -276,31 +279,27 @@ mod = extensions.find(name) doc = gettext(mod.__doc__) or '' if '\n' in doc.strip(): - msg = _('use "hg help -e %s" to show help for ' - 'the %s extension') % (name, name) + msg = _('(use "hg help -e %s" to show help for ' + 'the %s extension)') % (name, name) rst.append('\n%s\n' % msg) except KeyError: pass # options if not ui.quiet and entry[1]: - rst.append('\n%s\n\n' % _("options:")) - rst.append(optrst(entry[1], ui.verbose)) + rst.append(optrst(_("options"), entry[1], ui.verbose)) if ui.verbose: - rst.append('\n%s\n\n' % _("global options:")) - rst.append(optrst(commands.globalopts, ui.verbose)) + rst.append(optrst(_("global options"), + commands.globalopts, ui.verbose)) if not ui.verbose: if not full: - rst.append(_('\nuse "hg help %s" to show the full help text\n') + rst.append(_('\n(use "hg %s -h" to show more help)\n') % name) elif not ui.quiet: - omitted = _('use "hg -v help %s" to show more complete' - ' help and the global options') % name - notomitted = _('use "hg -v help %s" to show' - ' the global options') % name - indicateomitted(rst, omitted, notomitted) + rst.append(_('\n(some details hidden, use --verbose ' + 'to show complete help)')) return rst @@ -366,30 +365,25 @@ for t, desc in topics: rst.append(" :%s: %s\n" % (t, desc)) - optlist = [] - if not ui.quiet: - if ui.verbose: - optlist.append((_("global options:"), commands.globalopts)) - if name == 'shortlist': - optlist.append((_('use "hg help" for the full list ' - 'of commands'), ())) + if ui.quiet: + pass + elif ui.verbose: + rst.append('\n%s\n' % optrst(_("global options"), + commands.globalopts, ui.verbose)) + if name == 'shortlist': + rst.append(_('\n(use "hg help" for the full list ' + 'of commands)\n')) + else: + if name == 'shortlist': + rst.append(_('\n(use "hg help" for the full list of commands ' + 'or "hg -v" for details)\n')) + elif name and not full: + rst.append(_('\n(use "hg help %s" to show the full help ' + 'text)\n') % name) else: - if name == 'shortlist': - msg = _('use "hg help" for the full list of commands ' - 'or "hg -v" for details') - elif name and not full: - msg = _('use "hg help %s" to show the full help ' - 'text') % name - else: - msg = _('use "hg -v help%s" to show builtin aliases and ' - 'global options') % (name and " " + name or "") - optlist.append((msg, ())) - - if optlist: - for title, options in optlist: - rst.append('\n%s\n' % title) - if options: - rst.append('\n%s\n' % optrst(options, ui.verbose)) + rst.append(_('\n(use "hg help -v%s" to show built-in aliases ' + 'and global options)\n') + % (name and " " + name or "")) return rst def helptopic(name): @@ -408,8 +402,8 @@ rst += [" %s\n" % l for l in doc().splitlines()] if not ui.verbose: - omitted = (_('use "hg help -v %s" to show more complete help') % - name) + omitted = _('(some details hidden, use --verbose' + ' to show complete help)') indicateomitted(rst, omitted) try: @@ -440,8 +434,8 @@ rst.append('\n') if not ui.verbose: - omitted = (_('use "hg help -v %s" to show more complete help') % - name) + omitted = _('(some details hidden, use --verbose' + ' to show complete help)') indicateomitted(rst, omitted) if mod: @@ -452,8 +446,8 @@ modcmds = set([c.split('|', 1)[0] for c in ct]) rst.extend(helplist(modcmds.__contains__)) else: - rst.append(_('use "hg help extensions" for information on enabling ' - 'extensions\n')) + rst.append(_('(use "hg help extensions" for information on enabling' + ' extensions)\n')) return rst def helpextcmd(name): @@ -464,8 +458,8 @@ rst = listexts(_("'%s' is provided by the following " "extension:") % cmd, {ext: doc}, indent=4) rst.append('\n') - rst.append(_('use "hg help extensions" for information on enabling ' - 'extensions\n')) + rst.append(_('(use "hg help extensions" for information on enabling ' + 'extensions)\n')) return rst
--- a/mercurial/help/config.txt Thu Aug 14 16:18:45 2014 -0500 +++ b/mercurial/help/config.txt Thu Aug 14 16:25:47 2014 -0500 @@ -229,8 +229,9 @@ Positional arguments like ``$1``, ``$2``, etc. in the alias definition expand to the command arguments. Unmatched arguments are removed. ``$0`` expands to the alias name and ``$@`` expands to all -arguments separated by a space. These expansions happen before the -command is passed to the shell. +arguments separated by a space. ``"$@"`` (with quotes) expands to all +arguments quoted individually and separated by a space. These expansions +happen before the command is passed to the shell. Shell aliases are executed in an environment where ``$HG`` expands to the path of the Mercurial that was used to execute the alias. This is @@ -388,6 +389,48 @@ - :hg:`tag` - :hg:`transplant` +Configuring items below instead of ``changeset`` allows showing +customized message only for specific actions, or showing different +messages for each actions. + +- ``changeset.backout`` for :hg:`backout` +- ``changeset.commit.amend`` for :hg:`commit --amend` +- ``changeset.commit.normal`` for :hg:`commit` without ``--amend`` +- ``changeset.fetch`` for :hg:`fetch` (impling merge commit) +- ``changeset.gpg.sign`` for :hg:`sign` +- ``changeset.graft`` for :hg:`graft` +- ``changeset.histedit.edit`` for ``edit`` of :hg:`histedit` +- ``changeset.histedit.fold`` for ``fold`` of :hg:`histedit` +- ``changeset.histedit.mess`` for ``mess`` of :hg:`histedit` +- ``changeset.histedit.pick`` for ``pick`` of :hg:`histedit` +- ``changeset.import.bypass`` for :hg:`import --bypass` +- ``changeset.import.normal`` for :hg:`import` without ``--bypass`` +- ``changeset.mq.qnew`` for :hg:`qnew` +- ``changeset.mq.qfold`` for :hg:`qfold` +- ``changeset.mq.qrefresh`` for :hg:`qrefresh` +- ``changeset.rebase.collapse`` for :hg:`rebase --collapse` +- ``changeset.rebase.normal`` for :hg:`rebase` without ``--collapse`` +- ``changeset.shelve.shelve`` for :hg:`shelve` +- ``changeset.tag.add`` for :hg:`tag` without ``--remove`` +- ``changeset.tag.remove`` for :hg:`tag --remove` +- ``changeset.transplant`` for :hg:`transplant` + +These dot-separated lists of names are treated as hierarchical ones. +For example, ``changeset.tag.remove`` customizes the commit message +only for :hg:`tag --remove`, but ``changeset.tag`` customizes the +commit message for :hg:`tag` regardless of ``--remove`` option. + +In this section, items other than ``changeset`` can be referred from +others. For example, the configuration to list committed files up +below can be referred as ``{listupfiles}``:: + + [committemplate] + listupfiles = {file_adds % + "HG: added {file}\n" }{file_mods % + "HG: changed {file}\n" }{file_dels % + "HG: removed {file}\n" }{if(files, "", + "HG: no files changed\n")} + ``decode/encode`` ----------------- @@ -912,8 +955,10 @@ ``premerge`` Attempt to run internal non-interactive 3-way merge tool before - launching external tool. Options are ``true``, ``false``, or ``keep`` - to leave markers in the file if the premerge fails. + launching external tool. Options are ``true``, ``false``, ``keep`` or + ``keep-merge3``. The ``keep`` option will leave markers in the file if the + premerge fails. The ``keep-merge3`` will do the same but include information + about the base of the merge in the marker (see internal:merge3). Default: True ``binary``
--- a/mercurial/i18n.py Thu Aug 14 16:18:45 2014 -0500 +++ b/mercurial/i18n.py Thu Aug 14 16:25:47 2014 -0500 @@ -6,7 +6,7 @@ # GNU General Public License version 2 or any later version. import encoding -import gettext, sys, os +import gettext, sys, os, locale # modelled after templater.templatepath: if getattr(sys, 'frozen', None) is not None: @@ -20,7 +20,25 @@ if os.path.isdir(localedir): break -t = gettext.translation('hg', localedir, fallback=True) +_languages = None +if (os.name == 'nt' + and 'LANGUAGE' not in os.environ + and 'LC_ALL' not in os.environ + and 'LC_MESSAGES' not in os.environ + and 'LANG' not in os.environ): + # Try to detect UI language by "User Interface Language Management" API + # if no locale variables are set. Note that locale.getdefaultlocale() + # uses GetLocaleInfo(), which may be different from UI language. + # (See http://msdn.microsoft.com/en-us/library/dd374098(v=VS.85).aspx ) + try: + import ctypes + langid = ctypes.windll.kernel32.GetUserDefaultUILanguage() + _languages = [locale.windows_locale[langid]] + except (ImportError, AttributeError, KeyError): + # ctypes not found or unknown langid + pass + +t = gettext.translation('hg', localedir, _languages, fallback=True) def gettext(message): """Translate message.
--- a/mercurial/localrepo.py Thu Aug 14 16:18:45 2014 -0500 +++ b/mercurial/localrepo.py Thu Aug 14 16:25:47 2014 -0500 @@ -182,7 +182,9 @@ bundle2caps = {'HG2X': (), 'b2x:listkeys': (), - 'b2x:pushkey': ()} + 'b2x:pushkey': (), + 'b2x:changegroup': (), + } # a list of (ui, featureset) functions. # only functions defined in module of enabled extensions are invoked @@ -1087,8 +1089,6 @@ return l def unlock(): - if hasunfilteredcache(self, '_phasecache'): - self._phasecache.write() for k, ce in self._filecache.items(): if k == 'dirstate' or k not in self.__dict__: continue @@ -1440,7 +1440,7 @@ # be compliant anyway # # if minimal phase was 0 we don't need to retract anything - phases.retractboundary(self, targetphase, [n]) + phases.retractboundary(self, tr, targetphase, [n]) tr.close() branchmap.updatecache(self.filtered('served')) return n
--- a/mercurial/phases.py Thu Aug 14 16:18:45 2014 -0500 +++ b/mercurial/phases.py Thu Aug 14 16:25:47 2014 -0500 @@ -196,19 +196,24 @@ return f = self.opener('phaseroots', 'w', atomictemp=True) try: - for phase, roots in enumerate(self.phaseroots): - for h in roots: - f.write('%i %s\n' % (phase, hex(h))) + self._write(f) finally: f.close() + + def _write(self, fp): + for phase, roots in enumerate(self.phaseroots): + for h in roots: + fp.write('%i %s\n' % (phase, hex(h))) self.dirty = False - def _updateroots(self, phase, newroots): + def _updateroots(self, phase, newroots, tr): self.phaseroots[phase] = newroots self._phaserevs = None self.dirty = True - def advanceboundary(self, repo, targetphase, nodes): + tr.addfilegenerator('phase', ('phaseroots',), self._write) + + def advanceboundary(self, repo, tr, targetphase, nodes): # Be careful to preserve shallow-copied values: do not update # phaseroots values, replace them. @@ -224,15 +229,15 @@ roots = set(ctx.node() for ctx in repo.set( 'roots((%ln::) - (%ln::%ln))', olds, olds, nodes)) if olds != roots: - self._updateroots(phase, roots) + self._updateroots(phase, roots, tr) # some roots may need to be declared for lower phases delroots.extend(olds - roots) # declare deleted root in the target phase if targetphase != 0: - self.retractboundary(repo, targetphase, delroots) + self.retractboundary(repo, tr, targetphase, delroots) repo.invalidatevolatilesets() - def retractboundary(self, repo, targetphase, nodes): + def retractboundary(self, repo, tr, targetphase, nodes): # Be careful to preserve shallow-copied values: do not update # phaseroots values, replace them. @@ -247,7 +252,7 @@ currentroots.update(newroots) ctxs = repo.set('roots(%ln::)', currentroots) currentroots.intersection_update(ctx.node() for ctx in ctxs) - self._updateroots(targetphase, currentroots) + self._updateroots(targetphase, currentroots, tr) repo.invalidatevolatilesets() def filterunknown(self, repo): @@ -278,7 +283,7 @@ # (see branchmap one) self._phaserevs = None -def advanceboundary(repo, targetphase, nodes): +def advanceboundary(repo, tr, targetphase, nodes): """Add nodes to a phase changing other nodes phases if necessary. This function move boundary *forward* this means that all nodes @@ -286,10 +291,10 @@ Simplify boundary to contains phase roots only.""" phcache = repo._phasecache.copy() - phcache.advanceboundary(repo, targetphase, nodes) + phcache.advanceboundary(repo, tr, targetphase, nodes) repo._phasecache.replace(phcache) -def retractboundary(repo, targetphase, nodes): +def retractboundary(repo, tr, targetphase, nodes): """Set nodes back to a phase changing other nodes phases if necessary. @@ -298,7 +303,7 @@ Simplify boundary to contains phase roots only.""" phcache = repo._phasecache.copy() - phcache.retractboundary(repo, targetphase, nodes) + phcache.retractboundary(repo, tr, targetphase, nodes) repo._phasecache.replace(phcache) def listphases(repo): @@ -331,13 +336,16 @@ def pushphase(repo, nhex, oldphasestr, newphasestr): """List phases root for serialization over pushkey""" repo = repo.unfiltered() + tr = None lock = repo.lock() try: currentphase = repo[nhex].phase() newphase = abs(int(newphasestr)) # let's avoid negative index surprise oldphase = abs(int(oldphasestr)) # let's avoid negative index surprise if currentphase == oldphase and newphase < oldphase: - advanceboundary(repo, newphase, [bin(nhex)]) + tr = repo.transaction('pushkey-phase') + advanceboundary(repo, tr, newphase, [bin(nhex)]) + tr.close() return 1 elif currentphase == newphase: # raced, but got correct result @@ -345,6 +353,8 @@ else: return 0 finally: + if tr: + tr.release() lock.release() def analyzeremotephases(repo, subset, roots):
--- a/mercurial/repair.py Thu Aug 14 16:18:45 2014 -0500 +++ b/mercurial/repair.py Thu Aug 14 16:25:47 2014 -0500 @@ -47,7 +47,13 @@ return s -def strip(ui, repo, nodelist, backup="all", topic='backup'): +def strip(ui, repo, nodelist, backup=True, topic='backup'): + + # Simple way to maintain backwards compatibility for this + # argument. + if backup in ['none', 'strip']: + backup = False + repo = repo.unfiltered() repo.destroying() @@ -58,8 +64,6 @@ striplist = [cl.rev(node) for node in nodelist] striprev = min(striplist) - keeppartialbundle = backup == 'strip' - # Some revisions with rev > striprev may not be descendants of striprev. # We have to find these revisions and put them in a bundle, so that # we can restore them after the truncations. @@ -109,7 +113,7 @@ # create a changegroup for all the branches we need to keep backupfile = None vfs = repo.vfs - if backup == "all": + if backup: backupfile = _bundle(repo, stripbases, cl.heads(), node, topic) repo.ui.status(_("saved backup bundle to %s\n") % vfs.join(backupfile)) @@ -118,7 +122,7 @@ if saveheads or savebases: # do not compress partial bundle if we remove it from disk later chgrpfile = _bundle(repo, savebases, saveheads, node, 'temp', - compress=keeppartialbundle) + compress=False) mfst = repo.manifest @@ -156,8 +160,6 @@ if not repo.ui.verbose: repo.ui.popbuffer() f.close() - if not keeppartialbundle: - vfs.unlink(chgrpfile) # remove undo files for undovfs, undofile in repo.undofiles(): @@ -179,5 +181,9 @@ ui.warn(_("strip failed, partial bundle stored in '%s'\n") % vfs.join(chgrpfile)) raise + else: + if saveheads or savebases: + # Remove partial backup only if there were no exceptions + vfs.unlink(chgrpfile) repo.destroyed()
--- a/mercurial/repoview.py Thu Aug 14 16:18:45 2014 -0500 +++ b/mercurial/repoview.py Thu Aug 14 16:25:47 2014 -0500 @@ -7,11 +7,14 @@ # GNU General Public License version 2 or any later version. import copy +import error +import hashlib import phases import util import obsolete +import struct import tags as tagsmod - +from mercurial.i18n import _ def hideablerevs(repo): """Revisions candidates to be hidden @@ -19,13 +22,14 @@ This is a standalone function to help extensions to wrap it.""" return obsolete.getrevs(repo, 'obsolete') -def _gethiddenblockers(repo): - """Get revisions that will block hidden changesets from being filtered +def _getstaticblockers(repo): + """Cacheable revisions blocking hidden changesets from being filtered. + Additional non-cached hidden blockers are computed in _getdynamicblockers. This is a standalone function to help extensions to wrap it.""" assert not repo.changelog.filteredrevs hideable = hideablerevs(repo) - blockers = [] + blockers = set() if hideable: # We use cl to avoid recursive lookup from repo[xxx] cl = repo.changelog @@ -33,29 +37,123 @@ revs = cl.revs(start=firsthideable) tofilter = repo.revs( '(%ld) and children(%ld)', list(revs), list(hideable)) - blockers = [r for r in tofilter if r not in hideable] - for par in repo[None].parents(): - blockers.append(par.rev()) - for bm in repo._bookmarks.values(): - blockers.append(cl.rev(bm)) - tags = {} - tagsmod.readlocaltags(repo.ui, repo, tags, {}) - if tags: - rev, nodemap = cl.rev, cl.nodemap - blockers.extend(rev(t[0]) for t in tags.values() if t[0] in nodemap) + blockers.update([r for r in tofilter if r not in hideable]) + return blockers + +def _getdynamicblockers(repo): + """Non-cacheable revisions blocking hidden changesets from being filtered. + + Get revisions that will block hidden changesets and are likely to change, + but unlikely to create hidden blockers. They won't be cached, so be careful + with adding additional computation.""" + + cl = repo.changelog + blockers = set() + blockers.update([par.rev() for par in repo[None].parents()]) + blockers.update([cl.rev(bm) for bm in repo._bookmarks.values()]) + + tags = {} + tagsmod.readlocaltags(repo.ui, repo, tags, {}) + if tags: + rev, nodemap = cl.rev, cl.nodemap + blockers.update(rev(t[0]) for t in tags.values() if t[0] in nodemap) return blockers +cacheversion = 1 +cachefile = 'cache/hidden' + +def cachehash(repo, hideable): + """return sha1 hash of repository data to identify a valid cache. + + We calculate a sha1 of repo heads and the content of the obsstore and write + it to the cache. Upon reading we can easily validate by checking the hash + against the stored one and discard the cache in case the hashes don't match. + """ + h = hashlib.sha1() + h.update(''.join(repo.heads())) + h.update(str(hash(frozenset(hideable)))) + return h.digest() + +def trywritehiddencache(repo, hideable, hidden): + """write cache of hidden changesets to disk + + Will not write the cache if a wlock cannot be obtained lazily. + The cache consists of a head of 22byte: + 2 byte version number of the cache + 20 byte sha1 to validate the cache + n*4 byte hidden revs + """ + wlock = fh = None + try: + wlock = repo.wlock(wait=False) + # write cache to file + newhash = cachehash(repo, hideable) + sortedset = sorted(hidden) + data = struct.pack('>%iI' % len(sortedset), *sortedset) + fh = repo.vfs.open(cachefile, 'w+b', atomictemp=True) + fh.write(struct.pack(">H", cacheversion)) + fh.write(newhash) + fh.write(data) + except (IOError, OSError): + repo.ui.debug('error writing hidden changesets cache') + except error.LockHeld: + repo.ui.debug('cannot obtain lock to write hidden changesets cache') + finally: + if fh: + fh.close() + if wlock: + wlock.release() + +def tryreadcache(repo, hideable): + """read a cache if the cache exists and is valid, otherwise returns None.""" + hidden = fh = None + try: + if repo.vfs.exists(cachefile): + fh = repo.vfs.open(cachefile, 'rb') + version, = struct.unpack(">H", fh.read(2)) + oldhash = fh.read(20) + newhash = cachehash(repo, hideable) + if (cacheversion, oldhash) == (version, newhash): + # cache is valid, so we can start reading the hidden revs + data = fh.read() + count = len(data) / 4 + hidden = frozenset(struct.unpack('>%iI' % count, data)) + return hidden + finally: + if fh: + fh.close() + def computehidden(repo): """compute the set of hidden revision to filter During most operation hidden should be filtered.""" assert not repo.changelog.filteredrevs + + hidden = frozenset() hideable = hideablerevs(repo) if hideable: cl = repo.changelog - blocked = cl.ancestors(_gethiddenblockers(repo), inclusive=True) - return frozenset(r for r in hideable if r not in blocked) - return frozenset() + hidden = tryreadcache(repo, hideable) + if hidden is None: + blocked = cl.ancestors(_getstaticblockers(repo), inclusive=True) + hidden = frozenset(r for r in hideable if r not in blocked) + trywritehiddencache(repo, hideable, hidden) + elif repo.ui.configbool('experimental', 'verifyhiddencache', True): + blocked = cl.ancestors(_getstaticblockers(repo), inclusive=True) + computed = frozenset(r for r in hideable if r not in blocked) + if computed != hidden: + trywritehiddencache(repo, hideable, computed) + repo.ui.warn(_('Cache inconsistency detected. Please ' + + 'open an issue on http://bz.selenic.com.\n')) + hidden = computed + + # check if we have wd parents, bookmarks or tags pointing to hidden + # changesets and remove those. + dynamic = hidden & _getdynamicblockers(repo) + if dynamic: + blocked = cl.ancestors(dynamic, inclusive=True) + hidden = frozenset(r for r in hidden if r not in blocked) + return hidden def computeunserved(repo): """compute the set of revision that should be filtered when used a server
--- a/mercurial/simplemerge.py Thu Aug 14 16:18:45 2014 -0500 +++ b/mercurial/simplemerge.py Thu Aug 14 16:25:47 2014 -0500 @@ -82,8 +82,7 @@ start_marker='<<<<<<<', mid_marker='=======', end_marker='>>>>>>>', - base_marker=None, - reprocess=False): + base_marker=None): """Return merge in cvs-like form. """ self.conflicts = False @@ -93,8 +92,6 @@ newline = '\r\n' elif self.a[0].endswith('\r'): newline = '\r' - if base_marker and reprocess: - raise CantReprocessAndShowBase if name_a: start_marker = start_marker + ' ' + name_a if name_b: @@ -102,8 +99,6 @@ if name_base and base_marker: base_marker = base_marker + ' ' + name_base merge_regions = self.merge_regions() - if reprocess is True: - merge_regions = self.reprocess_merge_regions(merge_regions) for t in merge_regions: what = t[0] if what == 'unchanged': @@ -131,33 +126,6 @@ else: raise ValueError(what) - def merge_annotated(self): - """Return merge with conflicts, showing origin of lines. - - Most useful for debugging merge. - """ - for t in self.merge_regions(): - what = t[0] - if what == 'unchanged': - for i in range(t[1], t[2]): - yield 'u | ' + self.base[i] - elif what == 'a' or what == 'same': - for i in range(t[1], t[2]): - yield what[0] + ' | ' + self.a[i] - elif what == 'b': - for i in range(t[1], t[2]): - yield 'b | ' + self.b[i] - elif what == 'conflict': - yield '<<<<\n' - for i in range(t[3], t[4]): - yield 'A | ' + self.a[i] - yield '----\n' - for i in range(t[5], t[6]): - yield 'B | ' + self.b[i] - yield '>>>>\n' - else: - raise ValueError(what) - def merge_groups(self): """Yield sequence of line groups. Each one is a tuple: @@ -278,42 +246,6 @@ ia = aend ib = bend - def reprocess_merge_regions(self, merge_regions): - """Where there are conflict regions, remove the agreed lines. - - Lines where both A and B have made the same changes are - eliminated. - """ - for region in merge_regions: - if region[0] != "conflict": - yield region - continue - type, iz, zmatch, ia, amatch, ib, bmatch = region - a_region = self.a[ia:amatch] - b_region = self.b[ib:bmatch] - matches = mdiff.get_matching_blocks(''.join(a_region), - ''.join(b_region)) - next_a = ia - next_b = ib - for region_ia, region_ib, region_len in matches[:-1]: - region_ia += ia - region_ib += ib - reg = self.mismatch_region(next_a, region_ia, next_b, - region_ib) - if reg is not None: - yield reg - yield 'same', region_ia, region_len + region_ia - next_a = region_ia + region_len - next_b = region_ib + region_len - reg = self.mismatch_region(next_a, amatch, next_b, bmatch) - if reg is not None: - yield reg - - def mismatch_region(next_a, region_ia, next_b, region_ib): - if next_a < region_ia or next_b < region_ib: - return 'conflict', None, None, next_a, region_ia, next_b, region_ib - mismatch_region = staticmethod(mismatch_region) - def find_sync_regions(self): """Return a list of sync regions, where both descendants match the base. @@ -415,13 +347,16 @@ name_a = local name_b = other + name_base = None labels = opts.get('label', []) if len(labels) > 0: name_a = labels[0] if len(labels) > 1: name_b = labels[1] if len(labels) > 2: - raise util.Abort(_("can only specify two labels.")) + name_base = labels[2] + if len(labels) > 3: + raise util.Abort(_("can only specify three labels.")) try: localtext = readfile(local) @@ -437,11 +372,12 @@ else: out = sys.stdout - reprocess = not opts.get('no_minimal') - m3 = Merge3Text(basetext, localtext, othertext) - for line in m3.merge_lines(name_a=name_a, name_b=name_b, - reprocess=reprocess): + extrakwargs = {} + if name_base is not None: + extrakwargs['base_marker'] = '|||||||' + extrakwargs['name_base'] = name_base + for line in m3.merge_lines(name_a=name_a, name_b=name_b, **extrakwargs): out.write(line) if not opts.get('print'):
--- a/mercurial/transaction.py Thu Aug 14 16:18:45 2014 -0500 +++ b/mercurial/transaction.py Thu Aug 14 16:25:47 2014 -0500 @@ -96,6 +96,9 @@ opener.chmod(self.journal, createmode & 0666) opener.chmod(self.backupjournal, createmode & 0666) + # hold file generations to be performed on commit + self._filegenerators = {} + def __del__(self): if self.journal: self._abort() @@ -154,7 +157,7 @@ if file in self.map or file in self.backupmap: return - backupfile = "journal.%s" % file + backupfile = "%s.backup.%s" % (self.journal, file) if self.opener.exists(file): filepath = self.opener.join(file) backuppath = self.opener.join(backupfile) @@ -173,6 +176,28 @@ self.backupsfile.flush() @active + def addfilegenerator(self, genid, filenames, genfunc, order=0): + """add a function to generates some files at transaction commit + + The `genfunc` argument is a function capable of generating proper + content of each entry in the `filename` tuple. + + At transaction close time, `genfunc` will be called with one file + object argument per entries in `filenames`. + + The transaction itself is responsible for the backup, creation and + final write of such file. + + The `genid` argument is used to ensure the same set of file is only + generated once. Call to `addfilegenerator` for a `genid` already + present will overwrite the old entry. + + The `order` argument may be used to control the order in which multiple + generator will be executed. + """ + self._filegenerators[genid] = (order, filenames, genfunc) + + @active def find(self, file): if file in self.map: return self.entries[self.map[file]] @@ -213,6 +238,18 @@ @active def close(self): '''commit the transaction''' + # write files registered for generation + for order, filenames, genfunc in sorted(self._filegenerators.values()): + files = [] + try: + for name in filenames: + self.addbackup(name) + files.append(self.opener(name, 'w', atomictemp=True)) + genfunc(*files) + finally: + for f in files: + f.close() + if self.count == 1 and self.onclose is not None: self.onclose()
--- a/mercurial/wireproto.py Thu Aug 14 16:18:45 2014 -0500 +++ b/mercurial/wireproto.py Thu Aug 14 16:25:47 2014 -0500 @@ -203,7 +203,8 @@ gboptsmap = {'heads': 'nodes', 'common': 'nodes', 'bundlecaps': 'csv', - 'listkeys': 'csv'} + 'listkeys': 'csv', + 'cg': 'boolean'} # client side @@ -349,6 +350,8 @@ value = encodelist(value) elif keytype == 'csv': value = ','.join(value) + elif keytype == 'boolean': + value = bool(value) elif keytype != 'plain': raise KeyError('unknown getbundle option type %s' % keytype) @@ -652,6 +655,8 @@ opts[k] = decodelist(v) elif keytype == 'csv': opts[k] = set(v.split(',')) + elif keytype == 'boolean': + opts[k] = '%i' % bool(v) elif keytype != 'plain': raise KeyError('unknown getbundle option type %s' % keytype)
--- a/tests/hghave.py Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/hghave.py Thu Aug 14 16:25:47 2014 -0500 @@ -5,6 +5,17 @@ tempprefix = 'hg-hghave-' +checks = { + "true": (lambda: True, "yak shaving"), + "false": (lambda: False, "nail clipper"), +} + +def check(name, desc): + def decorator(func): + checks[name] = (func, desc) + return func + return decorator + def matchoutput(cmd, regexp, ignorestatus=False): """Return True if cmd executes successfully and its output is matched by the supplied regular expression. @@ -19,9 +30,11 @@ ret = 1 return (ignorestatus or ret is None) and r.search(s) +@check("baz", "GNU Arch baz client") def has_baz(): return matchoutput('baz --version 2>&1', r'baz Bazaar version') +@check("bzr", "Canonical's Bazaar client") def has_bzr(): try: import bzrlib @@ -29,6 +42,7 @@ except ImportError: return False +@check("bzr114", "Canonical's Bazaar client >= 1.14") def has_bzr114(): try: import bzrlib @@ -37,21 +51,26 @@ except ImportError: return False +@check("cvs", "cvs client/server") def has_cvs(): re = r'Concurrent Versions System.*?server' return matchoutput('cvs --version 2>&1', re) and not has_msys() +@check("cvs112", "cvs client/server >= 1.12") def has_cvs112(): re = r'Concurrent Versions System \(CVS\) 1.12.*?server' return matchoutput('cvs --version 2>&1', re) and not has_msys() +@check("darcs", "darcs client") def has_darcs(): return matchoutput('darcs --version', r'2\.[2-9]', True) +@check("mtn", "monotone client (>= 1.0)") def has_mtn(): return matchoutput('mtn --version', r'monotone', True) and not matchoutput( 'mtn --version', r'monotone 0\.', True) +@check("eol-in-paths", "end-of-lines in paths") def has_eol_in_paths(): try: fd, path = tempfile.mkstemp(dir='.', prefix=tempprefix, suffix='\n\r') @@ -61,6 +80,7 @@ except (IOError, OSError): return False +@check("execbit", "executable bit") def has_executablebit(): try: EXECFLAGS = stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH @@ -78,6 +98,7 @@ return False return not (new_file_has_exec or exec_flags_cannot_flip) +@check("icasefs", "case insensitive file system") def has_icasefs(): # Stolen from mercurial.util fd, path = tempfile.mkstemp(dir='.', prefix=tempprefix) @@ -96,6 +117,7 @@ finally: os.remove(path) +@check("fifo", "named pipes") def has_fifo(): if getattr(os, "mkfifo", None) is None: return False @@ -107,9 +129,11 @@ except OSError: return False +@check("killdaemons", 'killdaemons.py support') def has_killdaemons(): return True +@check("cacheable", "cacheable filesystem") def has_cacheable_fs(): from mercurial import util @@ -120,6 +144,7 @@ finally: os.remove(path) +@check("lsprof", "python lsprof module") def has_lsprof(): try: import _lsprof @@ -127,12 +152,15 @@ except ImportError: return False +@check("gettext", "GNU Gettext (msgfmt)") def has_gettext(): return matchoutput('msgfmt --version', 'GNU gettext-tools') +@check("git", "git command line client") def has_git(): return matchoutput('git --version 2>&1', r'^git version') +@check("docutils", "Docutils text processing library") def has_docutils(): try: from docutils.core import publish_cmdline @@ -146,16 +174,20 @@ return (0, 0) return (int(m.group(1)), int(m.group(2))) +@check("svn15", "subversion client and admin tools >= 1.5") def has_svn15(): return getsvnversion() >= (1, 5) +@check("svn13", "subversion client and admin tools >= 1.3") def has_svn13(): return getsvnversion() >= (1, 3) +@check("svn", "subversion client and admin tools") def has_svn(): return matchoutput('svn --version 2>&1', r'^svn, version') and \ matchoutput('svnadmin --version 2>&1', r'^svnadmin, version') +@check("svn-bindings", "subversion python bindings") def has_svn_bindings(): try: import svn.core @@ -166,10 +198,12 @@ except ImportError: return False +@check("p4", "Perforce server and client") def has_p4(): return (matchoutput('p4 -V', r'Rev\. P4/') and matchoutput('p4d -V', r'Rev\. P4D/')) +@check("symlink", "symbolic links") def has_symlink(): if getattr(os, "symlink", None) is None: return False @@ -181,6 +215,7 @@ except (OSError, AttributeError): return False +@check("hardlink", "hardlinks") def has_hardlink(): from mercurial import util fh, fn = tempfile.mkstemp(dir='.', prefix=tempprefix) @@ -196,12 +231,15 @@ finally: os.unlink(fn) +@check("tla", "GNU Arch tla client") def has_tla(): return matchoutput('tla --version 2>&1', r'The GNU Arch Revision') +@check("gpg", "gpg client") def has_gpg(): return matchoutput('gpg --version 2>&1', r'GnuPG') +@check("unix-permissions", "unix-style permissions") def has_unix_permissions(): d = tempfile.mkdtemp(dir='.', prefix=tempprefix) try: @@ -218,14 +256,17 @@ finally: os.rmdir(d) +@check("root", "root permissions") def has_root(): return getattr(os, 'geteuid', None) and os.geteuid() == 0 +@check("pyflakes", "Pyflakes python linter") def has_pyflakes(): return matchoutput("sh -c \"echo 'import re' 2>&1 | pyflakes\"", r"<stdin>:1: 're' imported but unused", True) +@check("pygments", "Pygments source highlighting library") def has_pygments(): try: import pygments @@ -233,14 +274,17 @@ except ImportError: return False +@check("python243", "python >= 2.4.3") def has_python243(): return sys.version_info >= (2, 4, 3) +@check("outer-repo", "outer repo") def has_outer_repo(): # failing for other reasons than 'no repo' imply that there is a repo return not matchoutput('hg root 2>&1', r'abort: no repository found', True) +@check("ssl", "python >= 2.6 ssl module and python OpenSSL") def has_ssl(): try: import ssl @@ -250,19 +294,24 @@ except ImportError: return False +@check("windows", "Windows") def has_windows(): return os.name == 'nt' +@check("system-sh", "system() uses sh") def has_system_sh(): return os.name != 'nt' +@check("serve", "platform and python can manage 'hg serve -d'") def has_serve(): return os.name != 'nt' # gross approximation +@check("test-repo", "running tests from repository") def has_test_repo(): t = os.environ["TESTDIR"] return os.path.isdir(os.path.join(t, "..", ".hg")) +@check("tic", "terminfo compiler and curses module") def has_tic(): try: import curses @@ -271,63 +320,20 @@ except ImportError: return False +@check("msys", "Windows with MSYS") def has_msys(): return os.getenv('MSYSTEM') +@check("aix", "AIX") def has_aix(): return sys.platform.startswith("aix") +@check("absimport", "absolute_import in __future__") def has_absimport(): import __future__ from mercurial import util return util.safehasattr(__future__, "absolute_import") +@check("py3k", "running with Python 3.x") def has_py3k(): return 3 == sys.version_info[0] - -checks = { - "true": (lambda: True, "yak shaving"), - "false": (lambda: False, "nail clipper"), - "baz": (has_baz, "GNU Arch baz client"), - "bzr": (has_bzr, "Canonical's Bazaar client"), - "bzr114": (has_bzr114, "Canonical's Bazaar client >= 1.14"), - "cacheable": (has_cacheable_fs, "cacheable filesystem"), - "cvs": (has_cvs, "cvs client/server"), - "cvs112": (has_cvs112, "cvs client/server >= 1.12"), - "darcs": (has_darcs, "darcs client"), - "docutils": (has_docutils, "Docutils text processing library"), - "eol-in-paths": (has_eol_in_paths, "end-of-lines in paths"), - "execbit": (has_executablebit, "executable bit"), - "fifo": (has_fifo, "named pipes"), - "gettext": (has_gettext, "GNU Gettext (msgfmt)"), - "git": (has_git, "git command line client"), - "gpg": (has_gpg, "gpg client"), - "hardlink": (has_hardlink, "hardlinks"), - "icasefs": (has_icasefs, "case insensitive file system"), - "killdaemons": (has_killdaemons, 'killdaemons.py support'), - "lsprof": (has_lsprof, "python lsprof module"), - "mtn": (has_mtn, "monotone client (>= 1.0)"), - "outer-repo": (has_outer_repo, "outer repo"), - "p4": (has_p4, "Perforce server and client"), - "pyflakes": (has_pyflakes, "Pyflakes python linter"), - "pygments": (has_pygments, "Pygments source highlighting library"), - "python243": (has_python243, "python >= 2.4.3"), - "root": (has_root, "root permissions"), - "serve": (has_serve, "platform and python can manage 'hg serve -d'"), - "ssl": (has_ssl, "python >= 2.6 ssl module and python OpenSSL"), - "svn": (has_svn, "subversion client and admin tools"), - "svn13": (has_svn13, "subversion client and admin tools >= 1.3"), - "svn15": (has_svn15, "subversion client and admin tools >= 1.5"), - "svn-bindings": (has_svn_bindings, "subversion python bindings"), - "symlink": (has_symlink, "symbolic links"), - "system-sh": (has_system_sh, "system() uses sh"), - "test-repo": (has_test_repo, "running tests from repository"), - "tic": (has_tic, "terminfo compiler and curses module"), - "tla": (has_tla, "GNU Arch tla client"), - "unix-permissions": (has_unix_permissions, "unix-style permissions"), - "windows": (has_windows, "Windows"), - "msys": (has_msys, "Windows with MSYS"), - "aix": (has_aix, "AIX"), - "absimport": (has_absimport, "absolute_import in __future__"), - "py3k": (has_py3k, "running with Python 3.x"), -}
--- a/tests/run-tests.py Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/run-tests.py Thu Aug 14 16:25:47 2014 -0500 @@ -57,6 +57,7 @@ import threading import killdaemons as killmod import Queue as queue +from xml.dom import minidom import unittest processlock = threading.Lock() @@ -190,6 +191,8 @@ " (implies --keep-tmpdir)") parser.add_option("-v", "--verbose", action="store_true", help="output verbose messages") + parser.add_option("--xunit", type="string", + help="record xunit results at specified path") parser.add_option("--view", type="string", help="external diff viewer") parser.add_option("--with-hg", type="string", @@ -304,6 +307,20 @@ return log(*msg) +# Bytes that break XML even in a CDATA block: control characters 0-31 +# sans \t, \n and \r +CDATA_EVIL = re.compile(r"[\000-\010\013\014\016-\037]") + +def cdatasafe(data): + """Make a string safe to include in a CDATA block. + + Certain control characters are illegal in a CDATA block, and + there's no way to include a ]]> in a CDATA either. This function + replaces illegal bytes with ? and adds a space between the ]] so + that it won't break the CDATA block. + """ + return CDATA_EVIL.sub('?', data).replace(']]>', '] ]>') + def log(*msg): """Log something to stdout. @@ -460,8 +477,15 @@ raise except SkipTest, e: result.addSkip(self, str(e)) + # The base class will have already counted this as a + # test we "ran", but we want to exclude skipped tests + # from those we count towards those run. + result.testsRun -= 1 except IgnoreTest, e: result.addIgnore(self, str(e)) + # As with skips, ignores also should be excluded from + # the number of tests executed. + result.testsRun -= 1 except WarnTest, e: result.addWarn(self, str(e)) except self.failureException, e: @@ -786,7 +810,15 @@ for n, l in enumerate(lines): if not l.endswith('\n'): l += '\n' - if l.startswith('#if'): + if l.startswith('#require'): + lsplit = l.split() + if len(lsplit) < 2 or lsplit[0] != '#require': + after.setdefault(pos, []).append(' !!! invalid #require\n') + if not self._hghave(lsplit[1:]): + script = ["exit 80\n"] + break + after.setdefault(pos, []).append(l) + elif l.startswith('#if'): lsplit = l.split() if len(lsplit) < 2 or lsplit[0] != '#if': after.setdefault(pos, []).append(' !!! invalid #if\n') @@ -1041,7 +1073,7 @@ output = re.sub(s, r, output) return ret, output.splitlines(True) -iolock = threading.Lock() +iolock = threading.RLock() class SkipTest(Exception): """Raised to indicate that a test is to be skipped.""" @@ -1077,46 +1109,59 @@ self.times = [] self._started = {} + self._stopped = {} + # Data stored for the benefit of generating xunit reports. + self.successes = [] + self.faildata = {} def addFailure(self, test, reason): self.failures.append((test, reason)) - iolock.acquire() if self._options.first: self.stop() else: + iolock.acquire() if not self._options.nodiff: self.stream.write('\nERROR: %s output changed\n' % test) self.stream.write('!') self.stream.flush() - iolock.release() + iolock.release() - def addError(self, *args, **kwargs): - super(TestResult, self).addError(*args, **kwargs) + def addSuccess(self, test): + iolock.acquire() + super(TestResult, self).addSuccess(test) + iolock.release() + self.successes.append(test) + def addError(self, test, err): + super(TestResult, self).addError(test, err) if self._options.first: self.stop() # Polyfill. def addSkip(self, test, reason): self.skipped.append((test, reason)) - + iolock.acquire() if self.showAll: self.stream.writeln('skipped %s' % reason) else: self.stream.write('s') self.stream.flush() + iolock.release() def addIgnore(self, test, reason): self.ignored.append((test, reason)) - + iolock.acquire() if self.showAll: self.stream.writeln('ignored %s' % reason) else: - if reason != 'not retesting': + if reason != 'not retesting' and reason != "doesn't match keyword": self.stream.write('i') + else: + self.testsRun += 1 self.stream.flush() + iolock.release() def addWarn(self, test, reason): self.warned.append((test, reason)) @@ -1124,16 +1169,20 @@ if self._options.first: self.stop() + iolock.acquire() if self.showAll: self.stream.writeln('warned %s' % reason) else: self.stream.write('~') self.stream.flush() + iolock.release() def addOutputMismatch(self, test, ret, got, expected): """Record a mismatch in test output for a particular test.""" accepted = False + failed = False + lines = [] iolock.acquire() if self._options.nodiff: @@ -1162,7 +1211,8 @@ else: rename(test.errpath, '%s.out' % test.path) accepted = True - + if not accepted and not failed: + self.faildata[test.name] = ''.join(lines) iolock.release() return accepted @@ -1170,17 +1220,30 @@ def startTest(self, test): super(TestResult, self).startTest(test) - self._started[test.name] = time.time() + # os.times module computes the user time and system time spent by + # child's processes along with real elapsed time taken by a process. + # This module has one limitation. It can only work for Linux user + # and not for Windows. + self._started[test.name] = os.times() def stopTest(self, test, interrupted=False): super(TestResult, self).stopTest(test) - self.times.append((test.name, time.time() - self._started[test.name])) + self._stopped[test.name] = os.times() + + starttime = self._started[test.name] + endtime = self._stopped[test.name] + self.times.append((test.name, endtime[2] - starttime[2], + endtime[3] - starttime[3], endtime[4] - starttime[4])) + del self._started[test.name] + del self._stopped[test.name] if interrupted: + iolock.acquire() self.stream.writeln('INTERRUPTED: %s (after %d seconds)' % ( - test.name, self.times[-1][1])) + test.name, self.times[-1][3])) + iolock.release() class TestSuite(unittest.TestSuite): """Custom unitest TestSuite that knows how to execute Mercurial tests.""" @@ -1314,6 +1377,7 @@ skipped = len(result.skipped) ignored = len(result.ignored) + iolock.acquire() self.stream.writeln('') if not self._runner.options.noskips: @@ -1326,20 +1390,39 @@ for test, msg in result.errors: self.stream.writeln('Errored %s: %s' % (test.name, msg)) + if self._runner.options.xunit: + xuf = open(self._runner.options.xunit, 'wb') + try: + timesd = dict( + (test, real) for test, cuser, csys, real in result.times) + doc = minidom.Document() + s = doc.createElement('testsuite') + s.setAttribute('name', 'run-tests') + s.setAttribute('tests', str(result.testsRun)) + s.setAttribute('errors', "0") # TODO + s.setAttribute('failures', str(failed)) + s.setAttribute('skipped', str(skipped + ignored)) + doc.appendChild(s) + for tc in result.successes: + t = doc.createElement('testcase') + t.setAttribute('name', tc.name) + t.setAttribute('time', '%.3f' % timesd[tc.name]) + s.appendChild(t) + for tc, err in sorted(result.faildata.iteritems()): + t = doc.createElement('testcase') + t.setAttribute('name', tc) + t.setAttribute('time', '%.3f' % timesd[tc]) + cd = doc.createCDATASection(cdatasafe(err)) + t.appendChild(cd) + s.appendChild(t) + xuf.write(doc.toprettyxml(indent=' ', encoding='utf-8')) + finally: + xuf.close() + self._runner._checkhglib('Tested') - # When '--retest' is enabled, only failure tests run. At this point - # "result.testsRun" holds the count of failure test that has run. But - # as while printing output, we have subtracted the skipped and ignored - # count from "result.testsRun". Therefore, to make the count remain - # the same, we need to add skipped and ignored count in here. - if self._runner.options.retest: - result.testsRun = result.testsRun + skipped + ignored - - # This differs from unittest's default output in that we don't count - # skipped and ignored tests as part of the total test count. self.stream.writeln('# Ran %d tests, %d skipped, %d warned, %d failed.' - % (result.testsRun - skipped - ignored, + % (result.testsRun, skipped + ignored, warned, failed)) if failed: self.stream.writeln('python hash seed: %s' % @@ -1347,15 +1430,19 @@ if self._runner.options.time: self.printtimes(result.times) + iolock.release() + return result def printtimes(self, times): + # iolock held by run self.stream.writeln('# Producing time report') - times.sort(key=lambda t: (t[1], t[0]), reverse=True) - cols = '%7.3f %s' - self.stream.writeln('%-7s %s' % ('Time', 'Test')) - for test, timetaken in times: - self.stream.writeln(cols % (timetaken, test)) + times.sort(key=lambda t: (t[3])) + cols = '%7.3f %7.3f %7.3f %s' + self.stream.writeln('%-7s %-7s %-7s %s' % ('cuser', 'csys', 'real', + 'Test')) + for test, cuser, csys, real in times: + self.stream.writeln(cols % (cuser, csys, real, test)) class TestRunner(object): """Holds context for executing tests.
--- a/tests/test-acl.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-acl.t Thu Aug 14 16:25:47 2014 -0500 @@ -82,6 +82,7 @@ query 1; heads searching for changes all remote heads known locally + listing keys for "phases" listing keys for "bookmarks" 3 changesets found list of changesets: @@ -140,6 +141,7 @@ query 1; heads searching for changes all remote heads known locally + listing keys for "phases" invalid branchheads cache (served): tip differs listing keys for "bookmarks" 3 changesets found @@ -202,6 +204,7 @@ query 1; heads searching for changes all remote heads known locally + listing keys for "phases" invalid branchheads cache (served): tip differs listing keys for "bookmarks" 3 changesets found @@ -274,6 +277,7 @@ query 1; heads searching for changes all remote heads known locally + listing keys for "phases" invalid branchheads cache (served): tip differs listing keys for "bookmarks" 3 changesets found @@ -341,6 +345,7 @@ query 1; heads searching for changes all remote heads known locally + listing keys for "phases" invalid branchheads cache (served): tip differs listing keys for "bookmarks" 3 changesets found @@ -413,6 +418,7 @@ query 1; heads searching for changes all remote heads known locally + listing keys for "phases" invalid branchheads cache (served): tip differs listing keys for "bookmarks" 3 changesets found @@ -482,6 +488,7 @@ query 1; heads searching for changes all remote heads known locally + listing keys for "phases" invalid branchheads cache (served): tip differs listing keys for "bookmarks" 3 changesets found @@ -556,6 +563,7 @@ query 1; heads searching for changes all remote heads known locally + listing keys for "phases" invalid branchheads cache (served): tip differs listing keys for "bookmarks" 3 changesets found @@ -627,6 +635,7 @@ query 1; heads searching for changes all remote heads known locally + listing keys for "phases" invalid branchheads cache (served): tip differs listing keys for "bookmarks" 3 changesets found @@ -700,6 +709,7 @@ query 1; heads searching for changes all remote heads known locally + listing keys for "phases" invalid branchheads cache (served): tip differs listing keys for "bookmarks" 3 changesets found @@ -779,6 +789,7 @@ query 1; heads searching for changes all remote heads known locally + listing keys for "phases" invalid branchheads cache (served): tip differs listing keys for "bookmarks" 3 changesets found @@ -859,6 +870,7 @@ query 1; heads searching for changes all remote heads known locally + listing keys for "phases" invalid branchheads cache (served): tip differs listing keys for "bookmarks" 3 changesets found @@ -934,6 +946,7 @@ query 1; heads searching for changes all remote heads known locally + listing keys for "phases" invalid branchheads cache (served): tip differs listing keys for "bookmarks" 3 changesets found @@ -1020,6 +1033,7 @@ query 1; heads searching for changes all remote heads known locally + listing keys for "phases" invalid branchheads cache (served): tip differs listing keys for "bookmarks" 3 changesets found @@ -1100,6 +1114,7 @@ query 1; heads searching for changes all remote heads known locally + listing keys for "phases" invalid branchheads cache (served): tip differs listing keys for "bookmarks" 3 changesets found @@ -1176,6 +1191,7 @@ query 1; heads searching for changes all remote heads known locally + listing keys for "phases" invalid branchheads cache (served): tip differs listing keys for "bookmarks" 3 changesets found @@ -1252,6 +1268,7 @@ query 1; heads searching for changes all remote heads known locally + listing keys for "phases" invalid branchheads cache (served): tip differs listing keys for "bookmarks" 3 changesets found @@ -1329,6 +1346,7 @@ query 1; heads searching for changes all remote heads known locally + listing keys for "phases" invalid branchheads cache (served): tip differs listing keys for "bookmarks" 3 changesets found @@ -1444,6 +1462,7 @@ query 1; heads searching for changes all remote heads known locally + listing keys for "phases" listing keys for "bookmarks" 4 changesets found list of changesets: @@ -1527,6 +1546,7 @@ query 1; heads searching for changes all remote heads known locally + listing keys for "phases" listing keys for "bookmarks" 4 changesets found list of changesets: @@ -1606,6 +1626,7 @@ query 1; heads searching for changes all remote heads known locally + listing keys for "phases" listing keys for "bookmarks" 4 changesets found list of changesets: @@ -1681,6 +1702,7 @@ query 1; heads searching for changes all remote heads known locally + listing keys for "phases" listing keys for "bookmarks" 4 changesets found list of changesets: @@ -1750,6 +1772,7 @@ query 1; heads searching for changes all remote heads known locally + listing keys for "phases" listing keys for "bookmarks" 4 changesets found list of changesets: @@ -1838,6 +1861,7 @@ query 1; heads searching for changes all remote heads known locally + listing keys for "phases" listing keys for "bookmarks" 4 changesets found list of changesets: @@ -1925,6 +1949,7 @@ query 1; heads searching for changes all remote heads known locally + listing keys for "phases" listing keys for "bookmarks" 4 changesets found list of changesets: @@ -1999,6 +2024,7 @@ query 1; heads searching for changes all remote heads known locally + listing keys for "phases" listing keys for "bookmarks" 4 changesets found list of changesets: @@ -2080,6 +2106,7 @@ query 1; heads searching for changes all remote heads known locally + listing keys for "phases" listing keys for "bookmarks" 4 changesets found list of changesets:
--- a/tests/test-alias.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-alias.t Thu Aug 14 16:25:47 2014 -0500 @@ -10,6 +10,7 @@ > unknown = bargle > ambiguous = s > recursive = recursive + > disabled = email > nodefinition = > noclosingquotation = ' > no--cwd = status --cwd elsewhere @@ -30,6 +31,7 @@ > echo1 = !printf '\$1\n' > echo2 = !printf '\$2\n' > echo13 = !printf '\$1 \$3\n' + > echotokens = !printf "%s\n" "\$@" > count = !hg log -r "\$@" --template=. | wc -c | sed -e 's/ //g' > mcount = !hg log \$@ --template=. | wc -c | sed -e 's/ //g' > rt = root @@ -60,7 +62,7 @@ unknown $ hg unknown - alias 'unknown' resolves to unknown command 'bargle' + abort: alias 'unknown' resolves to unknown command 'bargle' [255] $ hg help unknown alias 'unknown' resolves to unknown command 'bargle' @@ -69,7 +71,7 @@ ambiguous $ hg ambiguous - alias 'ambiguous' resolves to ambiguous command 's' + abort: alias 'ambiguous' resolves to ambiguous command 's' [255] $ hg help ambiguous alias 'ambiguous' resolves to ambiguous command 's' @@ -78,16 +80,32 @@ recursive $ hg recursive - alias 'recursive' resolves to unknown command 'recursive' + abort: alias 'recursive' resolves to unknown command 'recursive' [255] $ hg help recursive alias 'recursive' resolves to unknown command 'recursive' +disabled + + $ hg disabled + abort: alias 'disabled' resolves to unknown command 'email' + ('email' is provided by 'patchbomb' extension) + [255] + $ hg help disabled + alias 'disabled' resolves to unknown command 'email' + + 'email' is provided by the following extension: + + patchbomb command to send changesets as (a series of) patch emails + + (use "hg help extensions" for information on enabling extensions) + + no definition $ hg nodef - no definition for alias 'nodefinition' + abort: no definition for alias 'nodefinition' [255] $ hg help nodef no definition for alias 'nodefinition' @@ -96,7 +114,7 @@ no closing quotation $ hg noclosing - error in definition for alias 'noclosingquotation': No closing quotation + abort: error in definition for alias 'noclosingquotation': No closing quotation [255] $ hg help noclosing error in definition for alias 'noclosingquotation': No closing quotation @@ -105,27 +123,30 @@ invalid options $ hg no--cwd - error in definition for alias 'no--cwd': --cwd may only be given on the command line + abort: error in definition for alias 'no--cwd': --cwd may only be given on the command line [255] $ hg help no--cwd - error in definition for alias 'no--cwd': --cwd may only be given on the command line + error in definition for alias 'no--cwd': --cwd may only be given on the + command line $ hg no-R - error in definition for alias 'no-R': -R may only be given on the command line + abort: error in definition for alias 'no-R': -R may only be given on the command line [255] $ hg help no-R error in definition for alias 'no-R': -R may only be given on the command line $ hg no--repo - error in definition for alias 'no--repo': --repo may only be given on the command line + abort: error in definition for alias 'no--repo': --repo may only be given on the command line [255] $ hg help no--repo - error in definition for alias 'no--repo': --repo may only be given on the command line + error in definition for alias 'no--repo': --repo may only be given on the + command line $ hg no--repository - error in definition for alias 'no--repository': --repository may only be given on the command line + abort: error in definition for alias 'no--repository': --repository may only be given on the command line [255] $ hg help no--repository - error in definition for alias 'no--repository': --repository may only be given on the command line + error in definition for alias 'no--repository': --repository may only be given + on the command line $ hg no--config - error in definition for alias 'no--config': --config may only be given on the command line + abort: error in definition for alias 'no--config': --config may only be given on the command line [255] optional repository @@ -229,6 +250,10 @@ foo $ hg echoall 'test $2' foo test $2 foo + $ hg echoall 'test $@' foo '$@' + test $@ foo $@ + $ hg echoall 'test "$@"' foo '"$@"' + test "$@" foo "$@" $ hg echo1 foo bar baz foo $ hg echo2 foo bar baz @@ -237,6 +262,22 @@ foo baz $ hg echo2 foo + $ hg echotokens + + $ hg echotokens foo 'bar $1 baz' + foo + bar $1 baz + $ hg echotokens 'test $2' foo + test $2 + foo + $ hg echotokens 'test $@' foo '$@' + test $@ + foo + $@ + $ hg echotokens 'test "$@"' foo '"$@"' + test "$@" + foo + "$@" $ echo bar > bar $ hg commit -qA -m bar $ hg count . @@ -370,7 +411,7 @@ alias for: hg root - use "hg help rt" to show the full help text + (use "hg rt -h" to show more help) [255] invalid global arguments for normal commands, aliases, and shell aliases @@ -399,7 +440,7 @@ summary summarize working directory state update update working directory (or switch revisions) - use "hg help" for the full list of commands or "hg -v" for details + (use "hg help" for the full list of commands or "hg -v" for details) [255] $ hg --invalid mylog hg: option --invalid not recognized @@ -425,7 +466,7 @@ summary summarize working directory state update update working directory (or switch revisions) - use "hg help" for the full list of commands or "hg -v" for details + (use "hg help" for the full list of commands or "hg -v" for details) [255] $ hg --invalid blank hg: option --invalid not recognized @@ -451,7 +492,7 @@ summary summarize working directory state update update working directory (or switch revisions) - use "hg help" for the full list of commands or "hg -v" for details + (use "hg help" for the full list of commands or "hg -v" for details) [255] This should show id:
--- a/tests/test-archive-symlinks.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-archive-symlinks.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ - $ "$TESTDIR/hghave" symlink || exit 80 +#require symlink $ origdir=`pwd`
--- a/tests/test-archive.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-archive.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ - $ "$TESTDIR/hghave" serve || exit 80 +#require serve $ hg init test $ cd test
--- a/tests/test-bad-pull.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-bad-pull.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ - $ "$TESTDIR/hghave" serve || exit 80 +#require serve #if windows $ hg clone http://localhost:$HGPORT/ copy
--- a/tests/test-bookmarks-pushpull.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-bookmarks-pushpull.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ - $ "$TESTDIR/hghave" serve || exit 80 +#require serve $ cat << EOF >> $HGRCPATH > [ui]
--- a/tests/test-bundle2.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-bundle2.t Thu Aug 14 16:25:47 2014 -0500 @@ -964,7 +964,8 @@ > raise util.Abort('Abandon ship!', hint="don't panic") > > def uisetup(ui): - > exchange.bundle2partsgenerators.insert(0, _pushbundle2failpart) + > exchange.b2partsgenmapping['failpart'] = _pushbundle2failpart + > exchange.b2partsgenorder.insert(0, 'failpart') > > EOF
--- a/tests/test-casecollision-merge.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-casecollision-merge.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,6 +1,4 @@ -run only on case-insensitive filesystems - - $ "$TESTDIR/hghave" icasefs || exit 80 +#require icasefs ################################ test for branch merging
--- a/tests/test-casecollision.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-casecollision.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,6 +1,4 @@ -run only on case-sensitive filesystems - - $ "$TESTDIR/hghave" no-icasefs || exit 80 +#require no-icasefs test file addition with colliding case
--- a/tests/test-casefolding.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-casefolding.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ - $ "$TESTDIR/hghave" icasefs || exit 80 +#require icasefs $ hg debugfs | grep 'case-sensitive:' case-sensitive: no
--- a/tests/test-changelog-exec.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-changelog-exec.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,9 +1,9 @@ +#require execbit + b51a8138292a introduced a regression where we would mention in the changelog executable files added by the second parent of a merge. Test that that doesn't happen anymore - $ "$TESTDIR/hghave" execbit || exit 80 - $ hg init repo $ cd repo $ echo foo > foo
--- a/tests/test-check-code-hg.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-check-code-hg.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ -#if test-repo +#require test-repo $ check_code="$TESTDIR"/../contrib/check-code.py $ cd "$TESTDIR"/.. @@ -13,5 +13,3 @@ Skipping mercurial/httpclient/__init__.py it has no-che?k-code (glob) Skipping mercurial/httpclient/_readers.py it has no-che?k-code (glob) Skipping mercurial/httpclient/socketutil.py it has no-che?k-code (glob) - -#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-check-commit-hg.t Thu Aug 14 16:25:47 2014 -0500 @@ -0,0 +1,26 @@ +#require test-repo + +Enable obsolescence to avoid the warning issue when obsmarker are found + + $ cat > obs.py << EOF + > import mercurial.obsolete + > mercurial.obsolete._enabled = True + > EOF + $ echo '[extensions]' >> $HGRCPATH + $ echo "obs=${TESTTMP}/obs.py" >> $HGRCPATH + +Go back in the hg repo + + $ cd $TESTDIR/.. + + $ for node in `hg log --rev 'draft() and ::.' --template '{node|short}\n'`; do + > hg export $node | contrib/check-commit > ${TESTTMP}/check-commit.out + > if [ $? -ne 0 ]; then + > echo "Revision $node does not comply to commit message rules" + > echo '------------------------------------------------------' + > cat ${TESTTMP}/check-commit.out + > echo + > fi + > done + +
--- a/tests/test-check-pyflakes.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-check-pyflakes.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ -#if test-repo pyflakes +#require test-repo pyflakes $ cd "`dirname "$TESTDIR"`" @@ -19,4 +19,4 @@ contrib/win32/hgwebdir_wsgi.py:93: 'from isapi.install import *' used; unable to detect undefined names (glob) tests/filterpyflakes.py:58: undefined name 'undefinedname' -#endif +
--- a/tests/test-clone-cgi.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-clone-cgi.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ - $ "$TESTDIR/hghave" no-msys || exit 80 # MSYS will translate web paths as if they were file paths +#require no-msys # MSYS will translate web paths as if they were file paths This is a test of the wire protocol over CGI-based hgweb. initialize repository
--- a/tests/test-commandserver.py.out Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-commandserver.py.out Thu Aug 14 16:25:47 2014 -0500 @@ -34,7 +34,7 @@ summary summarize working directory state update update working directory (or switch revisions) -use "hg help" for the full list of commands or "hg -v" for details +(use "hg help" for the full list of commands or "hg -v" for details) runcommand id --quiet 000000000000 runcommand id
--- a/tests/test-commit.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-commit.t Thu Aug 14 16:25:47 2014 -0500 @@ -359,6 +359,20 @@ $ cat >> .hg/hgrc <<EOF > [committemplate] + > changeset.commit.normal = HG: this is "commit.normal" template + > HG: {extramsg} + > {if(currentbookmark, + > "HG: bookmark '{currentbookmark}' is activated\n", + > "HG: no bookmark is activated\n")}{subrepos % + > "HG: subrepo '{subrepo}' is changed\n"} + > + > changeset.commit = HG: this is "commit" template + > HG: {extramsg} + > {if(currentbookmark, + > "HG: bookmark '{currentbookmark}' is activated\n", + > "HG: no bookmark is activated\n")}{subrepos % + > "HG: subrepo '{subrepo}' is changed\n"} + > > changeset = HG: this is customized commit template > HG: {extramsg} > {if(currentbookmark, @@ -373,7 +387,7 @@ $ echo 'sub2 = sub2' >> .hgsub $ HGEDITOR=cat hg commit -S -q - HG: this is customized commit template + HG: this is "commit.normal" template HG: Leave message empty to abort commit. HG: bookmark 'currentbookmark' is activated HG: subrepo 'sub' is changed @@ -381,9 +395,28 @@ abort: empty commit message [255] + $ cat >> .hg/hgrc <<EOF + > [committemplate] + > changeset.commit.normal = + > # now, "changeset.commit" should be chosen for "hg commit" + > EOF + $ hg bookmark --inactive currentbookmark $ hg forget .hgsub $ HGEDITOR=cat hg commit -q + HG: this is "commit" template + HG: Leave message empty to abort commit. + HG: no bookmark is activated + abort: empty commit message + [255] + + $ cat >> .hg/hgrc <<EOF + > [committemplate] + > changeset.commit = + > # now, "changeset" should be chosen for "hg commit" + > EOF + + $ HGEDITOR=cat hg commit -q HG: this is customized commit template HG: Leave message empty to abort commit. HG: no bookmark is activated
--- a/tests/test-completion.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-completion.t Thu Aug 14 16:25:47 2014 -0500 @@ -257,7 +257,7 @@ debugsuccessorssets: debugwalk: include, exclude debugwireargs: three, four, five, ssh, remotecmd, insecure - graft: rev, continue, edit, log, currentdate, currentuser, date, user, tool, dry-run + graft: rev, continue, edit, log, force, currentdate, currentuser, date, user, tool, dry-run grep: print0, all, text, follow, ignore-case, files-with-matches, line-number, rev, user, date, include, exclude heads: rev, topo, active, closed, style, template help: extension, command, keyword
--- a/tests/test-conflict.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-conflict.t Thu Aug 14 16:25:47 2014 -0500 @@ -198,3 +198,37 @@ 5 >>>>>>> other Hop we are done. + +internal:merge3 + + $ hg up -q --clean . + + $ hg merge 1 --tool internal:merge3 + merging a + warning: conflicts during merge. + merging a incomplete! (edit conflicts, then use 'hg resolve --mark') + 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] + $ cat a + Small Mathematical Series. + <<<<<<< local + 1 + 2 + 3 + 6 + 8 + ||||||| base + One + Two + Three + Four + Five + ======= + 1 + 2 + 3 + 4 + 5 + >>>>>>> other + Hop we are done.
--- a/tests/test-contrib.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-contrib.t Thu Aug 14 16:25:47 2014 -0500 @@ -143,23 +143,11 @@ $ echo not other >> conflict-local $ echo end >> conflict-local $ echo end >> conflict-other + $ python simplemerge -p conflict-local base conflict-other base <<<<<<< conflict-local not other - ======= - other - >>>>>>> conflict-other - end - warning: conflicts during merge. - [1] - ---no-minimal - - $ python simplemerge -p --no-minimal conflict-local base conflict-other - base - <<<<<<< conflict-local - not other end ======= other @@ -174,10 +162,11 @@ base <<<<<<< foo not other + end ======= other + end >>>>>>> conflict-other - end warning: conflicts during merge. [1] @@ -187,17 +176,33 @@ base <<<<<<< foo not other + end ======= other + end >>>>>>> bar + warning: conflicts during merge. + [1] + +3 labels + + $ python simplemerge -p -L foo -L bar -L base conflict-local base conflict-other + base + <<<<<<< foo + not other end + ||||||| base + ======= + other + end + >>>>>>> bar warning: conflicts during merge. [1] too many labels - $ python simplemerge -p -L foo -L bar -L baz conflict-local base conflict-other - abort: can only specify two labels. + $ python simplemerge -p -L foo -L bar -L baz -L buz conflict-local base conflict-other + abort: can only specify three labels. [255] binary file @@ -231,7 +236,7 @@ -L --label labels to use on conflict markers -a --text treat all files as text -p --print print results instead of overwriting LOCAL - --no-minimal do not try to minimize conflict regions + --no-minimal no effect (DEPRECATED) -h --help display help and exit -q --quiet suppress output @@ -251,7 +256,7 @@ -L --label labels to use on conflict markers -a --text treat all files as text -p --print print results instead of overwriting LOCAL - --no-minimal do not try to minimize conflict regions + --no-minimal no effect (DEPRECATED) -h --help display help and exit -q --quiet suppress output [1] @@ -272,7 +277,7 @@ -L --label labels to use on conflict markers -a --text treat all files as text -p --print print results instead of overwriting LOCAL - --no-minimal do not try to minimize conflict regions + --no-minimal no effect (DEPRECATED) -h --help display help and exit -q --quiet suppress output [1]
--- a/tests/test-convert-baz.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-convert-baz.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ - $ "$TESTDIR/hghave" baz symlink || exit 80 +#require baz symlink $ baz my-id "mercurial <mercurial@selenic.com>"
--- a/tests/test-convert-bzr-114.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-convert-bzr-114.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,5 +1,5 @@ +#require bzr114 - $ "$TESTDIR/hghave" bzr114 || exit 80 $ . "$TESTDIR/bzr-definitions" The file/directory replacement can only be reproduced on
--- a/tests/test-convert-cvs-branch.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-convert-cvs-branch.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,7 +1,8 @@ +#require cvs + This is http://mercurial.selenic.com/bts/issue1148 and http://mercurial.selenic.com/bts/issue1447 - $ "$TESTDIR/hghave" cvs || exit 80 $ cvscall() > { > cvs -f "$@" > /dev/null
--- a/tests/test-convert-cvs-detectmerge.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-convert-cvs-detectmerge.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,8 +1,9 @@ +#require cvs + Test config convert.cvsps.mergefrom config setting. (Should test similar mergeto feature, but I don't understand it yet.) Requires builtin cvsps. - $ "$TESTDIR/hghave" cvs || exit 80 $ CVSROOT=`pwd`/cvsrepo $ export CVSROOT
--- a/tests/test-convert-cvs-synthetic.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-convert-cvs-synthetic.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,6 +1,7 @@ +#require cvs112 + This feature requires use of builtin cvsps! - $ "$TESTDIR/hghave" cvs112 || exit 80 $ echo "[extensions]" >> $HGRCPATH $ echo "convert = " >> $HGRCPATH
--- a/tests/test-convert-cvs.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-convert-cvs.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,5 +1,5 @@ +#require cvs - $ "$TESTDIR/hghave" cvs || exit 80 $ cvscall() > { > cvs -f "$@"
--- a/tests/test-convert-cvsnt-mergepoints.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-convert-cvsnt-mergepoints.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,5 +1,5 @@ +#require cvs - $ "$TESTDIR/hghave" cvs || exit 80 $ filterpath() > { > eval "$@" | sed "s:$CVSROOT:*REPO*:g"
--- a/tests/test-convert-darcs.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-convert-darcs.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,5 +1,5 @@ +#require darcs - $ "$TESTDIR/hghave" darcs || exit 80 $ echo "[extensions]" >> $HGRCPATH $ echo "convert=" >> $HGRCPATH $ DARCS_EMAIL='test@example.org'; export DARCS_EMAIL
--- a/tests/test-convert-git.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-convert-git.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,5 +1,5 @@ +#require git - $ "$TESTDIR/hghave" git || exit 80 $ echo "[core]" >> $HOME/.gitconfig $ echo "autocrlf = false" >> $HOME/.gitconfig $ echo "[core]" >> $HOME/.gitconfig
--- a/tests/test-convert-hg-svn.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-convert-hg-svn.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,5 +1,5 @@ +#require svn svn-bindings - $ "$TESTDIR/hghave" svn svn-bindings || exit 80 $ echo "[extensions]" >> $HGRCPATH $ echo "convert = " >> $HGRCPATH $ echo "mq = " >> $HGRCPATH
--- a/tests/test-convert-mtn.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-convert-mtn.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,5 +1,4 @@ - - $ "$TESTDIR/hghave" mtn || exit 80 +#require mtn Monotone directory is called .monotone on *nix and monotone on Windows.
--- a/tests/test-convert-p4-filetypes.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-convert-p4-filetypes.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ - $ "$TESTDIR/hghave" p4 execbit symlink || exit 80 +#require p4 execbit symlink $ echo "[extensions]" >> $HGRCPATH $ echo "convert = " >> $HGRCPATH
--- a/tests/test-convert-p4.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-convert-p4.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ - $ "$TESTDIR/hghave" p4 || exit 80 +#require p4 $ echo "[extensions]" >> $HGRCPATH $ echo "convert = " >> $HGRCPATH
--- a/tests/test-convert-svn-branches.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-convert-svn-branches.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,5 +1,4 @@ - - $ "$TESTDIR/hghave" svn svn-bindings || exit 80 +#require svn svn-bindings $ cat >> $HGRCPATH <<EOF > [extensions]
--- a/tests/test-convert-svn-encoding.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-convert-svn-encoding.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,5 +1,4 @@ - - $ "$TESTDIR/hghave" svn svn-bindings || exit 80 +#require svn svn-bindings $ cat >> $HGRCPATH <<EOF > [extensions]
--- a/tests/test-convert-svn-move.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-convert-svn-move.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,5 +1,4 @@ - - $ "$TESTDIR/hghave" svn svn-bindings || exit 80 +#require svn svn-bindings $ cat >> $HGRCPATH <<EOF > [extensions]
--- a/tests/test-convert-svn-sink.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-convert-svn-sink.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ - $ "$TESTDIR/hghave" svn13 || exit 80 +#require svn13 $ svnupanddisplay() > {
--- a/tests/test-convert-svn-source.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-convert-svn-source.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,5 +1,4 @@ - - $ "$TESTDIR/hghave" svn svn-bindings || exit 80 +#require svn svn-bindings $ cat >> $HGRCPATH <<EOF > [extensions]
--- a/tests/test-convert-svn-startrev.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-convert-svn-startrev.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,5 +1,4 @@ - - $ "$TESTDIR/hghave" svn svn-bindings || exit 80 +#require svn svn-bindings $ cat >> $HGRCPATH <<EOF > [extensions]
--- a/tests/test-convert-svn-tags.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-convert-svn-tags.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,5 +1,4 @@ - - $ "$TESTDIR/hghave" svn svn-bindings || exit 80 +#require svn svn-bindings $ cat >> $HGRCPATH <<EOF > [extensions]
--- a/tests/test-convert-tagsbranch-topology.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-convert-tagsbranch-topology.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,5 +1,5 @@ +#require git - $ "$TESTDIR/hghave" git || exit 80 $ echo "[core]" >> $HOME/.gitconfig $ echo "autocrlf = false" >> $HOME/.gitconfig $ echo "[core]" >> $HOME/.gitconfig
--- a/tests/test-convert-tla.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-convert-tla.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,5 +1,5 @@ +#require tla symlink - $ "$TESTDIR/hghave" tla symlink || exit 80 $ tla my-id "mercurial <mercurial@selenic.com>" $ echo "[extensions]" >> $HGRCPATH $ echo "convert=" >> $HGRCPATH
--- a/tests/test-convert.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-convert.t Thu Aug 14 16:25:47 2014 -0500 @@ -272,7 +272,7 @@ --sourcesort preserve source changesets order --closesort try to reorder closed revisions - use "hg -v help convert" to show the global options + (some details hidden, use --verbose to show complete help) $ hg init a $ cd a $ echo a > a
--- a/tests/test-diff-upgrade.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-diff-upgrade.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ - $ "$TESTDIR/hghave" execbit || exit 80 +#require execbit $ echo "[extensions]" >> $HGRCPATH $ echo "autodiff=$TESTDIR/autodiff.py" >> $HGRCPATH
--- a/tests/test-dispatch.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-dispatch.t Thu Aug 14 16:25:47 2014 -0500 @@ -19,7 +19,7 @@ output the current or given revision of files - options: + options ([+] can be repeated): -o --output FORMAT print output to file with formatted name -r --rev REV print the given revision @@ -27,9 +27,7 @@ -I --include PATTERN [+] include names matching the given patterns -X --exclude PATTERN [+] exclude names matching the given patterns - [+] marked option can be specified multiple times - - use "hg help cat" to show the full help text + (use "hg cat -h" to show more help) [255] [defaults]
--- a/tests/test-encoding-align.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-encoding-align.t Thu Aug 14 16:25:47 2014 -0500 @@ -58,7 +58,7 @@ \xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d \xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d \xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d \xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d (esc) \xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d (esc) - use "hg -v help showoptlist" to show the global options + (some details hidden, use --verbose to show complete help) $ rm -f s; touch s
--- a/tests/test-encoding-textwrap.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-encoding-textwrap.t Thu Aug 14 16:25:47 2014 -0500 @@ -69,7 +69,7 @@ \x82\xa0\x82\xa2\x82\xa4\x82\xa6\x82\xa8\x82\xa9\x82\xab\x82\xad\x82\xaf\x82\xa0\x82\xa2\x82\xa4\x82\xa6\x82\xa8\x82\xa9\x82\xab\x82\xad\x82\xaf\x82\xa0\x82\xa2\x82\xa4\x82\xa6\x82\xa8\x82\xa9\x82\xab\x82\xad\x82\xaf (esc) \x82\xa0\x82\xa2\x82\xa4\x82\xa6\x82\xa8\x82\xa9\x82\xab\x82\xad\x82\xaf (esc) - use "hg -v help show_full_ja" to show the global options + (some details hidden, use --verbose to show complete help) (1-2) display Japanese full-width characters in utf-8 @@ -84,7 +84,7 @@ \xe3\x81\x82\xe3\x81\x84\xe3\x81\x86\xe3\x81\x88\xe3\x81\x8a\xe3\x81\x8b\xe3\x81\x8d\xe3\x81\x8f\xe3\x81\x91\xe3\x81\x82\xe3\x81\x84\xe3\x81\x86\xe3\x81\x88\xe3\x81\x8a\xe3\x81\x8b\xe3\x81\x8d\xe3\x81\x8f\xe3\x81\x91\xe3\x81\x82\xe3\x81\x84\xe3\x81\x86\xe3\x81\x88\xe3\x81\x8a\xe3\x81\x8b\xe3\x81\x8d\xe3\x81\x8f\xe3\x81\x91 (esc) \xe3\x81\x82\xe3\x81\x84\xe3\x81\x86\xe3\x81\x88\xe3\x81\x8a\xe3\x81\x8b\xe3\x81\x8d\xe3\x81\x8f\xe3\x81\x91 (esc) - use "hg -v help show_full_ja" to show the global options + (some details hidden, use --verbose to show complete help) (1-3) display Japanese half-width characters in cp932 @@ -100,7 +100,7 @@ \xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9 (esc) \xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9 (esc) - use "hg -v help show_half_ja" to show the global options + (some details hidden, use --verbose to show complete help) (1-4) display Japanese half-width characters in utf-8 @@ -115,7 +115,7 @@ \xef\xbd\xb1\xef\xbd\xb2\xef\xbd\xb3\xef\xbd\xb4\xef\xbd\xb5\xef\xbd\xb6\xef\xbd\xb7\xef\xbd\xb8\xef\xbd\xb9\xef\xbd\xb1\xef\xbd\xb2\xef\xbd\xb3\xef\xbd\xb4\xef\xbd\xb5\xef\xbd\xb6\xef\xbd\xb7\xef\xbd\xb8\xef\xbd\xb9\xef\xbd\xb1\xef\xbd\xb2\xef\xbd\xb3\xef\xbd\xb4\xef\xbd\xb5\xef\xbd\xb6\xef\xbd\xb7\xef\xbd\xb8\xef\xbd\xb9\xef\xbd\xb1\xef\xbd\xb2\xef\xbd\xb3\xef\xbd\xb4\xef\xbd\xb5\xef\xbd\xb6\xef\xbd\xb7\xef\xbd\xb8\xef\xbd\xb9\xef\xbd\xb1\xef\xbd\xb2\xef\xbd\xb3\xef\xbd\xb4\xef\xbd\xb5\xef\xbd\xb6\xef\xbd\xb7\xef\xbd\xb8\xef\xbd\xb9\xef\xbd\xb1\xef\xbd\xb2\xef\xbd\xb3\xef\xbd\xb4\xef\xbd\xb5\xef\xbd\xb6\xef\xbd\xb7\xef\xbd\xb8\xef\xbd\xb9 (esc) \xef\xbd\xb1\xef\xbd\xb2\xef\xbd\xb3\xef\xbd\xb4\xef\xbd\xb5\xef\xbd\xb6\xef\xbd\xb7\xef\xbd\xb8\xef\xbd\xb9\xef\xbd\xb1\xef\xbd\xb2\xef\xbd\xb3\xef\xbd\xb4\xef\xbd\xb5\xef\xbd\xb6\xef\xbd\xb7\xef\xbd\xb8\xef\xbd\xb9 (esc) - use "hg -v help show_half_ja" to show the global options + (some details hidden, use --verbose to show complete help) @@ -136,7 +136,7 @@ \x83\xbf\x83\xc0\x83\xc1\x83\xc2\x83\xd2\x83\xc4\x83\xc5\x83\xc6\x81\x9b\x83\xbf\x83\xc0\x83\xc1\x83\xc2\x83\xd2\x83\xc4\x83\xc5\x83\xc6\x81\x9b\x83\xbf\x83\xc0\x83\xc1\x83\xc2\x83\xd2\x83\xc4\x83\xc5\x83\xc6\x81\x9b\x83\xbf\x83\xc0\x83\xc1\x83\xc2\x83\xd2\x83\xc4\x83\xc5\x83\xc6\x81\x9b\x83\xbf\x83\xc0\x83\xc1\x83\xc2\x83\xd2\x83\xc4\x83\xc5\x83\xc6\x81\x9b\x83\xbf\x83\xc0\x83\xc1\x83\xc2\x83\xd2\x83\xc4\x83\xc5\x83\xc6\x81\x9b (esc) \x83\xbf\x83\xc0\x83\xc1\x83\xc2\x83\xd2\x83\xc4\x83\xc5\x83\xc6\x81\x9b (esc) - use "hg -v help show_ambig_ja" to show the global options + (some details hidden, use --verbose to show complete help) (2-1-2) display Japanese ambiguous-width characters in utf-8 @@ -151,7 +151,7 @@ \xce\xb1\xce\xb2\xce\xb3\xce\xb4\xcf\x85\xce\xb6\xce\xb7\xce\xb8\xe2\x97\x8b\xce\xb1\xce\xb2\xce\xb3\xce\xb4\xcf\x85\xce\xb6\xce\xb7\xce\xb8\xe2\x97\x8b\xce\xb1\xce\xb2\xce\xb3\xce\xb4\xcf\x85\xce\xb6\xce\xb7\xce\xb8\xe2\x97\x8b\xce\xb1\xce\xb2\xce\xb3\xce\xb4\xcf\x85\xce\xb6\xce\xb7\xce\xb8\xe2\x97\x8b\xce\xb1\xce\xb2\xce\xb3\xce\xb4\xcf\x85\xce\xb6\xce\xb7\xce\xb8\xe2\x97\x8b\xce\xb1\xce\xb2\xce\xb3\xce\xb4\xcf\x85\xce\xb6\xce\xb7\xce\xb8\xe2\x97\x8b (esc) \xce\xb1\xce\xb2\xce\xb3\xce\xb4\xcf\x85\xce\xb6\xce\xb7\xce\xb8\xe2\x97\x8b (esc) - use "hg -v help show_ambig_ja" to show the global options + (some details hidden, use --verbose to show complete help) (2-1-3) display Russian ambiguous-width characters in cp1251 @@ -166,7 +166,7 @@ \xcd\xe0\xf1\xf2\xf0\xee\xe9\xea\xe8\xcd\xe0\xf1\xf2\xf0\xee\xe9\xea\xe8\xcd\xe0\xf1\xf2\xf0\xee\xe9\xea\xe8\xcd\xe0\xf1\xf2\xf0\xee\xe9\xea\xe8\xcd\xe0\xf1\xf2\xf0\xee\xe9\xea\xe8\xcd\xe0\xf1\xf2\xf0\xee\xe9\xea\xe8 (esc) \xcd\xe0\xf1\xf2\xf0\xee\xe9\xea\xe8 (esc) - use "hg -v help show_ambig_ru" to show the global options + (some details hidden, use --verbose to show complete help) (2-1-4) display Russian ambiguous-width characters in utf-8 @@ -181,7 +181,7 @@ \xd0\x9d\xd0\xb0\xd1\x81\xd1\x82\xd1\x80\xd0\xbe\xd0\xb9\xd0\xba\xd0\xb8\xd0\x9d\xd0\xb0\xd1\x81\xd1\x82\xd1\x80\xd0\xbe\xd0\xb9\xd0\xba\xd0\xb8\xd0\x9d\xd0\xb0\xd1\x81\xd1\x82\xd1\x80\xd0\xbe\xd0\xb9\xd0\xba\xd0\xb8\xd0\x9d\xd0\xb0\xd1\x81\xd1\x82\xd1\x80\xd0\xbe\xd0\xb9\xd0\xba\xd0\xb8\xd0\x9d\xd0\xb0\xd1\x81\xd1\x82\xd1\x80\xd0\xbe\xd0\xb9\xd0\xba\xd0\xb8\xd0\x9d\xd0\xb0\xd1\x81\xd1\x82\xd1\x80\xd0\xbe\xd0\xb9\xd0\xba\xd0\xb8 (esc) \xd0\x9d\xd0\xb0\xd1\x81\xd1\x82\xd1\x80\xd0\xbe\xd0\xb9\xd0\xba\xd0\xb8 (esc) - use "hg -v help show_ambig_ru" to show the global options + (some details hidden, use --verbose to show complete help) (2-2) treat width of ambiguous characters as wide @@ -202,7 +202,7 @@ \x83\xbf\x83\xc0\x83\xc1\x83\xc2\x83\xd2\x83\xc4\x83\xc5\x83\xc6\x81\x9b\x83\xbf\x83\xc0\x83\xc1\x83\xc2\x83\xd2\x83\xc4\x83\xc5\x83\xc6\x81\x9b\x83\xbf\x83\xc0\x83\xc1\x83\xc2\x83\xd2\x83\xc4\x83\xc5\x83\xc6\x81\x9b (esc) \x83\xbf\x83\xc0\x83\xc1\x83\xc2\x83\xd2\x83\xc4\x83\xc5\x83\xc6\x81\x9b (esc) - use "hg -v help show_ambig_ja" to show the global options + (some details hidden, use --verbose to show complete help) (2-2-2) display Japanese ambiguous-width characters in utf-8 @@ -220,7 +220,7 @@ \xce\xb1\xce\xb2\xce\xb3\xce\xb4\xcf\x85\xce\xb6\xce\xb7\xce\xb8\xe2\x97\x8b\xce\xb1\xce\xb2\xce\xb3\xce\xb4\xcf\x85\xce\xb6\xce\xb7\xce\xb8\xe2\x97\x8b\xce\xb1\xce\xb2\xce\xb3\xce\xb4\xcf\x85\xce\xb6\xce\xb7\xce\xb8\xe2\x97\x8b (esc) \xce\xb1\xce\xb2\xce\xb3\xce\xb4\xcf\x85\xce\xb6\xce\xb7\xce\xb8\xe2\x97\x8b (esc) - use "hg -v help show_ambig_ja" to show the global options + (some details hidden, use --verbose to show complete help) (2-2-3) display Russian ambiguous-width characters in cp1251 @@ -238,7 +238,7 @@ \xcd\xe0\xf1\xf2\xf0\xee\xe9\xea\xe8\xcd\xe0\xf1\xf2\xf0\xee\xe9\xea\xe8\xcd\xe0\xf1\xf2\xf0\xee\xe9\xea\xe8 (esc) \xcd\xe0\xf1\xf2\xf0\xee\xe9\xea\xe8 (esc) - use "hg -v help show_ambig_ru" to show the global options + (some details hidden, use --verbose to show complete help) (2-2-4) display Russian ambiguous-width characters in utf-8 @@ -256,6 +256,6 @@ \xd0\x9d\xd0\xb0\xd1\x81\xd1\x82\xd1\x80\xd0\xbe\xd0\xb9\xd0\xba\xd0\xb8\xd0\x9d\xd0\xb0\xd1\x81\xd1\x82\xd1\x80\xd0\xbe\xd0\xb9\xd0\xba\xd0\xb8\xd0\x9d\xd0\xb0\xd1\x81\xd1\x82\xd1\x80\xd0\xbe\xd0\xb9\xd0\xba\xd0\xb8 (esc) \xd0\x9d\xd0\xb0\xd1\x81\xd1\x82\xd1\x80\xd0\xbe\xd0\xb9\xd0\xba\xd0\xb8 (esc) - use "hg -v help show_ambig_ru" to show the global options + (some details hidden, use --verbose to show complete help) $ cd ..
--- a/tests/test-eolfilename.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-eolfilename.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,6 +1,6 @@ -http://mercurial.selenic.com/bts/issue352 +#require eol-in-paths - $ "$TESTDIR/hghave" eol-in-paths || exit 80 +http://mercurial.selenic.com/bts/issue352 test issue352
--- a/tests/test-execute-bit.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-execute-bit.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ - $ "$TESTDIR/hghave" execbit || exit 80 +#require execbit $ hg init $ echo a > a
--- a/tests/test-extdiff.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-extdiff.t Thu Aug 14 16:25:47 2014 -0500 @@ -37,7 +37,7 @@ compared to the working directory, and, when no revisions are specified, the working directory files are compared to its parent. - options: + options ([+] can be repeated): -o --option OPT [+] pass option to comparison program -r --rev REV [+] revision @@ -45,9 +45,7 @@ -I --include PATTERN [+] include names matching the given patterns -X --exclude PATTERN [+] exclude names matching the given patterns - [+] marked option can be specified multiple times - - use "hg -v help falabala" to show the global options + (some details hidden, use --verbose to show complete help) $ hg ci -d '0 0' -mtest1
--- a/tests/test-extension.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-extension.t Thu Aug 14 16:25:47 2014 -0500 @@ -301,7 +301,7 @@ foo yet another foo command - global options: + global options ([+] can be repeated): -R --repository REPO repository root directory or name of overlay bundle file @@ -321,8 +321,6 @@ --version output version information and exit -h --help display help and exit --hidden consider hidden changesets - - [+] marked option can be specified multiple times @@ -337,7 +335,7 @@ debugfoobar yet another debug command foo yet another foo command - global options: + global options ([+] can be repeated): -R --repository REPO repository root directory or name of overlay bundle file @@ -357,8 +355,6 @@ --version output version information and exit -h --help display help and exit --hidden consider hidden changesets - - [+] marked option can be specified multiple times @@ -388,9 +384,9 @@ compared to the working directory, and, when no revisions are specified, the working directory files are compared to its parent. - use "hg help -e extdiff" to show help for the extdiff extension + (use "hg help -e extdiff" to show help for the extdiff extension) - options: + options ([+] can be repeated): -p --program CMD comparison program to run -o --option OPT [+] pass option to comparison program @@ -399,9 +395,7 @@ -I --include PATTERN [+] include names matching the given patterns -X --exclude PATTERN [+] exclude names matching the given patterns - [+] marked option can be specified multiple times - - use "hg -v help extdiff" to show the global options + (some details hidden, use --verbose to show complete help) @@ -469,7 +463,7 @@ extdiff use external program to diff repository (or selected files) - use "hg -v help extdiff" to show builtin aliases and global options + (use "hg help -v extdiff" to show built-in aliases and global options) @@ -533,7 +527,7 @@ multirevs command - use "hg -v help multirevs" to show the global options + (some details hidden, use --verbose to show complete help) @@ -543,7 +537,7 @@ multirevs command - use "hg help multirevs" to show the full help text + (use "hg multirevs -h" to show more help) [255] @@ -588,7 +582,7 @@ patchbomb command to send changesets as (a series of) patch emails - use "hg help extensions" for information on enabling extensions + (use "hg help extensions" for information on enabling extensions) $ hg qdel @@ -597,7 +591,7 @@ mq manage a stack of patches - use "hg help extensions" for information on enabling extensions + (use "hg help extensions" for information on enabling extensions) [255] @@ -607,7 +601,7 @@ churn command to display statistics about repository history - use "hg help extensions" for information on enabling extensions + (use "hg help extensions" for information on enabling extensions) [255] @@ -617,12 +611,12 @@ $ hg help churn churn extension - command to display statistics about repository history - use "hg help extensions" for information on enabling extensions + (use "hg help extensions" for information on enabling extensions) $ hg help patchbomb patchbomb extension - command to send changesets as (a series of) patch emails - use "hg help extensions" for information on enabling extensions + (use "hg help extensions" for information on enabling extensions) Broken disabled extension and command: @@ -642,7 +636,7 @@ $ hg --config extensions.path=./path.py help broken broken extension - (no help text available) - use "hg help extensions" for information on enabling extensions + (use "hg help extensions" for information on enabling extensions) $ cat > hgext/forest.py <<EOF
--- a/tests/test-fetch.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-fetch.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ - $ "$TESTDIR/hghave" serve || exit 80 +#require serve $ echo "[extensions]" >> $HGRCPATH $ echo "fetch=" >> $HGRCPATH
--- a/tests/test-flags.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-flags.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ - $ "$TESTDIR/hghave" execbit || exit 80 +#require execbit $ umask 027
--- a/tests/test-gendoc.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-gendoc.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,6 +1,7 @@ +#require docutils + Test document extraction - $ "$TESTDIR/hghave" docutils || exit 80 $ HGENCODING=UTF-8 $ export HGENCODING $ { echo C; ls "$TESTDIR/../i18n"/*.po | sort; } | while read PO; do
--- a/tests/test-getbundle.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-getbundle.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ - $ "$TESTDIR/hghave" serve || exit 80 +#require serve = Test the getbundle() protocol function =
--- a/tests/test-globalopts.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-globalopts.t Thu Aug 14 16:25:47 2014 -0500 @@ -357,7 +357,7 @@ templating Template Usage urls URL Paths - use "hg -v help" to show builtin aliases and global options + (use "hg help -v" to show built-in aliases and global options) @@ -439,7 +439,7 @@ templating Template Usage urls URL Paths - use "hg -v help" to show builtin aliases and global options + (use "hg help -v" to show built-in aliases and global options) Not tested: --debugger
--- a/tests/test-glog.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-glog.t Thu Aug 14 16:25:47 2014 -0500 @@ -1645,13 +1645,28 @@ ('symbol', 'filelog') ('string', 'aa')))) -Test --follow on a directory +Test --follow on a non-existent directory $ testlog -f dir abort: cannot follow file not in parent revision: "dir" abort: cannot follow file not in parent revision: "dir" abort: cannot follow file not in parent revision: "dir" +Test --follow on a directory + + $ hg up -q '.^' + $ testlog -f dir + [] + (group + (func + ('symbol', '_matchfiles') + (list + (list + ('string', 'r:') + ('string', 'd:relpath')) + ('string', 'p:dir')))) + $ hg up -q tip + Test --follow on file not in parent revision $ testlog -f a @@ -1662,9 +1677,15 @@ Test --follow and patterns $ testlog -f 'glob:*' - abort: can only follow copies/renames for explicit filenames - abort: can only follow copies/renames for explicit filenames - abort: can only follow copies/renames for explicit filenames + [] + (group + (func + ('symbol', '_matchfiles') + (list + (list + ('string', 'r:') + ('string', 'd:relpath')) + ('string', 'p:glob:*')))) Test --follow on a single rename @@ -1829,9 +1850,15 @@ ('string', 'd:relpath')) ('string', 'p:a')))) $ testlog --removed --follow a - abort: can only follow copies/renames for explicit filenames - abort: can only follow copies/renames for explicit filenames - abort: can only follow copies/renames for explicit filenames + [] + (group + (func + ('symbol', '_matchfiles') + (list + (list + ('string', 'r:') + ('string', 'd:relpath')) + ('string', 'p:a')))) Test --patch and --stat with --follow and --follow-first
--- a/tests/test-gpg.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-gpg.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,6 +1,7 @@ +#require gpg + Test the GPG extension - $ "$TESTDIR/hghave" gpg || exit 80 $ cat <<EOF >> $HGRCPATH > [extensions] > gpg=
--- a/tests/test-graft.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-graft.t Thu Aug 14 16:25:47 2014 -0500 @@ -631,3 +631,50 @@ grafting revision 13 grafting revision 19 merging b + +graft with --force (still doesn't graft merges) + + $ hg graft 19 0 6 + skipping ungraftable merge revision 6 + skipping ancestor revision 0 + skipping already grafted revision 19 (22 also has origin 2) + [255] + $ hg graft 19 0 6 --force + skipping ungraftable merge revision 6 + grafting revision 19 + merging b + grafting revision 0 + +graft --force after backout + + $ echo abc > a + $ hg ci -m 28 + $ hg backout 28 + reverting a + changeset 29:484c03b8dfa4 backs out changeset 28:6c56f0f7f033 + $ hg graft 28 + skipping ancestor revision 28 + [255] + $ hg graft 28 --force + grafting revision 28 + merging a + $ cat a + abc + +graft --continue after --force + + $ hg backout 30 + reverting a + changeset 31:3b96c18b7a1b backs out changeset 30:8f539994be33 + $ hg graft 28 --force --tool internal:fail + grafting revision 28 + abort: unresolved conflicts, can't continue + (use hg resolve and hg graft --continue) + [255] + $ hg resolve --all + merging a + (no more unresolved files) + $ hg graft -c + grafting revision 28 + $ cat a + abc
--- a/tests/test-hardlinks.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-hardlinks.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ - $ "$TESTDIR/hghave" hardlink || exit 80 +#require hardlink $ cat > nlinks.py <<EOF > import sys
--- a/tests/test-help.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-help.t Thu Aug 14 16:25:47 2014 -0500 @@ -23,7 +23,7 @@ summary summarize working directory state update update working directory (or switch revisions) - use "hg help" for the full list of commands or "hg -v" for details + (use "hg help" for the full list of commands or "hg -v" for details) $ hg -q add add the specified files on the next commit @@ -122,7 +122,7 @@ templating Template Usage urls URL Paths - use "hg -v help" to show builtin aliases and global options + (use "hg help -v" to show built-in aliases and global options) $ hg -q help add add the specified files on the next commit @@ -305,7 +305,7 @@ update, up, checkout, co update working directory (or switch revisions) - global options: + global options ([+] can be repeated): -R --repository REPO repository root directory or name of overlay bundle file @@ -326,9 +326,7 @@ -h --help display help and exit --hidden consider hidden changesets - [+] marked option can be specified multiple times - - use "hg help" for the full list of commands + (use "hg help" for the full list of commands) $ hg add -h hg add [OPTION]... [FILE]... @@ -344,16 +342,14 @@ Returns 0 if all files are successfully added. - options: + options ([+] can be repeated): -I --include PATTERN [+] include names matching the given patterns -X --exclude PATTERN [+] exclude names matching the given patterns -S --subrepos recurse into subrepositories -n --dry-run do not perform actions, just print output - [+] marked option can be specified multiple times - - use "hg -v help add" to show more complete help and the global options + (some details hidden, use --verbose to show complete help) Verbose help for add @@ -383,16 +379,14 @@ Returns 0 if all files are successfully added. - options: + options ([+] can be repeated): -I --include PATTERN [+] include names matching the given patterns -X --exclude PATTERN [+] exclude names matching the given patterns -S --subrepos recurse into subrepositories -n --dry-run do not perform actions, just print output - [+] marked option can be specified multiple times - - global options: + global options ([+] can be repeated): -R --repository REPO repository root directory or name of overlay bundle file @@ -412,8 +406,6 @@ --version output version information and exit -h --help display help and exit --hidden consider hidden changesets - - [+] marked option can be specified multiple times Test help option with version option @@ -431,16 +423,14 @@ add the specified files on the next commit - options: + options ([+] can be repeated): -I --include PATTERN [+] include names matching the given patterns -X --exclude PATTERN [+] exclude names matching the given patterns -S --subrepos recurse into subrepositories -n --dry-run do not perform actions, just print output - [+] marked option can be specified multiple times - - use "hg help add" to show the full help text + (use "hg add -h" to show more help) [255] Test ambiguous command help @@ -451,7 +441,7 @@ add add the specified files on the next commit addremove add all new files, delete all missing files - use "hg -v help ad" to show builtin aliases and global options + (use "hg help -v ad" to show built-in aliases and global options) Test command without options @@ -472,7 +462,7 @@ Returns 0 on success, 1 if errors are encountered. - use "hg -v help verify" to show the global options + (some details hidden, use --verbose to show complete help) $ hg help diff hg diff [OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]... @@ -505,7 +495,7 @@ Returns 0 on success. - options: + options ([+] can be repeated): -r --rev REV [+] revision -c --change REV change made by revision @@ -523,9 +513,7 @@ -X --exclude PATTERN [+] exclude names matching the given patterns -S --subrepos recurse into subrepositories - [+] marked option can be specified multiple times - - use "hg -v help diff" to show more complete help and the global options + (some details hidden, use --verbose to show complete help) $ hg help status hg status [OPTION]... [FILE]... @@ -567,7 +555,7 @@ Returns 0 on success. - options: + options ([+] can be repeated): -A --all show status of all files -m --modified show only modified files @@ -586,9 +574,7 @@ -X --exclude PATTERN [+] exclude names matching the given patterns -S --subrepos recurse into subrepositories - [+] marked option can be specified multiple times - - use "hg -v help status" to show more complete help and the global options + (some details hidden, use --verbose to show complete help) $ hg -q help status hg status [OPTION]... [FILE]... @@ -624,7 +610,7 @@ summary summarize working directory state update update working directory (or switch revisions) - use "hg help" for the full list of commands or "hg -v" for details + (use "hg help" for the full list of commands or "hg -v" for details) [255] @@ -663,7 +649,7 @@ -n -- normal desc --newline VALUE line1 line2 - use "hg -v help nohelp" to show the global options + (some details hidden, use --verbose to show complete help) $ hg help -k nohelp Commands: @@ -758,7 +744,7 @@ templating Template Usage urls URL Paths - use "hg -v help" to show builtin aliases and global options + (use "hg help -v" to show built-in aliases and global options) Test list of internal help commands @@ -820,7 +806,7 @@ debugwireargs (no help text available) - use "hg -v help debug" to show builtin aliases and global options + (use "hg help -v debug" to show built-in aliases and global options) Test list of commands with command with no help text @@ -832,7 +818,7 @@ nohelp (no help text available) - use "hg -v help helpext" to show builtin aliases and global options + (use "hg help -v helpext" to show built-in aliases and global options) test deprecated option is hidden in command help @@ -843,7 +829,7 @@ options: - use "hg -v help debugoptDEP" to show the global options + (some details hidden, use --verbose to show complete help) test deprecated option is shown with -v $ hg help -v debugoptDEP | grep dopt @@ -857,9 +843,9 @@ (*) (glob) - flaggor: + options: - *"hg -v help debugoptDEP"* (glob) + (some details hidden, use --verbose to show complete help) #endif Test commands that collide with topics (issue4240) @@ -1030,7 +1016,7 @@ This paragraph is never omitted, too (for extension) - use "hg help -v addverboseitems" to show more complete help + (some details hidden, use --verbose to show complete help) no commands defined $ hg help -v addverboseitems @@ -1051,7 +1037,7 @@ This paragraph is never omitted, too (for topic) - use "hg help -v topic-containing-verbose" to show more complete help + (some details hidden, use --verbose to show complete help) $ hg help -v topic-containing-verbose This is the topic to test omit indicating. """""""""""""""""""""""""""""""""""""""""" @@ -1715,7 +1701,7 @@ Returns 0 if all files are successfully added. </p> <p> - options: + options ([+] can be repeated): </p> <table> <tr><td>-I</td> @@ -1732,10 +1718,7 @@ <td>do not perform actions, just print output</td></tr> </table> <p> - [+] marked option can be specified multiple times - </p> - <p> - global options: + global options ([+] can be repeated): </p> <table> <tr><td>-R</td> @@ -1787,9 +1770,6 @@ <td>--hidden</td> <td>consider hidden changesets</td></tr> </table> - <p> - [+] marked option can be specified multiple times - </p> </div> </div> @@ -1911,7 +1891,7 @@ Returns 0 on success, 1 if any warnings encountered. </p> <p> - options: + options ([+] can be repeated): </p> <table> <tr><td>-A</td> @@ -1928,10 +1908,7 @@ <td>exclude names matching the given patterns</td></tr> </table> <p> - [+] marked option can be specified multiple times - </p> - <p> - global options: + global options ([+] can be repeated): </p> <table> <tr><td>-R</td> @@ -1983,9 +1960,6 @@ <td>--hidden</td> <td>consider hidden changesets</td></tr> </table> - <p> - [+] marked option can be specified multiple times - </p> </div> </div>
--- a/tests/test-hgweb-commands.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-hgweb-commands.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ - $ "$TESTDIR/hghave" serve || exit 80 +#require serve An attempt at more fully testing the hgweb web interface. The following things are tested elsewhere and are therefore omitted:
--- a/tests/test-hgweb-descend-empties.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-hgweb-descend-empties.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ - $ "$TESTDIR/hghave" serve || exit 80 +#require serve Test chains of near empty directories, terminating 3 different ways: - a1: file at level 4 (deepest)
--- a/tests/test-hgweb-diffs.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-hgweb-diffs.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ - $ "$TESTDIR/hghave" serve || exit 80 +#require serve setting up repo
--- a/tests/test-hgweb-empty.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-hgweb-empty.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ - $ "$TESTDIR/hghave" serve || exit 80 +#require serve Some tests for hgweb in an empty repository
--- a/tests/test-hgweb-filelog.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-hgweb-filelog.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ - $ "$TESTDIR/hghave" serve || exit 80 +#require serve $ hg init test $ cd test
--- a/tests/test-hgweb-raw.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-hgweb-raw.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ - $ "$TESTDIR/hghave" serve || exit 80 +#require serve Test raw style of hgweb
--- a/tests/test-hgweb-removed.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-hgweb-removed.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ - $ "$TESTDIR/hghave" serve || exit 80 +#require serve setting up repo
--- a/tests/test-hgweb.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-hgweb.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ - $ "$TESTDIR/hghave" serve || exit 80 +#require serve Some tests for hgweb. Tests static files, plain files and different 404's.
--- a/tests/test-hgwebdir.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-hgwebdir.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ - $ "$TESTDIR/hghave" serve || exit 80 +#require serve hide outer repo and work in dir without '.hg' $ hg init
--- a/tests/test-hgwebdirsym.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-hgwebdirsym.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,6 +1,6 @@ -Tests whether or not hgwebdir properly handles various symlink topologies. +#require serve symlink - $ "$TESTDIR/hghave" serve symlink || exit 80 +Tests whether or not hgwebdir properly handles various symlink topologies. hide outer repo $ hg init
--- a/tests/test-highlight.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-highlight.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,5 +1,5 @@ +#require pygments serve - $ "$TESTDIR/hghave" pygments serve || exit 80 $ cat <<EOF >> $HGRCPATH > [extensions] > highlight =
--- a/tests/test-histedit-arguments.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-histedit-arguments.t Thu Aug 14 16:25:47 2014 -0500 @@ -57,6 +57,7 @@ # p, pick = use commit # e, edit = use commit, but stop for amending # f, fold = use commit, but combine it with the one above + # r, roll = like fold, but discard this commit's description # d, drop = remove commit from history # m, mess = edit message without changing commit content # @@ -255,6 +256,7 @@ # p, pick = use commit # e, edit = use commit, but stop for amending # f, fold = use commit, but combine it with the one above + # r, roll = like fold, but discard this commit's description # d, drop = remove commit from history # m, mess = edit message without changing commit content #
--- a/tests/test-histedit-bookmark-motion.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-histedit-bookmark-motion.t Thu Aug 14 16:25:47 2014 -0500 @@ -73,6 +73,7 @@ # p, pick = use commit # e, edit = use commit, but stop for amending # f, fold = use commit, but combine it with the one above + # r, roll = like fold, but discard this commit's description # d, drop = remove commit from history # m, mess = edit message without changing commit content # @@ -133,6 +134,7 @@ # p, pick = use commit # e, edit = use commit, but stop for amending # f, fold = use commit, but combine it with the one above + # r, roll = like fold, but discard this commit's description # d, drop = remove commit from history # m, mess = edit message without changing commit content #
--- a/tests/test-histedit-commute.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-histedit-commute.t Thu Aug 14 16:25:47 2014 -0500 @@ -67,6 +67,7 @@ # p, pick = use commit # e, edit = use commit, but stop for amending # f, fold = use commit, but combine it with the one above + # r, roll = like fold, but discard this commit's description # d, drop = remove commit from history # m, mess = edit message without changing commit content # @@ -344,6 +345,7 @@ # p, pick = use commit # e, edit = use commit, but stop for amending # f, fold = use commit, but combine it with the one above + # r, roll = like fold, but discard this commit's description # d, drop = remove commit from history # m, mess = edit message without changing commit content #
--- a/tests/test-histedit-fold-non-commute.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-histedit-fold-non-commute.t Thu Aug 14 16:25:47 2014 -0500 @@ -183,3 +183,165 @@ f $ cd .. + +Repeat test using "roll", not "fold". "roll" folds in changes but drops message + + $ initrepo r2 + $ cd r2 + +Initial generation of the command files + + $ EDITED="$TESTTMP/editedhistory.2" + $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 3 >> $EDITED + $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 4 >> $EDITED + $ hg log --template 'roll {node|short} {rev} {desc}\n' -r 7 >> $EDITED + $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 5 >> $EDITED + $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 6 >> $EDITED + $ cat $EDITED + pick 65a9a84f33fd 3 c + pick 00f1c5383965 4 d + roll 39522b764e3d 7 does not commute with e + pick 7b4e2f4b7bcd 5 e + pick 500cac37a696 6 f + +log before edit + $ hg log --graph + @ changeset: 7:39522b764e3d + | tag: tip + | user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | summary: does not commute with e + | + o changeset: 6:500cac37a696 + | user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | summary: f + | + o changeset: 5:7b4e2f4b7bcd + | user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | summary: e + | + o changeset: 4:00f1c5383965 + | user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | summary: d + | + o changeset: 3:65a9a84f33fd + | user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | summary: c + | + o changeset: 2:da6535b52e45 + | user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | summary: b + | + o changeset: 1:c1f09da44841 + | user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | summary: a + | + o changeset: 0:1715188a53c7 + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: Initial commit + + +edit the history + $ hg histedit 3 --commands $EDITED 2>&1 | fixbundle + 2 files updated, 0 files merged, 0 files removed, 0 files unresolved + merging e + warning: conflicts during merge. + merging e incomplete! (edit conflicts, then use 'hg resolve --mark') + Fix up the change and run hg histedit --continue + +fix up + $ echo 'I can haz no commute' > e + $ hg resolve --mark e + (no more unresolved files) + $ hg histedit --continue 2>&1 | fixbundle | grep -v '2 files removed' + 2 files updated, 0 files merged, 0 files removed, 0 files unresolved + 2 files updated, 0 files merged, 0 files removed, 0 files unresolved + 0 files updated, 0 files merged, 0 files removed, 0 files unresolved + merging e + warning: conflicts during merge. + merging e incomplete! (edit conflicts, then use 'hg resolve --mark') + Fix up the change and run hg histedit --continue + +just continue this time + $ hg revert -r 'p1()' e + $ hg resolve --mark e + (no more unresolved files) + $ hg histedit --continue 2>&1 | fixbundle + 0 files updated, 0 files merged, 0 files removed, 0 files unresolved + 0 files updated, 0 files merged, 0 files removed, 0 files unresolved + +log after edit + $ hg log --graph + @ changeset: 5:e7c4f5d4eb75 + | tag: tip + | user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | summary: f + | + o changeset: 4:803d1bb561fc + | user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | summary: d + | + o changeset: 3:65a9a84f33fd + | user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | summary: c + | + o changeset: 2:da6535b52e45 + | user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | summary: b + | + o changeset: 1:c1f09da44841 + | user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | summary: a + | + o changeset: 0:1715188a53c7 + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: Initial commit + + +contents of e + $ hg cat e + I can haz no commute + +manifest + $ hg manifest + a + b + c + d + e + f + +description is taken from rollup target commit + + $ hg log --debug --rev 4 + changeset: 4:803d1bb561fceac3129ec778db9da249a3106fc3 + phase: draft + parent: 3:65a9a84f33fdeb1ad5679b3941ec885d2b24027b + parent: -1:0000000000000000000000000000000000000000 + manifest: 4:b068a323d969f22af1296ec6a5ea9384cef437ac + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + files: d e + extra: branch=default + extra: histedit_source=00f1c53839651fa5c76d423606811ea5455a79d0,39522b764e3d26103f08bd1fa2ccd3e3d7dbcf4e + description: + d + + + +done with repo r2 + + $ cd ..
--- a/tests/test-histedit-fold.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-histedit-fold.t Thu Aug 14 16:25:47 2014 -0500 @@ -105,6 +105,50 @@ +rollup will fold without preserving the folded commit's message + + $ hg histedit d2ae7f538514 --commands - 2>&1 <<EOF | fixbundle + > pick d2ae7f538514 b + > roll ee283cb5f2d5 e + > pick 6de59d13424a f + > pick 9c277da72c9b d + > EOF + 0 files updated, 0 files merged, 4 files removed, 0 files unresolved + 0 files updated, 0 files merged, 2 files removed, 0 files unresolved + 2 files updated, 0 files merged, 0 files removed, 0 files unresolved + 0 files updated, 0 files merged, 0 files removed, 0 files unresolved + 0 files updated, 0 files merged, 0 files removed, 0 files unresolved + 0 files updated, 0 files merged, 0 files removed, 0 files unresolved + +log after edit + $ hg logt --graph + @ 3:c4a9eb7989fc d + | + o 2:8e03a72b6f83 f + | + o 1:391ee782c689 b + | + o 0:cb9a9f314b8b a + + +description is taken from rollup target commit + + $ hg log --debug --rev 1 + changeset: 1:391ee782c68930be438ccf4c6a403daedbfbffa5 + phase: draft + parent: 0:cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b + parent: -1:0000000000000000000000000000000000000000 + manifest: 1:b5e112a3a8354e269b1524729f0918662d847c38 + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + files+: b e + extra: branch=default + extra: histedit_source=d2ae7f538514cd87c17547b0de4cea71fe1af9fb,ee283cb5f2d5955443f23a27b697a04339e9a39a + description: + b + + + check saving last-message.txt $ cat > $TESTTMP/abortfolding.py <<EOF @@ -128,9 +172,9 @@ > EOF $ rm -f .hg/last-message.txt - $ HGEDITOR="sh $TESTTMP/editor.sh" hg histedit 6de59d13424a --commands - 2>&1 <<EOF | fixbundle - > pick 6de59d13424a f - > fold 9c277da72c9b d + $ HGEDITOR="sh $TESTTMP/editor.sh" hg histedit 8e03a72b6f83 --commands - 2>&1 <<EOF | fixbundle + > pick 8e03a72b6f83 f + > fold c4a9eb7989fc d > EOF 0 files updated, 0 files merged, 1 files removed, 0 files unresolved allow non-folding commit
--- a/tests/test-histedit-obsolete.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-histedit-obsolete.t Thu Aug 14 16:25:47 2014 -0500 @@ -57,6 +57,7 @@ # p, pick = use commit # e, edit = use commit, but stop for amending # f, fold = use commit, but combine it with the one above + # r, roll = like fold, but discard this commit's description # d, drop = remove commit from history # m, mess = edit message without changing commit content #
--- a/tests/test-histedit-outgoing.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-histedit-outgoing.t Thu Aug 14 16:25:47 2014 -0500 @@ -49,6 +49,7 @@ # p, pick = use commit # e, edit = use commit, but stop for amending # f, fold = use commit, but combine it with the one above + # r, roll = like fold, but discard this commit's description # d, drop = remove commit from history # m, mess = edit message without changing commit content # @@ -80,6 +81,7 @@ # p, pick = use commit # e, edit = use commit, but stop for amending # f, fold = use commit, but combine it with the one above + # r, roll = like fold, but discard this commit's description # d, drop = remove commit from history # m, mess = edit message without changing commit content # @@ -103,6 +105,7 @@ # p, pick = use commit # e, edit = use commit, but stop for amending # f, fold = use commit, but combine it with the one above + # r, roll = like fold, but discard this commit's description # d, drop = remove commit from history # m, mess = edit message without changing commit content #
--- a/tests/test-hook.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-hook.t Thu Aug 14 16:25:47 2014 -0500 @@ -210,6 +210,7 @@ $ hg push -B baz ../a pushing to ../a searching for changes + listkeys hook: HG_NAMESPACE=phases HG_VALUES={'cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b': '1', 'publishing': 'True'} no changes found listkeys hook: HG_NAMESPACE=phases HG_VALUES={'cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b': '1', 'publishing': 'True'} listkeys hook: HG_NAMESPACE=bookmarks HG_VALUES={'bar': '0000000000000000000000000000000000000000', 'foo': '0000000000000000000000000000000000000000'}
--- a/tests/test-http-branchmap.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-http-branchmap.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ - $ "$TESTDIR/hghave" killdaemons || exit 80 +#require killdaemons $ hgserve() { > hg serve -a localhost -p $HGPORT1 -d --pid-file=hg.pid \
--- a/tests/test-http-clone-r.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-http-clone-r.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ - $ "$TESTDIR/hghave" serve || exit 80 +#require serve creating 'remote
--- a/tests/test-http-proxy.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-http-proxy.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ - $ "$TESTDIR/hghave" serve || exit 80 +#require serve $ hg init a $ cd a
--- a/tests/test-http.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-http.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ - $ "$TESTDIR/hghave" serve || exit 80 +#require serve $ hg init test $ cd test @@ -261,9 +261,10 @@ "GET /?cmd=listkeys HTTP/1.1" 403 - x-hgarg-1:namespace=namespaces "GET /?cmd=capabilities HTTP/1.1" 200 - "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D7f4e523d01f2cc3765ac8934da3d14db775ff872 + "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=phases + "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases "GET /?cmd=branchmap HTTP/1.1" 200 - "GET /?cmd=branchmap HTTP/1.1" 200 - - "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=bookmarks "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks "POST /?cmd=unbundle HTTP/1.1" 200 - x-hgarg-1:heads=686173686564+5eb5abfefeea63c80dd7553bcc3783f37e0c5524 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases
--- a/tests/test-https.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-https.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,6 +1,6 @@ -Proper https client requires the built-in ssl from Python 2.6. +#require serve ssl - $ "$TESTDIR/hghave" serve ssl || exit 80 +Proper https client requires the built-in ssl from Python 2.6. Certificates created with: printf '.\n.\n.\n.\n.\nlocalhost\nhg@localhost\n' | \
--- a/tests/test-hup.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-hup.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,6 +1,7 @@ +#require serve fifo + Test hangup signal in the middle of transaction - $ "$TESTDIR/hghave" serve fifo || exit 80 $ hg init $ mkfifo p $ hg serve --stdio < p 1>out 2>&1 &
--- a/tests/test-i18n.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-i18n.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,6 +1,6 @@ -Translations are optional: +#require gettext - $ "$TESTDIR/hghave" gettext || exit 80 +(Translations are optional) #if no-outer-repo
--- a/tests/test-identify.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-identify.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ - $ "$TESTDIR/hghave" serve || exit 80 +#require serve #if no-outer-repo
--- a/tests/test-incoming-outgoing.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-incoming-outgoing.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ - $ "$TESTDIR/hghave" serve || exit 80 +#require serve $ hg init test $ cd test
--- a/tests/test-inherit-mode.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-inherit-mode.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,7 +1,6 @@ -test that new files created in .hg inherit the permissions from .hg/store +#require unix-permissions - - $ "$TESTDIR/hghave" unix-permissions || exit 80 +test that new files created in .hg inherit the permissions from .hg/store $ mkdir dir @@ -121,7 +120,6 @@ 00660 ../push/.hg/store/data/dir/bar.i 00660 ../push/.hg/store/data/foo.i 00660 ../push/.hg/store/fncache - 00660 ../push/.hg/store/phaseroots 00660 ../push/.hg/store/undo 00660 ../push/.hg/store/undo.phaseroots 00660 ../push/.hg/undo.bookmarks
--- a/tests/test-issue1438.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-issue1438.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,6 +1,6 @@ -http://mercurial.selenic.com/bts/issue1438 +#require symlink - $ "$TESTDIR/hghave" symlink || exit 80 +http://mercurial.selenic.com/bts/issue1438 $ hg init
--- a/tests/test-issue1802.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-issue1802.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ - $ "$TESTDIR/hghave" execbit || exit 80 +#require execbit Create extension that can disable exec checks:
--- a/tests/test-known.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-known.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ - $ "$TESTDIR/hghave" killdaemons || exit 80 +#require killdaemons = Test the known() protocol function =
--- a/tests/test-largefiles-update.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-largefiles-update.t Thu Aug 14 16:25:47 2014 -0500 @@ -99,4 +99,72 @@ $ cat .hglf/large1 58e24f733a964da346e2407a2bee99d9001184f5 +Test that "hg rollback" restores status of largefiles correctly + + $ hg update -C -q + $ hg remove large1 + $ hg forget large2 + $ echo largeX > largeX + $ hg add --large largeX + $ hg commit -m 'will be rollback-ed soon' + $ echo largeY > largeY + $ hg add --large largeY + $ hg status -A large1 + large1: No such file or directory + $ hg status -A large2 + ? large2 + $ hg status -A largeX + C largeX + $ hg status -A largeY + A largeY + $ hg rollback + repository tip rolled back to revision 3 (undo commit) + working directory now based on revision 3 + $ hg status -A large1 + R large1 + $ hg status -A large2 + R large2 + $ hg status -A largeX + A largeX + $ hg status -A largeY + ? largeY + +Test that "hg status" shows status of largefiles correctly just after +automated commit like rebase/transplant + + $ cat >> .hg/hgrc <<EOF + > [extensions] + > rebase = + > strip = + > transplant = + > EOF + $ hg update -q -C 1 + $ hg remove large1 + $ echo largeX > largeX + $ hg add --large largeX + $ hg commit -m '#4' + + $ hg rebase -s 1 -d 2 --keep + $ hg status -A large1 + large1: No such file or directory + $ hg status -A largeX + C largeX + $ hg strip -q 5 + + $ hg update -q -C 2 + $ hg transplant -q 1 4 + $ hg status -A large1 + large1: No such file or directory + $ hg status -A largeX + C largeX + $ hg strip -q 5 + + $ hg update -q -C 2 + $ hg transplant -q --merge 1 --merge 4 + $ hg status -A large1 + large1: No such file or directory + $ hg status -A largeX + C largeX + $ hg strip -q 5 + $ cd ..
--- a/tests/test-lock-badness.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-lock-badness.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ -#if unix-permissions no-root no-windows +#require unix-permissions no-root no-windows Prepare @@ -39,4 +39,3 @@ [255] $ chmod 700 a/.hg/store -#endif
--- a/tests/test-log.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-log.t Thu Aug 14 16:25:47 2014 -0500 @@ -78,12 +78,52 @@ summary: c --f, directory +-f, non-existent directory $ hg log -f dir abort: cannot follow file not in parent revision: "dir" [255] +-f, directory + + $ hg up -q 3 + $ hg log -f dir + changeset: 2:f8954cd4dc1f + user: test + date: Thu Jan 01 00:00:03 1970 +0000 + summary: c + +-f, directory with --patch + + $ hg log -f dir -p + changeset: 2:f8954cd4dc1f + user: test + date: Thu Jan 01 00:00:03 1970 +0000 + summary: c + + diff -r d89b0a12d229 -r f8954cd4dc1f dir/b + --- /dev/null* (glob) + +++ b/dir/b* (glob) + @@ -0,0 +1,1 @@ + +a + + +-f, pattern + + $ hg log -f -I 'dir**' -p + changeset: 2:f8954cd4dc1f + user: test + date: Thu Jan 01 00:00:03 1970 +0000 + summary: c + + diff -r d89b0a12d229 -r f8954cd4dc1f dir/b + --- /dev/null* (glob) + +++ b/dir/b* (glob) + @@ -0,0 +1,1 @@ + +a + + $ hg up -q 4 + -f, a wrong style $ hg log -f -l1 --style something
--- a/tests/test-merge-tools.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-merge-tools.t Thu Aug 14 16:25:47 2014 -0500 @@ -30,6 +30,14 @@ $ echo "revision 3" >> f $ hg commit -Am "revision 3" created new head + +revision 4 - hard to merge + + $ hg update 0 > /dev/null + $ echo "revision 4" > f + $ hg commit -Am "revision 4" + created new head + $ echo "[merge-tools]" > .hg/hgrc $ beforemerge() { @@ -701,6 +709,77 @@ # hg stat M f +premerge=keep keeps conflict markers in: + + $ beforemerge + [merge-tools] + false.whatever= + true.priority=1 + true.executable=cat + # hg update -C 1 + $ hg merge -r 4 --config merge-tools.true.premerge=keep + merging f + <<<<<<< local: ef83787e2614 - test: revision 1 + revision 1 + space + ======= + revision 4 + >>>>>>> other: 81448d39c9a0 - test: revision 4 + revision 0 + space + revision 4 + 0 files updated, 1 files merged, 0 files removed, 0 files unresolved + (branch merge, don't forget to commit) + $ aftermerge + # cat f + <<<<<<< local: ef83787e2614 - test: revision 1 + revision 1 + space + ======= + revision 4 + >>>>>>> other: 81448d39c9a0 - test: revision 4 + # hg stat + M f + +premerge=keep-merge3 keeps conflict markers with base content: + + $ beforemerge + [merge-tools] + false.whatever= + true.priority=1 + true.executable=cat + # hg update -C 1 + $ hg merge -r 4 --config merge-tools.true.premerge=keep-merge3 + merging f + <<<<<<< local: ef83787e2614 - test: revision 1 + revision 1 + space + ||||||| base + revision 0 + space + ======= + revision 4 + >>>>>>> other: 81448d39c9a0 - test: revision 4 + revision 0 + space + revision 4 + 0 files updated, 1 files merged, 0 files removed, 0 files unresolved + (branch merge, don't forget to commit) + $ aftermerge + # cat f + <<<<<<< local: ef83787e2614 - test: revision 1 + revision 1 + space + ||||||| base + revision 0 + space + ======= + revision 4 + >>>>>>> other: 81448d39c9a0 - test: revision 4 + # hg stat + M f + + Tool execution set tools.args explicit to include $base $local $other $output: @@ -832,17 +911,17 @@ true.priority=1 true.executable=cat # hg update -C 1 - $ echo "revision 4" > '"; exit 1; echo "' - $ hg commit -Am "revision 4" - adding "; exit 1; echo " - warning: filename contains '"', which is reserved on Windows: '"; exit 1; echo "' - $ hg update -C 1 > /dev/null $ echo "revision 5" > '"; exit 1; echo "' $ hg commit -Am "revision 5" adding "; exit 1; echo " warning: filename contains '"', which is reserved on Windows: '"; exit 1; echo "' + $ hg update -C 1 > /dev/null + $ echo "revision 6" > '"; exit 1; echo "' + $ hg commit -Am "revision 6" + adding "; exit 1; echo " + warning: filename contains '"', which is reserved on Windows: '"; exit 1; echo "' created new head - $ hg merge --config merge-tools.true.executable="true" -r 4 + $ hg merge --config merge-tools.true.executable="true" -r 5 merging "; exit 1; echo " 0 files updated, 1 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit)
--- a/tests/test-merge-types.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-merge-types.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ - $ "$TESTDIR/hghave" symlink execbit || exit 80 +#require symlink execbit $ tellmeabout() { > if [ -h $1 ]; then
--- a/tests/test-mq-qclone-http.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-mq-qclone-http.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ - $ "$TESTDIR/hghave" killdaemons || exit 80 +#require killdaemons hide outer repo $ hg init
--- a/tests/test-mq-qimport.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-mq-qimport.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ - $ "$TESTDIR/hghave" killdaemons || exit 80 +#require killdaemons $ cat > writelines.py <<EOF > import sys
--- a/tests/test-mq-qrefresh-interactive.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-mq-qrefresh-interactive.t Thu Aug 14 16:25:47 2014 -0500 @@ -29,7 +29,7 @@ Returns 0 on success. - options: + options ([+] can be repeated): -e --edit invoke editor on commit messages -g --git use git extended diff format @@ -44,9 +44,7 @@ -m --message TEXT use text as commit message -l --logfile FILE read commit message from file - [+] marked option can be specified multiple times - - use "hg -v help qrefresh" to show the global options + (some details hidden, use --verbose to show complete help) help qrefresh (record) @@ -73,7 +71,7 @@ Returns 0 on success. - options: + options ([+] can be repeated): -e --edit invoke editor on commit messages -g --git use git extended diff format @@ -89,9 +87,7 @@ -l --logfile FILE read commit message from file -i --interactive interactively select changes to refresh - [+] marked option can be specified multiple times - - use "hg -v help qrefresh" to show the global options + (some details hidden, use --verbose to show complete help) $ hg init a $ cd a
--- a/tests/test-mq-qrefresh-replace-log-message.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-mq-qrefresh-replace-log-message.t Thu Aug 14 16:25:47 2014 -0500 @@ -32,17 +32,19 @@ $ cat >> .hg/hgrc <<EOF > [committemplate] + > listupfiles = {file_adds % + > "HG: added {file}\n" }{file_mods % + > "HG: changed {file}\n" }{file_dels % + > "HG: removed {file}\n" }{if(files, "", + > "HG: no files changed\n")} + > > changeset = HG: this is customized commit template > {desc}\n\n > HG: Enter commit message. Lines beginning with 'HG:' are removed. > HG: {extramsg} > HG: -- > HG: user: {author} - > HG: branch '{branch}'\n{file_adds % - > "HG: added {file}\n" }{file_mods % - > "HG: changed {file}\n" }{file_dels % - > "HG: removed {file}\n" }{if(files, "", - > "HG: no files changed\n")} + > HG: branch '{branch}'\n{listupfiles} > EOF $ echo bbbb > file
--- a/tests/test-mq-subrepo-svn.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-mq-subrepo-svn.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ - $ "$TESTDIR/hghave" svn13 || exit 80 +#require svn13 $ echo "[extensions]" >> $HGRCPATH $ echo "mq=" >> $HGRCPATH
--- a/tests/test-mq-symlinks.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-mq-symlinks.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ - $ "$TESTDIR/hghave" symlink || exit 80 +#require symlink $ echo "[extensions]" >> $HGRCPATH $ echo "mq=" >> $HGRCPATH
--- a/tests/test-mq.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-mq.t Thu Aug 14 16:25:47 2014 -0500 @@ -95,7 +95,7 @@ qtop print the name of the current patch qunapplied print the patches not yet applied - use "hg -v help mq" to show builtin aliases and global options + (use "hg help -v mq" to show built-in aliases and global options) $ hg init a $ cd a
--- a/tests/test-newcgi.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-newcgi.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ - $ "$TESTDIR/hghave" no-msys || exit 80 # MSYS will translate web paths as if they were file paths +#require no-msys # MSYS will translate web paths as if they were file paths This tests if CGI files from after d0db3462d568 but before d74fc8dec2b4 still work.
--- a/tests/test-newercgi.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-newercgi.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ - $ "$TESTDIR/hghave" no-msys || exit 80 # MSYS will translate web paths as if they were file paths +#require no-msys # MSYS will translate web paths as if they were file paths This is a rudimentary test of the CGI files as of d74fc8dec2b4.
--- a/tests/test-no-symlinks.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-no-symlinks.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ - $ "$TESTDIR/hghave" no-symlink || exit 80 +#require no-symlink # The following script was used to create the bundle: #
--- a/tests/test-obsolete.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-obsolete.t Thu Aug 14 16:25:47 2014 -0500 @@ -2,6 +2,8 @@ > [phases] > # public changeset are not obsolete > publish=false + > [ui] + > logtemplate="{rev}:{node|short} ({phase}) [{tags} {bookmarks}] {desc|firstline}\n" > EOF $ mkcommit() { > echo "$1" > "$1" @@ -58,11 +60,7 @@ $ hg up null --quiet # having 0 as parent prevents it to be hidden $ hg tip - changeset: -1:000000000000 - tag: tip - user: - date: Thu Jan 01 00:00:00 1970 +0000 - + -1:000000000000 (public) [tip ] $ hg up --hidden tip --quiet $ cd .. @@ -125,59 +123,22 @@ Check that graphlog detect that a changeset is obsolete: $ hg log -G - @ changeset: 5:5601fb93a350 - | tag: tip - | parent: 1:7c3bad9141dc - | user: test - | date: Thu Jan 01 00:00:00 1970 +0000 - | summary: add new_3_c + @ 5:5601fb93a350 (draft) [tip ] add new_3_c | - o changeset: 1:7c3bad9141dc - | user: test - | date: Thu Jan 01 00:00:00 1970 +0000 - | summary: add b + o 1:7c3bad9141dc (draft) [ ] add b | - o changeset: 0:1f0dee641bb7 - user: test - date: Thu Jan 01 00:00:00 1970 +0000 - summary: add a + o 0:1f0dee641bb7 (draft) [ ] add a check that heads does not report them $ hg heads - changeset: 5:5601fb93a350 - tag: tip - parent: 1:7c3bad9141dc - user: test - date: Thu Jan 01 00:00:00 1970 +0000 - summary: add new_3_c - + 5:5601fb93a350 (draft) [tip ] add new_3_c $ hg heads --hidden - changeset: 5:5601fb93a350 - tag: tip - parent: 1:7c3bad9141dc - user: test - date: Thu Jan 01 00:00:00 1970 +0000 - summary: add new_3_c - - changeset: 4:ca819180edb9 - parent: 1:7c3bad9141dc - user: test - date: Thu Jan 01 00:00:00 1970 +0000 - summary: add new_2_c - - changeset: 3:cdbce2fbb163 - parent: 1:7c3bad9141dc - user: test - date: Thu Jan 01 00:00:00 1970 +0000 - summary: add new_c - - changeset: 2:245bde4270cd - user: test - date: Thu Jan 01 00:00:00 1970 +0000 - summary: add original_c - + 5:5601fb93a350 (draft) [tip ] add new_3_c + 4:ca819180edb9 (draft) [ ] add new_2_c + 3:cdbce2fbb163 (draft) [ ] add new_c + 2:245bde4270cd (draft) [ ] add original_c check that summary does not report them @@ -204,13 +165,7 @@ check that various commands work well with filtering $ hg tip - changeset: 5:5601fb93a350 - tag: tip - parent: 1:7c3bad9141dc - user: test - date: Thu Jan 01 00:00:00 1970 +0000 - summary: add new_3_c - + 5:5601fb93a350 (draft) [tip ] add new_3_c $ hg log -r 6 abort: unknown revision '6'! [255] @@ -222,27 +177,13 @@ $ hg --hidden phase --public 2 $ hg log -G - @ changeset: 5:5601fb93a350 - | tag: tip - | parent: 1:7c3bad9141dc - | user: test - | date: Thu Jan 01 00:00:00 1970 +0000 - | summary: add new_3_c + @ 5:5601fb93a350 (draft) [tip ] add new_3_c | - | o changeset: 2:245bde4270cd - |/ user: test - | date: Thu Jan 01 00:00:00 1970 +0000 - | summary: add original_c + | o 2:245bde4270cd (public) [ ] add original_c + |/ + o 1:7c3bad9141dc (public) [ ] add b | - o changeset: 1:7c3bad9141dc - | user: test - | date: Thu Jan 01 00:00:00 1970 +0000 - | summary: add b - | - o changeset: 0:1f0dee641bb7 - user: test - date: Thu Jan 01 00:00:00 1970 +0000 - summary: add a + o 0:1f0dee641bb7 (public) [ ] add a And that bumped changeset are detected @@ -253,13 +194,7 @@ the public changeset $ hg log --hidden -r 'bumped()' - changeset: 5:5601fb93a350 - tag: tip - parent: 1:7c3bad9141dc - user: test - date: Thu Jan 01 00:00:00 1970 +0000 - summary: add new_3_c - + 5:5601fb93a350 (draft) [tip ] add new_3_c And that we can't push bumped changeset @@ -289,27 +224,13 @@ $ hg debugobsolete -d '1338 0' --flags 1 `getid new_3_c` `getid n3w_3_c` $ hg log -r 'bumped()' $ hg log -G - @ changeset: 6:6f9641995072 - | tag: tip - | parent: 1:7c3bad9141dc - | user: test - | date: Thu Jan 01 00:00:00 1970 +0000 - | summary: add n3w_3_c + @ 6:6f9641995072 (draft) [tip ] add n3w_3_c | - | o changeset: 2:245bde4270cd - |/ user: test - | date: Thu Jan 01 00:00:00 1970 +0000 - | summary: add original_c + | o 2:245bde4270cd (public) [ ] add original_c + |/ + o 1:7c3bad9141dc (public) [ ] add b | - o changeset: 1:7c3bad9141dc - | user: test - | date: Thu Jan 01 00:00:00 1970 +0000 - | summary: add b - | - o changeset: 0:1f0dee641bb7 - user: test - date: Thu Jan 01 00:00:00 1970 +0000 - summary: add a + o 0:1f0dee641bb7 (public) [ ] add a @@ -328,28 +249,10 @@ $ cd tmpc $ hg incoming ../tmpb comparing with ../tmpb - changeset: 0:1f0dee641bb7 - user: test - date: Thu Jan 01 00:00:00 1970 +0000 - summary: add a - - changeset: 1:7c3bad9141dc - user: test - date: Thu Jan 01 00:00:00 1970 +0000 - summary: add b - - changeset: 2:245bde4270cd - user: test - date: Thu Jan 01 00:00:00 1970 +0000 - summary: add original_c - - changeset: 6:6f9641995072 - tag: tip - parent: 1:7c3bad9141dc - user: test - date: Thu Jan 01 00:00:00 1970 +0000 - summary: add n3w_3_c - + 0:1f0dee641bb7 (public) [ ] add a + 1:7c3bad9141dc (public) [ ] add b + 2:245bde4270cd (public) [ ] add original_c + 6:6f9641995072 (draft) [tip ] add n3w_3_c Try to pull markers (extinct changeset are excluded but marker are pushed) @@ -414,6 +317,7 @@ $ hg init empty $ hg --config extensions.debugkeys=debugkeys.py -R empty push tmpd pushing to tmpd + listkeys phases no changes found listkeys phases listkeys bookmarks @@ -426,45 +330,19 @@ updating to branch default 3 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg -R clone-dest log -G --hidden - @ changeset: 6:6f9641995072 - | tag: tip - | parent: 1:7c3bad9141dc - | user: test - | date: Thu Jan 01 00:00:00 1970 +0000 - | summary: add n3w_3_c - | - | x changeset: 5:5601fb93a350 - |/ parent: 1:7c3bad9141dc - | user: test - | date: Thu Jan 01 00:00:00 1970 +0000 - | summary: add new_3_c - | - | x changeset: 4:ca819180edb9 - |/ parent: 1:7c3bad9141dc - | user: test - | date: Thu Jan 01 00:00:00 1970 +0000 - | summary: add new_2_c + @ 6:6f9641995072 (draft) [tip ] add n3w_3_c | - | x changeset: 3:cdbce2fbb163 - |/ parent: 1:7c3bad9141dc - | user: test - | date: Thu Jan 01 00:00:00 1970 +0000 - | summary: add new_c + | x 5:5601fb93a350 (draft) [ ] add new_3_c + |/ + | x 4:ca819180edb9 (draft) [ ] add new_2_c + |/ + | x 3:cdbce2fbb163 (draft) [ ] add new_c + |/ + | o 2:245bde4270cd (public) [ ] add original_c + |/ + o 1:7c3bad9141dc (public) [ ] add b | - | o changeset: 2:245bde4270cd - |/ user: test - | date: Thu Jan 01 00:00:00 1970 +0000 - | summary: add original_c - | - o changeset: 1:7c3bad9141dc - | user: test - | date: Thu Jan 01 00:00:00 1970 +0000 - | summary: add b - | - o changeset: 0:1f0dee641bb7 - user: test - date: Thu Jan 01 00:00:00 1970 +0000 - summary: add a + o 0:1f0dee641bb7 (public) [ ] add a $ hg -R clone-dest debugobsolete 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C {'date': '56 12', 'user': 'test'} @@ -519,27 +397,13 @@ $ hg log -G - o changeset: 3:6f9641995072 - | tag: tip - | parent: 1:7c3bad9141dc - | user: test - | date: Thu Jan 01 00:00:00 1970 +0000 - | summary: add n3w_3_c + o 3:6f9641995072 (draft) [tip ] add n3w_3_c | - | o changeset: 2:245bde4270cd - |/ user: test - | date: Thu Jan 01 00:00:00 1970 +0000 - | summary: add original_c + | o 2:245bde4270cd (public) [ ] add original_c + |/ + o 1:7c3bad9141dc (public) [ ] add b | - o changeset: 1:7c3bad9141dc - | user: test - | date: Thu Jan 01 00:00:00 1970 +0000 - | summary: add b - | - o changeset: 0:1f0dee641bb7 - user: test - date: Thu Jan 01 00:00:00 1970 +0000 - summary: add a + o 0:1f0dee641bb7 (public) [ ] add a $ hg up 'desc("n3w_3_c")' 3 files updated, 0 files merged, 0 files removed, 0 files unresolved @@ -547,38 +411,17 @@ $ mkcommit original_e $ hg debugobsolete `getid original_d` -d '0 0' $ hg log -r 'obsolete()' - changeset: 4:94b33453f93b - user: test - date: Thu Jan 01 00:00:00 1970 +0000 - summary: add original_d - + 4:94b33453f93b (draft) [ ] add original_d $ hg log -G -r '::unstable()' - @ changeset: 5:cda648ca50f5 - | tag: tip - | user: test - | date: Thu Jan 01 00:00:00 1970 +0000 - | summary: add original_e + @ 5:cda648ca50f5 (draft) [tip ] add original_e + | + x 4:94b33453f93b (draft) [ ] add original_d | - x changeset: 4:94b33453f93b - | user: test - | date: Thu Jan 01 00:00:00 1970 +0000 - | summary: add original_d + o 3:6f9641995072 (draft) [ ] add n3w_3_c | - o changeset: 3:6f9641995072 - | parent: 1:7c3bad9141dc - | user: test - | date: Thu Jan 01 00:00:00 1970 +0000 - | summary: add n3w_3_c + o 1:7c3bad9141dc (public) [ ] add b | - o changeset: 1:7c3bad9141dc - | user: test - | date: Thu Jan 01 00:00:00 1970 +0000 - | summary: add b - | - o changeset: 0:1f0dee641bb7 - user: test - date: Thu Jan 01 00:00:00 1970 +0000 - summary: add a + o 0:1f0dee641bb7 (public) [ ] add a refuse to push obsolete changeset @@ -607,38 +450,12 @@ $ hg out ../tmpf comparing with ../tmpf searching for changes - changeset: 0:1f0dee641bb7 - user: test - date: Thu Jan 01 00:00:00 1970 +0000 - summary: add a - - changeset: 1:7c3bad9141dc - user: test - date: Thu Jan 01 00:00:00 1970 +0000 - summary: add b - - changeset: 2:245bde4270cd - user: test - date: Thu Jan 01 00:00:00 1970 +0000 - summary: add original_c - - changeset: 3:6f9641995072 - parent: 1:7c3bad9141dc - user: test - date: Thu Jan 01 00:00:00 1970 +0000 - summary: add n3w_3_c - - changeset: 4:94b33453f93b - user: test - date: Thu Jan 01 00:00:00 1970 +0000 - summary: add original_d - - changeset: 5:cda648ca50f5 - tag: tip - user: test - date: Thu Jan 01 00:00:00 1970 +0000 - summary: add original_e - + 0:1f0dee641bb7 (public) [ ] add a + 1:7c3bad9141dc (public) [ ] add b + 2:245bde4270cd (public) [ ] add original_c + 3:6f9641995072 (draft) [ ] add n3w_3_c + 4:94b33453f93b (draft) [ ] add original_d + 5:cda648ca50f5 (draft) [tip ] add original_e $ hg push ../tmpf -f # -f because be push unstable too pushing to ../tmpf searching for changes @@ -658,37 +475,17 @@ Do not warn about new head when the new head is a successors of a remote one $ hg log -G - @ changeset: 5:cda648ca50f5 - | tag: tip - | user: test - | date: Thu Jan 01 00:00:00 1970 +0000 - | summary: add original_e + @ 5:cda648ca50f5 (draft) [tip ] add original_e | - x changeset: 4:94b33453f93b - | user: test - | date: Thu Jan 01 00:00:00 1970 +0000 - | summary: add original_d + x 4:94b33453f93b (draft) [ ] add original_d + | + o 3:6f9641995072 (draft) [ ] add n3w_3_c | - o changeset: 3:6f9641995072 - | parent: 1:7c3bad9141dc - | user: test - | date: Thu Jan 01 00:00:00 1970 +0000 - | summary: add n3w_3_c + | o 2:245bde4270cd (public) [ ] add original_c + |/ + o 1:7c3bad9141dc (public) [ ] add b | - | o changeset: 2:245bde4270cd - |/ user: test - | date: Thu Jan 01 00:00:00 1970 +0000 - | summary: add original_c - | - o changeset: 1:7c3bad9141dc - | user: test - | date: Thu Jan 01 00:00:00 1970 +0000 - | summary: add b - | - o changeset: 0:1f0dee641bb7 - user: test - date: Thu Jan 01 00:00:00 1970 +0000 - summary: add a + o 0:1f0dee641bb7 (public) [ ] add a $ hg up -q 'desc(n3w_3_c)' $ mkcommit obsolete_e @@ -697,13 +494,7 @@ $ hg outgoing ../tmpf # parasite hg outgoing testin comparing with ../tmpf searching for changes - changeset: 6:3de5eca88c00 - tag: tip - parent: 3:6f9641995072 - user: test - date: Thu Jan 01 00:00:00 1970 +0000 - summary: add obsolete_e - + 6:3de5eca88c00 (draft) [tip ] add obsolete_e $ hg push ../tmpf pushing to ../tmpf searching for changes @@ -773,13 +564,7 @@ $ echo "obs=!" >> $HGRCPATH $ hg log -r tip obsolete feature not enabled but 68 markers found! - changeset: 68:c15e9edfca13 - tag: tip - parent: 7:50c51b361e60 - user: test - date: Thu Jan 01 00:00:00 1970 +0000 - summary: add celestine - + 68:c15e9edfca13 (draft) [tip ] add celestine reenable for later test @@ -805,40 +590,19 @@ $ hg ci --amend $ cd ../other-issue3805 $ hg log -G - @ changeset: 0:193e9254ce7e - tag: tip - user: test - date: Thu Jan 01 00:00:00 1970 +0000 - summary: A + @ 0:193e9254ce7e (draft) [tip ] A $ hg log -G -R ../repo-issue3805 - @ changeset: 2:3816541e5485 - tag: tip - parent: -1:000000000000 - user: test - date: Thu Jan 01 00:00:00 1970 +0000 - summary: A + @ 2:3816541e5485 (draft) [tip ] A $ hg incoming comparing with $TESTTMP/tmpe/repo-issue3805 (glob) searching for changes - changeset: 2:3816541e5485 - tag: tip - parent: -1:000000000000 - user: test - date: Thu Jan 01 00:00:00 1970 +0000 - summary: A - + 2:3816541e5485 (draft) [tip ] A $ hg incoming --bundle ../issue3805.hg comparing with $TESTTMP/tmpe/repo-issue3805 (glob) searching for changes - changeset: 2:3816541e5485 - tag: tip - parent: -1:000000000000 - user: test - date: Thu Jan 01 00:00:00 1970 +0000 - summary: A - + 2:3816541e5485 (draft) [tip ] A $ hg outgoing comparing with $TESTTMP/tmpe/repo-issue3805 (glob) searching for changes @@ -853,13 +617,7 @@ $ hg incoming http://localhost:$HGPORT comparing with http://localhost:$HGPORT/ searching for changes - changeset: 1:3816541e5485 - tag: tip - parent: -1:000000000000 - user: test - date: Thu Jan 01 00:00:00 1970 +0000 - summary: A - + 1:3816541e5485 (public) [tip ] A $ hg outgoing http://localhost:$HGPORT comparing with http://localhost:$HGPORT/ searching for changes @@ -894,18 +652,9 @@ $ hg tag -l visible -r 0 --hidden $ hg log -G - @ changeset: 2:3816541e5485 - tag: tip - parent: -1:000000000000 - user: test - date: Thu Jan 01 00:00:00 1970 +0000 - summary: A + @ 2:3816541e5485 (draft) [tip ] A - x changeset: 0:193e9254ce7e - tag: visible - user: test - date: Thu Jan 01 00:00:00 1970 +0000 - summary: A + x 0:193e9254ce7e (draft) [visible ] A Test that removing a local tag does not cause some commands to fail
--- a/tests/test-oldcgi.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-oldcgi.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ - $ "$TESTDIR/hghave" no-msys || exit 80 # MSYS will translate web paths as if they were file paths +#require no-msys # MSYS will translate web paths as if they were file paths This tests if CGI files from before d0db3462d568 still work.
--- a/tests/test-patchbomb.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-patchbomb.t Thu Aug 14 16:25:47 2014 -0500 @@ -8,6 +8,21 @@ --===+[0-9]+=+--$ -> --===*=-- (glob) --===+[0-9]+=+$ -> --===*= (glob) + $ cat > prune-blank-after-boundary.py <<EOF + > import sys + > skipblank = False + > trim = lambda x: x.strip(' \r\n') + > for l in sys.stdin: + > if trim(l).endswith('=--') or trim(l).endswith('=='): + > skipblank = True + > print l, + > continue + > if not trim(l) and skipblank: + > continue + > skipblank = False + > print l, + > EOF + $ FILTERBOUNDARY="python `pwd`/prune-blank-after-boundary.py" $ echo "[extensions]" >> $HGRCPATH $ echo "patchbomb=" >> $HGRCPATH @@ -214,7 +229,7 @@ test bundle and description: $ hg email --date '1970-1-1 0:3' -n -f quux -t foo \ - > -c bar -s test -r tip -b --desc description + > -c bar -s test -r tip -b --desc description | $FILTERBOUNDARY searching for changes 1 changesets found @@ -689,7 +704,7 @@ test inline for single patch: - $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -i -r 2 + $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -i -r 2 | $FILTERBOUNDARY this patch series consists of 1 patches. @@ -732,7 +747,7 @@ test inline for single patch (quoted-printable): - $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -i -r 4 + $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -i -r 4 | $FILTERBOUNDARY this patch series consists of 1 patches. @@ -791,7 +806,7 @@ test inline for multiple patches: $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -i \ - > -r 0:1 -r 4 + > -r 0:1 -r 4 | $FILTERBOUNDARY this patch series consists of 3 patches. @@ -943,7 +958,7 @@ --===*=-- (glob) test attach for single patch: - $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -a -r 2 + $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -a -r 2 | $FILTERBOUNDARY this patch series consists of 1 patches. @@ -994,7 +1009,7 @@ --===*=-- (glob) test attach for single patch (quoted-printable): - $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -a -r 4 + $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -a -r 4 | $FILTERBOUNDARY this patch series consists of 1 patches. @@ -1061,7 +1076,7 @@ --===*=-- (glob) test attach and body for single patch: - $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -a --body -r 2 + $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -a --body -r 2 | $FILTERBOUNDARY this patch series consists of 1 patches. @@ -1123,7 +1138,7 @@ test attach for multiple patches: $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -a \ - > -r 0:1 -r 4 + > -r 0:1 -r 4 | $FILTERBOUNDARY this patch series consists of 3 patches. @@ -1579,7 +1594,8 @@ $ hg tag -r2 two two.diff test inline for single named patch: - $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -i -r 2 + $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -i \ + > -r 2 | $FILTERBOUNDARY this patch series consists of 1 patches. @@ -1621,7 +1637,8 @@ --===*=-- (glob) test inline for multiple named/unnamed patches: - $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -i -r 0:1 + $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -i \ + > -r 0:1 | $FILTERBOUNDARY this patch series consists of 2 patches. @@ -1927,7 +1944,7 @@ $ hg up -qr1 $ echo dirt > a $ hg email --date '1970-1-1 0:1' -n --flag fooFlag -f quux -t foo -c bar -s test \ - > -r 2 + > -r 2 | $FILTERBOUNDARY this patch series consists of 1 patches.
--- a/tests/test-permissions.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-permissions.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ -#if unix-permissions no-root +#require unix-permissions no-root $ hg init t $ cd t @@ -70,5 +70,3 @@ $ chmod +rx dir $ cd .. - -#endif
--- a/tests/test-phases-exchange.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-phases-exchange.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ - $ "$TESTDIR/hghave" killdaemons || exit 80 +#require killdaemons $ hgph() { hg log -G --template "{rev} {phase} {desc} - {node|short}\n" $*; }
--- a/tests/test-pull-http.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-pull-http.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ - $ "$TESTDIR/hghave" killdaemons || exit 80 +#require killdaemons $ hg init test $ cd test
--- a/tests/test-pull-permission.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-pull-permission.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ -#if unix-permissions no-root +#require unix-permissions no-root $ hg init a $ cd a @@ -30,5 +30,3 @@ 1 files, 1 changesets, 1 total revisions $ cd .. - -#endif
--- a/tests/test-pull.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-pull.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ - $ "$TESTDIR/hghave" serve || exit 80 +#require serve $ hg init test $ cd test
--- a/tests/test-push-cgi.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-push-cgi.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ - $ "$TESTDIR/hghave" no-msys || exit 80 # MSYS will translate web paths as if they were file paths +#require no-msys # MSYS will translate web paths as if they were file paths This is a test of the push wire protocol over CGI-based hgweb.
--- a/tests/test-push-http.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-push-http.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ - $ "$TESTDIR/hghave" killdaemons || exit 80 +#require killdaemons $ hg init test $ cd test
--- a/tests/test-push-warn.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-push-warn.t Thu Aug 14 16:25:47 2014 -0500 @@ -35,6 +35,7 @@ searching: 2 queries query 2; still undecided: 1, sample size is: 1 2 total queries + listing keys for "phases" listing keys for "bookmarks" remote has heads on branch 'default' that are not known locally: 1c9246a22a0a new remote heads on branch 'default':
--- a/tests/test-qrecord.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-qrecord.t Thu Aug 14 16:25:47 2014 -0500 @@ -9,7 +9,7 @@ record extension - commands to interactively select changes for commit/qrefresh - use "hg help extensions" for information on enabling extensions + (use "hg help extensions" for information on enabling extensions) help qrecord (no record) @@ -18,7 +18,7 @@ record commands to interactively select changes for commit/qrefresh - use "hg help extensions" for information on enabling extensions + (use "hg help extensions" for information on enabling extensions) $ echo "[extensions]" >> $HGRCPATH $ echo "record=" >> $HGRCPATH @@ -54,7 +54,7 @@ This command is not available when committing a merge. - options: + options ([+] can be repeated): -A --addremove mark new/missing files as added/removed before committing @@ -74,9 +74,7 @@ -b --ignore-space-change ignore changes in the amount of white space -B --ignore-blank-lines ignore changes whose lines are all blank - [+] marked option can be specified multiple times - - use "hg -v help record" to show the global options + (some details hidden, use --verbose to show complete help) help (no mq, so no qrecord) @@ -87,7 +85,7 @@ See "hg help qnew" & "hg help record" for more information and usage. - use "hg -v help qrecord" to show the global options + (some details hidden, use --verbose to show complete help) $ hg init a @@ -99,7 +97,7 @@ interactively record a new patch - use "hg help qrecord" to show the full help text + (use "hg qrecord -h" to show more help) [255] qrecord patch (mq not present) @@ -119,7 +117,7 @@ See "hg help qnew" & "hg help record" for more information and usage. - use "hg -v help qrecord" to show the global options + (some details hidden, use --verbose to show complete help) help (mq present) @@ -133,7 +131,7 @@ See "hg help qnew" & "hg help record" for more information and usage. - options: + options ([+] can be repeated): -e --edit invoke editor on commit messages -g --git use git extended diff format @@ -150,9 +148,7 @@ -B --ignore-blank-lines ignore changes whose lines are all blank --mq operate on patch repository - [+] marked option can be specified multiple times - - use "hg -v help qrecord" to show the global options + (some details hidden, use --verbose to show complete help) $ cd a
--- a/tests/test-relink.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-relink.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ - $ "$TESTDIR/hghave" hardlink || exit 80 +#require hardlink $ echo "[extensions]" >> $HGRCPATH $ echo "relink=" >> $HGRCPATH
--- a/tests/test-repair-strip.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-repair-strip.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ -#if unix-permissions no-root +#require unix-permissions no-root $ echo "[extensions]" >> $HGRCPATH $ echo "mq=">> $HGRCPATH @@ -130,5 +130,3 @@ 2 files, 2 changesets, 2 total revisions $ cd .. - -#endif
--- a/tests/test-revert-flags.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-revert-flags.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ - $ "$TESTDIR/hghave" execbit || exit 80 +#require execbit $ hg init repo $ cd repo
--- a/tests/test-revert.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-revert.t Thu Aug 14 16:25:47 2014 -0500 @@ -14,101 +14,94 @@ [255] $ hg revert --all - $ echo 123 > b +Introduce some changes and revert them +-------------------------------------- -should show b unknown + $ echo 123 > b $ hg status ? b $ echo 12 > c -should show b unknown and c modified - $ hg status M c ? b $ hg add b -should show b added and c modified - $ hg status M c A b $ hg rm a -should show a removed, b added and c modified - $ hg status M c A b R a - $ hg revert a -should show b added, copy saved, and c modified +revert removal of a file + $ hg revert a $ hg status M c A b - $ hg revert b -should show b unknown, and c modified +revert addition of a file + $ hg revert b $ hg status M c ? b - $ hg revert --no-backup c -should show unknown: b +revert modification of a file (--no-backup) + $ hg revert --no-backup c $ hg status ? b - $ hg add b -should show b added +revert deletion (! status) of a added file +------------------------------------------ + + $ hg add b $ hg status b A b $ rm b - -should show b deleted - $ hg status b ! b $ hg revert -v b forgetting b - -should not find b - $ hg status b b: * (glob) -should show a c e - $ ls a c e -should verbosely save backup to e.orig +Test creation of backup (.orig) files +------------------------------------- $ echo z > e $ hg revert --all -v saving current version of e as e.orig reverting e -should say no changes needed +revert on clean file (no change) +-------------------------------- $ hg revert a no changes needed to a -should say file not managed +revert on an untracked file +--------------------------- $ echo q > q $ hg revert q file not managed: q $ rm q -should say file not found +revert on file that does not exists +----------------------------------- $ hg revert notfound notfound: no such file in rev 334a9e57682c @@ -122,21 +115,26 @@ A z ? e.orig -should add a, remove d, forget z +revert to another revision (--rev) +---------------------------------- $ hg revert --all -r0 adding a removing d forgetting z -should forget a, undelete d +revert explicitly to parent (--rev) +----------------------------------- $ hg revert --all -rtip forgetting a undeleting d $ rm a *.orig -should silently add a +revert to another revision (--rev) and exact match +-------------------------------------------------- + +exact match are more silent $ hg revert -r0 a $ hg st a @@ -145,21 +143,24 @@ $ hg st d R d -should silently keep d removed +should keep d removed $ hg revert -r0 d + no changes needed to d $ hg st d R d $ hg update -C 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + +revert of exec bit +------------------ + #if execbit $ chmod +x c $ hg revert --all reverting c -should print non-executable - $ test -x c || echo non-executable non-executable @@ -170,8 +171,6 @@ $ hg revert --all reverting c -should print executable - $ test -x c && echo executable executable #endif @@ -180,6 +179,7 @@ Issue241: update and revert produces inconsistent repositories +-------------------------------------------------------------- $ hg init a $ cd a @@ -193,20 +193,23 @@ $ mkdir b $ echo b > b/b -should fail - no arguments +call `hg revert` with no file specified +--------------------------------------- $ hg revert -rtip abort: no files or directories specified (use --all to revert all files, or 'hg update 1' to update) [255] -should succeed +call `hg revert` with --all +--------------------------- $ hg revert --all -rtip reverting a Issue332: confusing message when reverting directory +---------------------------------------------------- $ hg ci -A -m b adding b/b @@ -224,6 +227,7 @@ reverting a rename target should revert the source +-------------------------------------------------- $ hg mv a newa $ hg revert newa @@ -258,6 +262,7 @@ $ hg rm removed ignoreddir/removed should revert ignored* and undelete *removed +-------------------------------------------- $ hg revert -a --no-backup reverting ignored @@ -271,10 +276,14 @@ $ hg rm removed should silently revert the named files +-------------------------------------- $ hg revert --no-backup ignored removed $ hg st -mardi +Reverting copy (issue3920) +-------------------------- + someone set up us the copies $ rm .hgignore @@ -300,8 +309,9 @@ R ignored Test revert of a file added by one side of the merge +==================================================== -(remove any pending change) +remove any pending change $ hg revert --all forgetting allyour @@ -309,7 +319,7 @@ undeleting ignored $ hg purge --all --config extensions.purge= -(Adds a new commit) +Adds a new commit $ echo foo > newadd $ hg add newadd @@ -317,7 +327,7 @@ created new head -(merge it with the other head) +merge it with the other head $ hg merge # merge 1 into 2 2 files updated, 0 files merged, 1 files removed, 0 files unresolved @@ -331,7 +341,7 @@ commit: 2 modified, 1 removed (merge) update: (current) -(clarifies who added what) +clarifies who added what $ hg status M allyour @@ -344,7 +354,8 @@ A base R ignored -(revert file added by p1() to p1() state) +revert file added by p1() to p1() state +----------------------------------------- $ hg revert -r 'p1()' 'glob:newad?' $ hg status @@ -352,7 +363,8 @@ M base R ignored -(revert file added by p1() to p2() state) +revert file added by p1() to p2() state +------------------------------------------ $ hg revert -r 'p2()' 'glob:newad?' removing newadd @@ -362,7 +374,8 @@ R ignored R newadd -(revert file added by p2() to p2() state) +revert file added by p2() to p2() state +------------------------------------------ $ hg revert -r 'p2()' 'glob:allyou?' $ hg status @@ -371,7 +384,8 @@ R ignored R newadd -(revert file added by p2() to p1() state) +revert file added by p2() to p1() state +------------------------------------------ $ hg revert -r 'p1()' 'glob:allyou?' removing allyour @@ -381,4 +395,821 @@ R ignored R newadd +Systematic behavior validation of most possible cases +===================================================== +This section tests most of the possible combinations of working directory +changes and inter-revision changes. The number of possible cases is significant +but they all have a slighly different handling. So this section commits to +generating and testing all of them to allow safe refactoring of the revert code. + +A python script is used to generate a file history for each combination of +changes between, on one side the working directory and its parent and on +the other side, changes between a revert target (--rev) and working directory +parent. The three states generated are: + +- a "base" revision +- a "parent" revision +- the working directory (based on "parent") + +The file generated have names of the form: + + <changeset-state>_<working-copy-state> + +Here, "changeset-state" conveys the state in "base" and "parent" (or the change +that happen between them), "working-copy-state" is self explanatory. + +All known states are not tested yet. See inline documentation for details. +Special cases from merge and rename are not tested by this section. + +There are also multiple cases where the current revert implementation is known to +slightly misbehave. + +Write the python script to disk +------------------------------- + + $ cat << EOF > gen-revert-cases.py + > # generate proper file state to test revert behavior + > import sys + > import os + > + > # content of the file in "base" and "parent" + > # None means no file at all + > ctxcontent = { + > # clean: no change from base to parent + > 'clean': ['base', 'base'], + > # modified: file content change from base to parent + > 'modified': ['base', 'parent'], + > # added: file is missing from base and added in parent + > 'added': [None, 'parent'], + > # removed: file exist in base but is removed from parent + > 'removed': ['base', None], + > # file exist neither in base not in parent + > 'missing': [None, None], + > } + > + > # content of file in working copy + > wccontent = { + > # clean: wc content is the same as parent + > 'clean': lambda cc: cc[1], + > # revert: wc content is the same as base + > 'revert': lambda cc: cc[0], + > # wc: file exist with a content different from base and parent + > 'wc': lambda cc: 'wc', + > # removed: file is missing and marked as untracked + > 'removed': lambda cc: None, + > # deleted: file is recorded as tracked but missing + > # rely on file deletion outside of this script + > 'deleted': lambda cc:'TOBEDELETED', + > } + > # untracked-X is a version of X where the file is not tracked (? unknown) + > wccontent['untracked-clean'] = wccontent['clean'] + > wccontent['untracked-revert'] = wccontent['revert'] + > wccontent['untracked-wc'] = wccontent['wc'] + > + > # build the combination of possible states + > combination = [] + > for ctxkey in ctxcontent: + > for wckey in wccontent: + > filename = "%s_%s" % (ctxkey, wckey) + > combination.append((filename, ctxkey, wckey)) + > + > # make sure we have stable output + > combination.sort() + > + > # retrieve the state we must generate + > target = sys.argv[1] + > + > # compute file content + > content = [] + > for filename, ctxkey, wckey in combination: + > cc = ctxcontent[ctxkey] + > if target == 'filelist': + > print filename + > elif target == 'base': + > content.append((filename, cc[0])) + > elif target == 'parent': + > content.append((filename, cc[1])) + > elif target == 'wc': + > content.append((filename, wccontent[wckey](cc))) + > else: + > print >> sys.stderr, "unknown target:", target + > sys.exit(1) + > + > # write actual content + > for filename, data in content: + > if data is not None: + > f = open(filename, 'w') + > f.write(data + '\n') + > f.close() + > elif os.path.exists(filename): + > os.remove(filename) + > EOF + +check list of planned files + + $ python gen-revert-cases.py filelist + added_clean + added_deleted + added_removed + added_revert + added_untracked-clean + added_untracked-revert + added_untracked-wc + added_wc + clean_clean + clean_deleted + clean_removed + clean_revert + clean_untracked-clean + clean_untracked-revert + clean_untracked-wc + clean_wc + missing_clean + missing_deleted + missing_removed + missing_revert + missing_untracked-clean + missing_untracked-revert + missing_untracked-wc + missing_wc + modified_clean + modified_deleted + modified_removed + modified_revert + modified_untracked-clean + modified_untracked-revert + modified_untracked-wc + modified_wc + removed_clean + removed_deleted + removed_removed + removed_revert + removed_untracked-clean + removed_untracked-revert + removed_untracked-wc + removed_wc + +Script to make a simple text version of the content +--------------------------------------------------- + + $ cat << EOF >> dircontent.py + > # generate a simple text view of the directory for easy comparison + > import os + > files = os.listdir('.') + > files.sort() + > for filename in files: + > if os.path.isdir(filename): + > continue + > content = open(filename).read() + > print '%-6s %s' % (content.strip(), filename) + > EOF + +Generate appropriate repo state +------------------------------- + + $ hg init revert-ref + $ cd revert-ref + +Generate base changeset + + $ python ../gen-revert-cases.py base + $ hg addremove --similarity 0 + adding clean_clean + adding clean_deleted + adding clean_removed + adding clean_revert + adding clean_untracked-clean + adding clean_untracked-revert + adding clean_untracked-wc + adding clean_wc + adding modified_clean + adding modified_deleted + adding modified_removed + adding modified_revert + adding modified_untracked-clean + adding modified_untracked-revert + adding modified_untracked-wc + adding modified_wc + adding removed_clean + adding removed_deleted + adding removed_removed + adding removed_revert + adding removed_untracked-clean + adding removed_untracked-revert + adding removed_untracked-wc + adding removed_wc + $ hg status + A clean_clean + A clean_deleted + A clean_removed + A clean_revert + A clean_untracked-clean + A clean_untracked-revert + A clean_untracked-wc + A clean_wc + A modified_clean + A modified_deleted + A modified_removed + A modified_revert + A modified_untracked-clean + A modified_untracked-revert + A modified_untracked-wc + A modified_wc + A removed_clean + A removed_deleted + A removed_removed + A removed_revert + A removed_untracked-clean + A removed_untracked-revert + A removed_untracked-wc + A removed_wc + $ hg commit -m 'base' + +(create a simple text version of the content) + + $ python ../dircontent.py > ../content-base.txt + $ cat ../content-base.txt + base clean_clean + base clean_deleted + base clean_removed + base clean_revert + base clean_untracked-clean + base clean_untracked-revert + base clean_untracked-wc + base clean_wc + base modified_clean + base modified_deleted + base modified_removed + base modified_revert + base modified_untracked-clean + base modified_untracked-revert + base modified_untracked-wc + base modified_wc + base removed_clean + base removed_deleted + base removed_removed + base removed_revert + base removed_untracked-clean + base removed_untracked-revert + base removed_untracked-wc + base removed_wc + +Create parent changeset + + $ python ../gen-revert-cases.py parent + $ hg addremove --similarity 0 + adding added_clean + adding added_deleted + adding added_removed + adding added_revert + adding added_untracked-clean + adding added_untracked-revert + adding added_untracked-wc + adding added_wc + removing removed_clean + removing removed_deleted + removing removed_removed + removing removed_revert + removing removed_untracked-clean + removing removed_untracked-revert + removing removed_untracked-wc + removing removed_wc + $ hg status + M modified_clean + M modified_deleted + M modified_removed + M modified_revert + M modified_untracked-clean + M modified_untracked-revert + M modified_untracked-wc + M modified_wc + A added_clean + A added_deleted + A added_removed + A added_revert + A added_untracked-clean + A added_untracked-revert + A added_untracked-wc + A added_wc + R removed_clean + R removed_deleted + R removed_removed + R removed_revert + R removed_untracked-clean + R removed_untracked-revert + R removed_untracked-wc + R removed_wc + $ hg commit -m 'parent' + +(create a simple text version of the content) + + $ python ../dircontent.py > ../content-parent.txt + $ cat ../content-parent.txt + parent added_clean + parent added_deleted + parent added_removed + parent added_revert + parent added_untracked-clean + parent added_untracked-revert + parent added_untracked-wc + parent added_wc + base clean_clean + base clean_deleted + base clean_removed + base clean_revert + base clean_untracked-clean + base clean_untracked-revert + base clean_untracked-wc + base clean_wc + parent modified_clean + parent modified_deleted + parent modified_removed + parent modified_revert + parent modified_untracked-clean + parent modified_untracked-revert + parent modified_untracked-wc + parent modified_wc + +Setup working directory + + $ python ../gen-revert-cases.py wc | cat + $ hg addremove --similarity 0 + removing added_removed + removing added_revert + removing added_untracked-revert + removing clean_removed + adding missing_deleted + adding missing_untracked-wc + adding missing_wc + removing modified_removed + adding removed_deleted + adding removed_revert + adding removed_untracked-revert + adding removed_untracked-wc + adding removed_wc + $ hg forget *untracked* + $ rm *deleted* + $ hg status + M added_wc + M clean_wc + M modified_revert + M modified_wc + A missing_wc + A removed_revert + A removed_wc + R added_removed + R added_revert + R added_untracked-clean + R added_untracked-revert + R added_untracked-wc + R clean_removed + R clean_untracked-clean + R clean_untracked-revert + R clean_untracked-wc + R modified_removed + R modified_untracked-clean + R modified_untracked-revert + R modified_untracked-wc + ! added_deleted + ! clean_deleted + ! missing_deleted + ! modified_deleted + ! removed_deleted + ? missing_untracked-wc + ? removed_untracked-revert + ? removed_untracked-wc + + $ hg status --rev 'desc("base")' + M clean_wc + M modified_clean + M modified_wc + M removed_wc + A added_clean + A added_wc + A missing_wc + R clean_removed + R clean_untracked-clean + R clean_untracked-revert + R clean_untracked-wc + R modified_removed + R modified_untracked-clean + R modified_untracked-revert + R modified_untracked-wc + R removed_clean + R removed_deleted + R removed_removed + R removed_untracked-clean + R removed_untracked-revert + R removed_untracked-wc + ! added_deleted + ! clean_deleted + ! missing_deleted + ! modified_deleted + ! removed_deleted + ? missing_untracked-wc + +(create a simple text version of the content) + + $ python ../dircontent.py > ../content-wc.txt + $ cat ../content-wc.txt + parent added_clean + parent added_untracked-clean + wc added_untracked-wc + wc added_wc + base clean_clean + base clean_revert + base clean_untracked-clean + base clean_untracked-revert + wc clean_untracked-wc + wc clean_wc + wc missing_untracked-wc + wc missing_wc + parent modified_clean + base modified_revert + parent modified_untracked-clean + base modified_untracked-revert + wc modified_untracked-wc + wc modified_wc + base removed_revert + base removed_untracked-revert + wc removed_untracked-wc + wc removed_wc + + $ cd .. + +Test revert --all to parent content +----------------------------------- + +(setup from reference repo) + + $ cp -r revert-ref revert-parent-all + $ cd revert-parent-all + +check revert output + + $ hg revert --all + reverting added_deleted + undeleting added_removed + undeleting added_revert + undeleting added_untracked-clean + undeleting added_untracked-revert + undeleting added_untracked-wc + reverting added_wc + reverting clean_deleted + undeleting clean_removed + undeleting clean_untracked-clean + undeleting clean_untracked-revert + undeleting clean_untracked-wc + reverting clean_wc + forgetting missing_deleted + forgetting missing_wc + reverting modified_deleted + undeleting modified_removed + reverting modified_revert + undeleting modified_untracked-clean + undeleting modified_untracked-revert + undeleting modified_untracked-wc + reverting modified_wc + forgetting removed_deleted + forgetting removed_revert + forgetting removed_wc + +Compare resulting directory with revert target. + +The diff is filtered to include change only. The only difference should be +additional `.orig` backup file when applicable. + + $ python ../dircontent.py > ../content-parent-all.txt + $ cd .. + $ diff -U 0 -- content-parent.txt content-parent-all.txt | grep _ + +wc added_untracked-wc.orig + +wc added_wc.orig + +wc clean_untracked-wc.orig + +wc clean_wc.orig + +wc missing_untracked-wc + +wc missing_wc + +base modified_revert.orig + +base modified_untracked-revert.orig + +wc modified_untracked-wc.orig + +wc modified_wc.orig + +base removed_revert + +base removed_untracked-revert + +wc removed_untracked-wc + +wc removed_wc + +Test revert --all to "base" content +----------------------------------- + +(setup from reference repo) + + $ cp -r revert-ref revert-base-all + $ cd revert-base-all + +check revert output + +Misbehavior: + +- report "reverting" when file needs no changes +| +| - reverting modified_revert +| - reverting removed_revert + + $ hg revert --all --rev 'desc(base)' + removing added_clean + removing added_deleted + removing added_wc + reverting clean_deleted + undeleting clean_removed + undeleting clean_untracked-clean + undeleting clean_untracked-revert + undeleting clean_untracked-wc + reverting clean_wc + forgetting missing_deleted + forgetting missing_wc + reverting modified_clean + reverting modified_deleted + undeleting modified_removed + reverting modified_revert + undeleting modified_untracked-clean + undeleting modified_untracked-revert + undeleting modified_untracked-wc + reverting modified_wc + adding removed_clean + reverting removed_deleted + adding removed_removed + reverting removed_revert + adding removed_untracked-clean + adding removed_untracked-revert + adding removed_untracked-wc + reverting removed_wc + +Compare resulting directory with revert target. + +The diff is filtered to include change only. The only difference should be +additional `.orig` backup file when applicable. + +Misbehavior: + +- no backup for +| - added_wc (DATA LOSS) + + $ python ../dircontent.py > ../content-base-all.txt + $ cd .. + $ diff -U 0 -- content-base.txt content-base-all.txt | grep _ + +parent added_untracked-clean + +wc added_untracked-wc + +wc clean_untracked-wc.orig + +wc clean_wc.orig + +wc missing_untracked-wc + +wc missing_wc + +parent modified_untracked-clean.orig + +wc modified_untracked-wc.orig + +wc modified_wc.orig + +wc removed_untracked-wc.orig + +wc removed_wc.orig + +Test revert to parent content with explicit file name +----------------------------------------------------- + +(setup from reference repo) + + $ cp -r revert-ref revert-parent-explicit + $ cd revert-parent-explicit + +revert all files individually and check the output +(output is expected to be different than in the --all case) + + $ for file in `python ../gen-revert-cases.py filelist`; do + > echo '### revert for:' $file; + > hg revert $file; + > echo + > done + ### revert for: added_clean + no changes needed to added_clean + + ### revert for: added_deleted + + ### revert for: added_removed + + ### revert for: added_revert + + ### revert for: added_untracked-clean + + ### revert for: added_untracked-revert + + ### revert for: added_untracked-wc + + ### revert for: added_wc + + ### revert for: clean_clean + no changes needed to clean_clean + + ### revert for: clean_deleted + + ### revert for: clean_removed + + ### revert for: clean_revert + no changes needed to clean_revert + + ### revert for: clean_untracked-clean + + ### revert for: clean_untracked-revert + + ### revert for: clean_untracked-wc + + ### revert for: clean_wc + + ### revert for: missing_clean + missing_clean: no such file in rev * (glob) + + ### revert for: missing_deleted + + ### revert for: missing_removed + missing_removed: no such file in rev * (glob) + + ### revert for: missing_revert + missing_revert: no such file in rev * (glob) + + ### revert for: missing_untracked-clean + missing_untracked-clean: no such file in rev * (glob) + + ### revert for: missing_untracked-revert + missing_untracked-revert: no such file in rev * (glob) + + ### revert for: missing_untracked-wc + file not managed: missing_untracked-wc + + ### revert for: missing_wc + + ### revert for: modified_clean + no changes needed to modified_clean + + ### revert for: modified_deleted + + ### revert for: modified_removed + + ### revert for: modified_revert + + ### revert for: modified_untracked-clean + + ### revert for: modified_untracked-revert + + ### revert for: modified_untracked-wc + + ### revert for: modified_wc + + ### revert for: removed_clean + removed_clean: no such file in rev * (glob) + + ### revert for: removed_deleted + + ### revert for: removed_removed + removed_removed: no such file in rev * (glob) + + ### revert for: removed_revert + + ### revert for: removed_untracked-clean + removed_untracked-clean: no such file in rev * (glob) + + ### revert for: removed_untracked-revert + file not managed: removed_untracked-revert + + ### revert for: removed_untracked-wc + file not managed: removed_untracked-wc + + ### revert for: removed_wc + + +check resulting directory againt the --all run +(There should be no difference) + + $ python ../dircontent.py > ../content-parent-explicit.txt + $ cd .. + $ diff -U 0 -- content-parent-all.txt content-parent-explicit.txt | grep _ + [1] + +Test revert to "base" content with explicit file name +----------------------------------------------------- + +(setup from reference repo) + + $ cp -r revert-ref revert-base-explicit + $ cd revert-base-explicit + +revert all files individually and check the output +(output is expected to be different than in the --all case) + +Misbehavior: + +- fails to report no change to revert for +| +| - clean_clean +| - clean_revert +| - modified_revert +| - removed_revert + + $ for file in `python ../gen-revert-cases.py filelist`; do + > echo '### revert for:' $file; + > hg revert $file --rev 'desc(base)'; + > echo + > done + ### revert for: added_clean + + ### revert for: added_deleted + + ### revert for: added_removed + no changes needed to added_removed + + ### revert for: added_revert + no changes needed to added_revert + + ### revert for: added_untracked-clean + no changes needed to added_untracked-clean + + ### revert for: added_untracked-revert + no changes needed to added_untracked-revert + + ### revert for: added_untracked-wc + no changes needed to added_untracked-wc + + ### revert for: added_wc + + ### revert for: clean_clean + + ### revert for: clean_deleted + + ### revert for: clean_removed + + ### revert for: clean_revert + + ### revert for: clean_untracked-clean + + ### revert for: clean_untracked-revert + + ### revert for: clean_untracked-wc + + ### revert for: clean_wc + + ### revert for: missing_clean + missing_clean: no such file in rev * (glob) + + ### revert for: missing_deleted + + ### revert for: missing_removed + missing_removed: no such file in rev * (glob) + + ### revert for: missing_revert + missing_revert: no such file in rev * (glob) + + ### revert for: missing_untracked-clean + missing_untracked-clean: no such file in rev * (glob) + + ### revert for: missing_untracked-revert + missing_untracked-revert: no such file in rev * (glob) + + ### revert for: missing_untracked-wc + file not managed: missing_untracked-wc + + ### revert for: missing_wc + + ### revert for: modified_clean + + ### revert for: modified_deleted + + ### revert for: modified_removed + + ### revert for: modified_revert + + ### revert for: modified_untracked-clean + + ### revert for: modified_untracked-revert + + ### revert for: modified_untracked-wc + + ### revert for: modified_wc + + ### revert for: removed_clean + + ### revert for: removed_deleted + + ### revert for: removed_removed + + ### revert for: removed_revert + + ### revert for: removed_untracked-clean + + ### revert for: removed_untracked-revert + + ### revert for: removed_untracked-wc + + ### revert for: removed_wc + + +check resulting directory againt the --all run +(There should be no difference) + + $ python ../dircontent.py > ../content-base-explicit.txt + $ cd .. + $ diff -U 0 -- content-base-all.txt content-base-explicit.txt | grep _ + [1]
--- a/tests/test-run-tests.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-run-tests.t Thu Aug 14 16:25:47 2014 -0500 @@ -13,6 +13,8 @@ $ cat > test-success.t << EOF > $ echo babar > babar + > $ echo xyzzy + > xyzzy > EOF $ $TESTDIR/run-tests.py --with-hg=`which hg` @@ -25,16 +27,20 @@ $ cat > test-failure.t << EOF > $ echo babar > rataxes + > This is a noop statement so that + > this test is still more bytes than success. > EOF $ $TESTDIR/run-tests.py --with-hg=`which hg` --- $TESTTMP/test-failure.t (glob) +++ $TESTTMP/test-failure.t.err (glob) - @@ -1,2 +1,2 @@ + @@ -1,4 +1,4 @@ $ echo babar - rataxes + babar + This is a noop statement so that + this test is still more bytes than success. ERROR: test-failure.t output changed !. @@ -42,6 +48,39 @@ # Ran 2 tests, 0 skipped, 0 warned, 1 failed. python hash seed: * (glob) [1] +test --xunit support + $ $TESTDIR/run-tests.py --with-hg=`which hg` --xunit=xunit.xml + + --- $TESTTMP/test-failure.t + +++ $TESTTMP/test-failure.t.err + @@ -1,4 +1,4 @@ + $ echo babar + - rataxes + + babar + This is a noop statement so that + this test is still more bytes than success. + + ERROR: test-failure.t output changed + !. + Failed test-failure.t: output changed + # Ran 2 tests, 0 skipped, 0 warned, 1 failed. + python hash seed: * (glob) + [1] + $ cat xunit.xml + <?xml version="1.0" encoding="utf-8"?> + <testsuite errors="0" failures="1" name="run-tests" skipped="0" tests="2"> + <testcase name="test-success.t" time="*"/> (glob) + <testcase name="test-failure.t" time="*"> (glob) + <![CDATA[--- $TESTTMP/test-failure.t + +++ $TESTTMP/test-failure.t.err + @@ -1,4 +1,4 @@ + $ echo babar + - rataxes + + babar + This is a noop statement so that + this test is still more bytes than success. + ]]> </testcase> + </testsuite> test for --retest ==================== @@ -50,15 +89,17 @@ --- $TESTTMP/test-failure.t (glob) +++ $TESTTMP/test-failure.t.err (glob) - @@ -1,2 +1,2 @@ + @@ -1,4 +1,4 @@ $ echo babar - rataxes + babar + This is a noop statement so that + this test is still more bytes than success. ERROR: test-failure.t output changed ! Failed test-failure.t: output changed - # Ran 1 tests, 1 skipped, 0 warned, 1 failed. + # Ran 2 tests, 1 skipped, 0 warned, 1 failed. python hash seed: * (glob) [1] @@ -71,16 +112,23 @@ . # Ran 1 tests, 0 skipped, 0 warned, 0 failed. +success w/ keyword + $ $TESTDIR/run-tests.py --with-hg=`which hg` -k xyzzy + . + # Ran 2 tests, 1 skipped, 0 warned, 0 failed. + failed $ $TESTDIR/run-tests.py --with-hg=`which hg` test-failure.t --- $TESTTMP/test-failure.t (glob) +++ $TESTTMP/test-failure.t.err (glob) - @@ -1,2 +1,2 @@ + @@ -1,4 +1,4 @@ $ echo babar - rataxes + babar + This is a noop statement so that + this test is still more bytes than success. ERROR: test-failure.t output changed ! @@ -89,6 +137,25 @@ python hash seed: * (glob) [1] +failure w/ keyword + $ $TESTDIR/run-tests.py --with-hg=`which hg` -k rataxes + + --- $TESTTMP/test-failure.t + +++ $TESTTMP/test-failure.t.err + @@ -1,4 +1,4 @@ + $ echo babar + - rataxes + + babar + This is a noop statement so that + this test is still more bytes than success. + + ERROR: test-failure.t output changed + ! + Failed test-failure.t: output changed + # Ran 2 tests, 1 skipped, 0 warned, 1 failed. + python hash seed: * (glob) + [1] + Running In Debug Mode ====================== @@ -97,14 +164,18 @@ SALT* 0 0 (glob) + echo babar babar - + echo SALT* 2 0 (glob) - SALT* 2 0 (glob) + + echo SALT* 4 0 (glob) + SALT* 4 0 (glob) .+ echo SALT* 0 0 (glob) SALT* 0 0 (glob) + echo babar babar + echo SALT* 2 0 (glob) SALT* 2 0 (glob) + + echo xyzzy + xyzzy + + echo SALT* 4 0 (glob) + SALT* 4 0 (glob) . # Ran 2 tests, 0 skipped, 0 warned, 0 failed. @@ -118,19 +189,23 @@ --- $TESTTMP/test-failure*.t (glob) +++ $TESTTMP/test-failure*.t.err (glob) - @@ -1,2 +1,2 @@ + @@ -1,4 +1,4 @@ $ echo babar - rataxes + babar + This is a noop statement so that + this test is still more bytes than success. ERROR: test-failure*.t output changed (glob) ! --- $TESTTMP/test-failure*.t (glob) +++ $TESTTMP/test-failure*.t.err (glob) - @@ -1,2 +1,2 @@ + @@ -1,4 +1,4 @@ $ echo babar - rataxes + babar + This is a noop statement so that + this test is still more bytes than success. ERROR: test-failure*.t output changed (glob) ! @@ -156,10 +231,12 @@ --- $TESTTMP/test-failure.t +++ $TESTTMP/test-failure.t.err - @@ -1,2 +1,2 @@ + @@ -1,4 +1,4 @@ $ echo babar - rataxes + babar + This is a noop statement so that + this test is still more bytes than success. Accept this change? [n] ERROR: test-failure.t output changed !. @@ -171,6 +248,20 @@ $ cat test-failure.t $ echo babar rataxes + This is a noop statement so that + this test is still more bytes than success. + +View the fix + + $ echo 'y' | $TESTDIR/run-tests.py --with-hg=`which hg` --view echo + $TESTTMP/test-failure.t $TESTTMP/test-failure.t.err + + ERROR: test-failure.t output changed + !. + Failed test-failure.t: output changed + # Ran 2 tests, 0 skipped, 0 warned, 1 failed. + python hash seed: * (glob) + [1] Accept the fix @@ -178,16 +269,20 @@ --- $TESTTMP/test-failure.t +++ $TESTTMP/test-failure.t.err - @@ -1,2 +1,2 @@ + @@ -1,4 +1,4 @@ $ echo babar - rataxes + babar + This is a noop statement so that + this test is still more bytes than success. Accept this change? [n] .. # Ran 2 tests, 0 skipped, 0 warned, 0 failed. $ cat test-failure.t $ echo babar babar + This is a noop statement so that + this test is still more bytes than success. (reinstall) $ mv backup test-failure.t @@ -201,3 +296,64 @@ # Ran 2 tests, 0 skipped, 0 warned, 1 failed. python hash seed: * (glob) [1] + +test for --time +================== + + $ $TESTDIR/run-tests.py --with-hg=`which hg` test-success.t --time + . + # Ran 1 tests, 0 skipped, 0 warned, 0 failed. + # Producing time report + cuser csys real Test + \s*[\d\.]{5} \s*[\d\.]{5} \s*[\d\.]{5} test-success.t (re) + +test for --time with --job enabled +==================================== + + $ $TESTDIR/run-tests.py --with-hg=`which hg` test-success.t --time --jobs 2 + . + # Ran 1 tests, 0 skipped, 0 warned, 0 failed. + # Producing time report + cuser csys real Test + \s*[\d\.]{5} \s*[\d\.]{5} \s*[\d\.]{5} test-success.t (re) + +Skips +================ + $ cat > test-skip.t <<EOF + > $ echo xyzzy + > #require false + > EOF + $ $TESTDIR/run-tests.py --with-hg=`which hg` --nodiff + !.s + Skipped test-skip.t: irrelevant + Failed test-failure.t: output changed + # Ran 2 tests, 1 skipped, 0 warned, 1 failed. + python hash seed: * (glob) + [1] + + $ $TESTDIR/run-tests.py --with-hg=`which hg` --keyword xyzzy + .s + Skipped test-skip.t: irrelevant + # Ran 2 tests, 2 skipped, 0 warned, 0 failed. + +Skips with xml + $ $TESTDIR/run-tests.py --with-hg=`which hg` --keyword xyzzy \ + > --xunit=xunit.xml + .s + Skipped test-skip.t: irrelevant + # Ran 2 tests, 2 skipped, 0 warned, 0 failed. + $ cat xunit.xml + <?xml version="1.0" encoding="utf-8"?> + <testsuite errors="0" failures="0" name="run-tests" skipped="2" tests="2"> + <testcase name="test-success.t" time="*"/> (glob) + </testsuite> + +Missing skips or blacklisted skips don't count as executed: + $ echo test-failure.t > blacklist + $ $TESTDIR/run-tests.py --with-hg=`which hg` --blacklist=blacklist \ + > test-failure.t test-bogus.t + ss + Skipped test-bogus.t: Doesn't exist + Skipped test-failure.t: blacklisted + # Ran 0 tests, 2 skipped, 0 warned, 0 failed. +
--- a/tests/test-schemes.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-schemes.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ - $ "$TESTDIR/hghave" serve || exit 80 +#require serve $ cat <<EOF >> $HGRCPATH > [extensions]
--- a/tests/test-serve.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-serve.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ - $ "$TESTDIR/hghave" serve || exit 80 +#require serve $ hgserve() > {
--- a/tests/test-share.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-share.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ - $ "$TESTDIR/hghave" killdaemons || exit 80 +#require killdaemons $ echo "[extensions]" >> $HGRCPATH $ echo "share = " >> $HGRCPATH
--- a/tests/test-simplemerge.py Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-simplemerge.py Thu Aug 14 16:25:47 2014 -0500 @@ -320,66 +320,6 @@ self.log(''.join(ml)) self.assertEquals(ml, MERGED_RESULT) - def test_minimal_conflicts_common(self): - """Reprocessing""" - base_text = ("a\n" * 20).splitlines(True) - this_text = ("a\n"*10+"b\n" * 10).splitlines(True) - other_text = ("a\n"*10+"c\n"+"b\n" * 8 + "c\n").splitlines(True) - m3 = Merge3(base_text, other_text, this_text) - m_lines = m3.merge_lines('OTHER', 'THIS', reprocess=True) - merged_text = "".join(list(m_lines)) - optimal_text = ("a\n" * 10 + "<<<<<<< OTHER\nc\n=======\n" - + ">>>>>>> THIS\n" - + 8* "b\n" + "<<<<<<< OTHER\nc\n=======\n" - + 2* "b\n" + ">>>>>>> THIS\n") - self.assertEquals(optimal_text, merged_text) - - def test_minimal_conflicts_unique(self): - def add_newline(s): - """Add a newline to each entry in the string""" - return [(x+'\n') for x in s] - - base_text = add_newline("abcdefghijklm") - this_text = add_newline("abcdefghijklmNOPQRSTUVWXYZ") - other_text = add_newline("abcdefghijklm1OPQRSTUVWXY2") - m3 = Merge3(base_text, other_text, this_text) - m_lines = m3.merge_lines('OTHER', 'THIS', reprocess=True) - merged_text = "".join(list(m_lines)) - optimal_text = ''.join(add_newline("abcdefghijklm") - + ["<<<<<<< OTHER\n1\n=======\nN\n>>>>>>> THIS\n"] - + add_newline('OPQRSTUVWXY') - + ["<<<<<<< OTHER\n2\n=======\nZ\n>>>>>>> THIS\n"] - ) - self.assertEquals(optimal_text, merged_text) - - def test_minimal_conflicts_nonunique(self): - def add_newline(s): - """Add a newline to each entry in the string""" - return [(x+'\n') for x in s] - - base_text = add_newline("abacddefgghij") - this_text = add_newline("abacddefgghijkalmontfprz") - other_text = add_newline("abacddefgghijknlmontfprd") - m3 = Merge3(base_text, other_text, this_text) - m_lines = m3.merge_lines('OTHER', 'THIS', reprocess=True) - merged_text = "".join(list(m_lines)) - optimal_text = ''.join(add_newline("abacddefgghijk") - + ["<<<<<<< OTHER\nn\n=======\na\n>>>>>>> THIS\n"] - + add_newline('lmontfpr') - + ["<<<<<<< OTHER\nd\n=======\nz\n>>>>>>> THIS\n"] - ) - self.assertEquals(optimal_text, merged_text) - - def test_reprocess_and_base(self): - """Reprocessing and showing base breaks correctly""" - base_text = ("a\n" * 20).splitlines(True) - this_text = ("a\n"*10+"b\n" * 10).splitlines(True) - other_text = ("a\n"*10+"c\n"+"b\n" * 8 + "c\n").splitlines(True) - m3 = Merge3(base_text, other_text, this_text) - m_lines = m3.merge_lines('OTHER', 'THIS', reprocess=True, - base_marker='|||||||') - self.assertRaises(CantReprocessAndShowBase, list, m_lines) - def test_binary(self): self.assertRaises(util.Abort, Merge3, ['\x00'], ['a'], ['b'])
--- a/tests/test-simplemerge.py.out Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-simplemerge.py.out Thu Aug 14 16:25:47 2014 -0500 @@ -1,5 +1,5 @@ -.................... +................ ---------------------------------------------------------------------- -Ran 20 tests in 0.000s +Ran 16 tests in 0.000s OK
--- a/tests/test-static-http.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-static-http.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ - $ "$TESTDIR/hghave" killdaemons || exit 80 +#require killdaemons #if windows $ hg clone http://localhost:$HGPORT/ copy
--- a/tests/test-strict.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-strict.t Thu Aug 14 16:25:47 2014 -0500 @@ -37,7 +37,7 @@ summary summarize working directory state update update working directory (or switch revisions) - use "hg help" for the full list of commands or "hg -v" for details + (use "hg help" for the full list of commands or "hg -v" for details) [255] $ hg annotate a 0: a
--- a/tests/test-strip.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-strip.t Thu Aug 14 16:25:47 2014 -0500 @@ -532,9 +532,9 @@ strip changesets and all their descendants from the repository - use "hg help -e strip" to show help for the strip extension + (use "hg help -e strip" to show help for the strip extension) - options: + options ([+] can be repeated): -r --rev REV [+] strip specified revision (optional, can specify revisions without this option) @@ -545,7 +545,5 @@ -B --bookmark VALUE remove revs only reachable from given bookmark --mq operate on patch repository - [+] marked option can be specified multiple times - - use "hg help strip" to show the full help text + (use "hg strip -h" to show more help) [255]
--- a/tests/test-subrepo-git.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-subrepo-git.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ - $ "$TESTDIR/hghave" git || exit 80 +#require git make git commits repeatable
--- a/tests/test-subrepo-relative-path.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-subrepo-relative-path.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ - $ "$TESTDIR/hghave" killdaemons || exit 80 +#require killdaemons Preparing the subrepository 'sub'
--- a/tests/test-subrepo-svn.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-subrepo-svn.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ - $ "$TESTDIR/hghave" svn15 || exit 80 +#require svn15 $ SVNREPOPATH=`pwd`/svn-repo #if windows
--- a/tests/test-symlink-placeholder.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-symlink-placeholder.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ - $ "$TESTDIR/hghave" symlink || exit 80 +#require symlink Create extension that can disable symlink support:
--- a/tests/test-symlinks.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-symlinks.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ - $ "$TESTDIR/hghave" symlink || exit 80 +#require symlink == tests added in 0.7 ==
--- a/tests/test-transplant.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-transplant.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ - $ "$TESTDIR/hghave" killdaemons || exit 80 +#require killdaemons $ cat <<EOF >> $HGRCPATH > [extensions]
--- a/tests/test-treediscovery-legacy.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-treediscovery-legacy.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ - $ "$TESTDIR/hghave" killdaemons || exit 80 +#require killdaemons Tests discovery against servers without getbundle support:
--- a/tests/test-treediscovery.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-treediscovery.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ - $ "$TESTDIR/hghave" killdaemons || exit 80 +#require killdaemons Tests discovery against servers without getbundle support:
--- a/tests/test-unbundlehash.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-unbundlehash.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ - $ "$TESTDIR/hghave" killdaemons || exit 80 +#require killdaemons Test wire protocol unbundle with hashed heads (capability: unbundlehash)
--- a/tests/test-update-issue1456.t Thu Aug 14 16:18:45 2014 -0500 +++ b/tests/test-update-issue1456.t Thu Aug 14 16:25:47 2014 -0500 @@ -1,4 +1,4 @@ - $ "$TESTDIR/hghave" execbit || exit 80 +#require execbit $ rm -rf a $ hg init a