--- a/Makefile Wed Sep 03 20:42:51 2014 +0200
+++ b/Makefile Sun Sep 07 11:46:11 2014 -0500
@@ -135,12 +135,13 @@
# Packaging targets
osx:
- @which -s bdist_mpkg || \
+ @which bdist_mpkg >/dev/null || \
(echo "Missing bdist_mpkg (easy_install bdist_mpkg)"; false)
+ rm -rf dist/mercurial-*.mpkg
bdist_mpkg setup.py
mkdir -p packages/osx
+ N=`cd dist && echo mercurial-*.mpkg | sed 's,\.mpkg$$,,'` && hdiutil create -srcfolder dist/$$N.mpkg/ -scrub -volname "$$N" -ov packages/osx/$$N.dmg
rm -rf dist/mercurial-*.mpkg
- mv dist/mercurial*macosx*.zip packages/osx
fedora:
mkdir -p packages/fedora
--- a/contrib/check-code.py Wed Sep 03 20:42:51 2014 +0200
+++ b/contrib/check-code.py Sun Sep 07 11:46:11 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),
@@ -214,8 +216,9 @@
(r'(\w|\)),\w', "missing whitespace after ,"),
(r'(\w|\))[+/*\-<>]\w', "missing whitespace in expression"),
(r'^\s+(\w|\.)+=\w[^,()\n]*$', "missing whitespace in assignment"),
- (r'(\s+)try:\n((?:\n|\1\s.*\n)+?)\1except.*?:\n'
- r'((?:\n|\1\s.*\n)+?)\1finally:', 'no try/except/finally in Python 2.4'),
+ (r'(\s+)try:\n((?:\n|\1\s.*\n)+?)(\1except.*?:\n'
+ r'((?:\n|\1\s.*\n)+?))+\1finally:',
+ 'no try/except/finally in Python 2.4'),
(r'(?<!def)(\s+|^|\()next\(.+\)',
'no next(foo) in Python 2.4 and 2.5, use foo.next() instead'),
(r'(\s+)try:\n((?:\n|\1\s.*\n)*?)\1\s*yield\b.*?'
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/contrib/check-commit Sun Sep 07 11:46:11 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)
--- a/contrib/convert-repo Wed Sep 03 20:42:51 2014 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-#!/usr/bin/env python
-#
-# Wrapper script around the convert.py hgext extension
-# for foreign SCM conversion to mercurial format.
-#
-
-import sys
-from mercurial import ui, fancyopts
-from hgext import convert
-
-# Options extracted from the cmdtable
-func, options, help = convert.cmdtable['convert']
-
-# An ui instance
-u = ui.ui()
-
-opts = {}
-args = []
-try:
- args = list(fancyopts.fancyopts(sys.argv[1:], options, opts))
- args += [None]*(3 - len(args))
- src, dest, revmapfile = args
-except (fancyopts.getopt.GetoptError, ValueError), inst:
- u.warn('Usage:\n%s\n' % help)
- sys.exit(-1)
-
-convert.convert(u, src, dest, revmapfile, **opts)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/contrib/hg-test-mode.el Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/contrib/revsetbenchmarks.py Sun Sep 07 11:46:11 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/revsetbenchmarks.txt Wed Sep 03 20:42:51 2014 +0200
+++ b/contrib/revsetbenchmarks.txt Sun Sep 07 11:46:11 2014 -0500
@@ -22,3 +22,4 @@
:10000 and draft()
max(::(tip~20) - obsolete())
roots((0:tip)::)
+(not public() - obsolete())
--- a/contrib/sample.hgrc Wed Sep 03 20:42:51 2014 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,128 +0,0 @@
-### --- User interface
-
-[ui]
-
-### show changed files and be a bit more verbose if True
-
-# verbose = True
-
-### username data to appear in comits
-### it usually takes the form: Joe User <joe.user@host.com>
-
-# username = Joe User <j.user@example.com>
-
-### --- Extensions
-
-[extensions]
-
-### each extension has its own 'extension_name=path' line
-### the default python library path is used when path is left blank
-### the hgext dir is used when 'hgext.extension_name=' is written
-
-### acl - Access control lists
-### hg help acl
-
-# hgext.acl =
-
-### bisect - binary search changesets to detect bugs
-### hg help bisect
-
-# hgext.hbisect =
-
-### bugzilla - update bugzilla bugs when changesets mention them
-### hg help bugzilla
-
-# hgext.bugzilla =
-
-### extdiff - Use external diff application instead of builtin one
-
-# hgext.extdiff =
-
-### gpg - GPG checks and signing
-### hg help gpg
-
-# hgext.gpg =
-
-### hgk - GUI repository browser
-### hg help view
-
-# hgext.hgk =
-
-### strip - Remove changesets and their descendents from history
-### hg help strip
-
-# hgext.strip =
-
-### notify - Template driven e-mail notifications
-### hg help notify
-
-# hgext.notify =
-
-### patchbomb - send changesets as a series of patch emails
-### hg help email
-
-# hgext.patchbomb =
-
-### churn - create a graph showing who changed the most lines
-### hg help churn
-
-# hgext.churn = /home/user/hg/hg/contrib/churn.py
-
-### eol - automatic management of line endings
-
-# hgext.eol =
-
-### --- hgk additional configuration
-
-[hgk]
-
-### set executable path
-
-# path = /home/user/hg/hg/contrib/hgk
-
-### --- Hook to Mercurial actions - See hgrc man page for avaliable hooks
-
-[hooks]
-
-### Example notify hooks (load hgext.notify extension before use)
-
-# incoming.notify = python:hgext.notify.hook
-# changegroup.notify = python:hgext.notify.hook
-
-### Email configuration for the notify and patchbomb extensions
-
-[email]
-
-### Your email address
-
-# from = user@example.com
-
-### Method to send email - smtp or /usr/sbin/sendmail or other program name
-
-# method = smtp
-
-### smtp server to send email to
-
-[smtp]
-
-# host = mail
-# port = 25
-# tls = false
-# username = user
-# password = blivet
-# local_hostname = myhost
-
-### --- Email notification hook for server
-
-[notify]
-### multiple sources can be specified as a whitespace or comma separated list
-
-# sources = serve push pull bundle
-
-### set this to False when you're ready for mail to start sending
-
-# test = True
-
-### path to config file with names of subscribers
-
-# config = /path/to/subscription/file
--- a/contrib/simplemerge Wed Sep 03 20:42:51 2014 +0200
+++ b/contrib/simplemerge Sun Sep 07 11:46:11 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/contrib/win32/hgwebdir_wsgi.py Wed Sep 03 20:42:51 2014 +0200
+++ b/contrib/win32/hgwebdir_wsgi.py Sun Sep 07 11:46:11 2014 -0500
@@ -52,6 +52,7 @@
# Enable tracing. Run 'python -m win32traceutil' to debug
if getattr(sys, 'isapidllhandle', None) is not None:
import win32traceutil
+ win32traceutil.SetupForPrint # silence unused import warning
# To serve pages in local charset instead of UTF-8, remove the two lines below
import os
@@ -90,6 +91,6 @@
return isapi_wsgi.ISAPISimpleHandler(handler)
if __name__=='__main__':
- from isapi.install import *
+ from isapi.install import ISAPIParameters, HandleCommandLine
params = ISAPIParameters()
HandleCommandLine(params)
--- a/hgext/convert/__init__.py Wed Sep 03 20:42:51 2014 +0200
+++ b/hgext/convert/__init__.py Sun Sep 07 11:46:11 2014 -0500
@@ -29,6 +29,8 @@
('A', 'authormap', '', _('remap usernames using this file'), _('FILE')),
('', 'filemap', '', _('remap file names using contents of file'),
_('FILE')),
+ ('', 'full', None,
+ _('apply filemap changes by converting all files again')),
('', 'splicemap', '', _('splice synthesized history into place'),
_('FILE')),
('', 'branchmap', '', _('change branch names while converting'),
@@ -131,6 +133,14 @@
it is converted. To rename from a subdirectory into the root of
the repository, use ``.`` as the path to rename to.
+ ``--full`` will make sure the converted changesets contain exactly
+ the right files with the right content. It will make a full
+ conversion of all files, not just the ones that have
+ changed. Files that already are correct will not be changed. This
+ can be used to apply filemap changes when converting
+ incrementally. This is currently only supported for Mercurial and
+ Subversion.
+
The splicemap is a file that allows insertion of synthetic
history, letting you specify the parents of a revision. This is
useful if you want to e.g. give a Subversion merge two parents, or
--- a/hgext/convert/bzr.py Wed Sep 03 20:42:51 2014 +0200
+++ b/hgext/convert/bzr.py Sun Sep 07 11:46:11 2014 -0500
@@ -122,8 +122,7 @@
kind = revtree.kind(fileid)
if kind not in supportedkinds:
# the file is not available anymore - was deleted
- raise IOError(_('%s is not available in %s anymore') %
- (name, rev))
+ return None, None
mode = self._modecache[(name, rev)]
if kind == 'symlink':
target = revtree.get_symlink_target(fileid)
@@ -135,8 +134,9 @@
sio = revtree.get_file(fileid)
return sio.read(), mode
- def getchanges(self, version):
- # set up caches: modecache and revtree
+ def getchanges(self, version, full):
+ if full:
+ raise util.Abort(_("convert from cvs do not support --full"))
self._modecache = {}
self._revtree = self.sourcerepo.revision_tree(version)
# get the parentids from the cache
--- a/hgext/convert/common.py Wed Sep 03 20:42:51 2014 +0200
+++ b/hgext/convert/common.py Sun Sep 07 11:46:11 2014 -0500
@@ -88,17 +88,18 @@
def getfile(self, name, rev):
"""Return a pair (data, mode) where data is the file content
as a string and mode one of '', 'x' or 'l'. rev is the
- identifier returned by a previous call to getchanges(). Raise
- IOError to indicate that name was deleted in rev.
+ identifier returned by a previous call to getchanges().
+ Data is None if file is missing/deleted in rev.
"""
raise NotImplementedError
- def getchanges(self, version):
+ def getchanges(self, version, full):
"""Returns a tuple of (files, copies).
files is a sorted list of (filename, id) tuples for all files
changed between version and its first parent returned by
- getcommit(). id is the source revision id of the file.
+ getcommit(). If full, all files in that revision is returned.
+ id is the source revision id of the file.
copies is a dictionary of dest: source
"""
@@ -204,7 +205,7 @@
mapping equivalent authors identifiers for each system."""
return None
- def putcommit(self, files, copies, parents, commit, source, revmap):
+ def putcommit(self, files, copies, parents, commit, source, revmap, full):
"""Create a revision with all changed files listed in 'files'
and having listed parents. 'commit' is a commit object
containing at a minimum the author, date, and message for this
@@ -212,7 +213,8 @@
'copies' is a dictionary mapping destinations to sources,
'source' is the source repository, and 'revmap' is a mapfile
of source revisions to converted revisions. Only getfile() and
- lookuprev() should be called on 'source'.
+ lookuprev() should be called on 'source'. 'full' means that 'files'
+ is complete and all other files should be removed.
Note that the sink repository is not told to update itself to
a particular revision (or even what that revision would be)
--- a/hgext/convert/convcmd.py Wed Sep 03 20:42:51 2014 +0200
+++ b/hgext/convert/convcmd.py Sun Sep 07 11:46:11 2014 -0500
@@ -386,8 +386,8 @@
def copy(self, rev):
commit = self.commitcache[rev]
-
- changes = self.source.getchanges(rev)
+ full = self.opts.get('full')
+ changes = self.source.getchanges(rev, full)
if isinstance(changes, basestring):
if changes == SKIPREV:
dest = SKIPREV
@@ -413,7 +413,7 @@
parents = [b[0] for b in pbranches]
source = progresssource(self.ui, self.source, len(files))
newnode = self.dest.putcommit(files, copies, parents, commit,
- source, self.map)
+ source, self.map, full)
source.close()
self.source.converted(rev, newnode)
self.map[rev] = newnode
--- a/hgext/convert/cvs.py Wed Sep 03 20:42:51 2014 +0200
+++ b/hgext/convert/cvs.py Sun Sep 07 11:46:11 2014 -0500
@@ -220,7 +220,7 @@
self._parse()
if rev.endswith("(DEAD)"):
- raise IOError
+ return None, None
args = ("-N -P -kk -r %s --" % rev).split()
args.append(self.cvsrepo + '/' + name)
@@ -258,7 +258,9 @@
else:
raise util.Abort(_("unknown CVS response: %s") % line)
- def getchanges(self, rev):
+ def getchanges(self, rev, full):
+ if full:
+ raise util.Abort(_("convert from cvs do not support --full"))
self._parse()
return sorted(self.files[rev].iteritems()), {}
--- a/hgext/convert/cvsps.py Wed Sep 03 20:42:51 2014 +0200
+++ b/hgext/convert/cvsps.py Sun Sep 07 11:46:11 2014 -0500
@@ -8,7 +8,6 @@
import os
import re
import cPickle as pickle
-from mercurial import util
from mercurial.i18n import _
from mercurial import hook
from mercurial import util
@@ -632,7 +631,19 @@
odd.add((l, r))
d = -1
break
+ # By this point, the changesets are sufficiently compared that
+ # we don't really care about ordering. However, this leaves
+ # some race conditions in the tests, so we compare on the
+ # number of files modified and the number of branchpoints in
+ # each changeset to ensure test output remains stable.
+ # recommended replacement for cmp from
+ # https://docs.python.org/3.0/whatsnew/3.0.html
+ c = lambda x, y: (x > y) - (x < y)
+ if not d:
+ d = c(len(l.entries), len(r.entries))
+ if not d:
+ d = c(len(l.branchpoints), len(r.branchpoints))
return d
changesets.sort(cscmp)
--- a/hgext/convert/darcs.py Wed Sep 03 20:42:51 2014 +0200
+++ b/hgext/convert/darcs.py Sun Sep 07 11:46:11 2014 -0500
@@ -8,7 +8,7 @@
from common import NoRepo, checktool, commandline, commit, converter_source
from mercurial.i18n import _
from mercurial import util
-import os, shutil, tempfile, re
+import os, shutil, tempfile, re, errno
# The naming drift of ElementTree is fun!
@@ -156,7 +156,9 @@
output, status = self.run('revert', all=True, repodir=self.tmppath)
self.checkexit(status, output)
- def getchanges(self, rev):
+ def getchanges(self, rev, full):
+ if full:
+ raise util.Abort(_("convert from darcs do not support --full"))
copies = {}
changes = []
man = None
@@ -192,8 +194,13 @@
if rev != self.lastrev:
raise util.Abort(_('internal calling inconsistency'))
path = os.path.join(self.tmppath, name)
- data = util.readfile(path)
- mode = os.lstat(path).st_mode
+ try:
+ data = util.readfile(path)
+ mode = os.lstat(path).st_mode
+ except IOError, inst:
+ if inst.errno == errno.ENOENT:
+ return None, None
+ raise
mode = (mode & 0111) and 'x' or ''
return data, mode
--- a/hgext/convert/filemap.py Wed Sep 03 20:42:51 2014 +0200
+++ b/hgext/convert/filemap.py Sun Sep 07 11:46:11 2014 -0500
@@ -304,7 +304,7 @@
wrev.add(rev)
self.wantedancestors[rev] = wrev
- def getchanges(self, rev):
+ def getchanges(self, rev, full):
parents = self.commits[rev].parents
if len(parents) > 1:
self.rebuild()
@@ -384,7 +384,7 @@
# Get the real changes and do the filtering/mapping. To be
# able to get the files later on in getfile, we hide the
# original filename in the rev part of the return value.
- changes, copies = self.base.getchanges(rev)
+ changes, copies = self.base.getchanges(rev, full)
files = {}
for f, r in changes:
newf = self.filemapper(f)
--- a/hgext/convert/git.py Wed Sep 03 20:42:51 2014 +0200
+++ b/hgext/convert/git.py Sun Sep 07 11:46:11 2014 -0500
@@ -135,7 +135,7 @@
def getfile(self, name, rev):
if rev == hex(nullid):
- raise IOError
+ return None, None
if name == '.hgsub':
data = '\n'.join([m.hgsub() for m in self.submoditer()])
mode = ''
@@ -180,7 +180,9 @@
continue
m.node = node.strip()
- def getchanges(self, version):
+ def getchanges(self, version, full):
+ if full:
+ raise util.Abort(_("convert from git do not support --full"))
self.modecache = {}
fh = self.gitopen("git diff-tree -z --root -m -r %s" % version)
changes = []
--- a/hgext/convert/gnuarch.py Wed Sep 03 20:42:51 2014 +0200
+++ b/hgext/convert/gnuarch.py Sun Sep 07 11:46:11 2014 -0500
@@ -137,13 +137,14 @@
if rev != self.lastrev:
raise util.Abort(_('internal calling inconsistency'))
- # Raise IOError if necessary (i.e. deleted files).
if not os.path.lexists(os.path.join(self.tmppath, name)):
- raise IOError
+ return None, None
return self._getfile(name, rev)
- def getchanges(self, rev):
+ def getchanges(self, rev, full):
+ if full:
+ raise util.Abort(_("convert from arch do not support --full"))
self._update(rev)
changes = []
copies = {}
--- a/hgext/convert/hg.py Wed Sep 03 20:42:51 2014 +0200
+++ b/hgext/convert/hg.py Sun Sep 07 11:46:11 2014 -0500
@@ -128,12 +128,16 @@
fp.write('%s %s\n' % (revid, s[1]))
return fp.getvalue()
- def putcommit(self, files, copies, parents, commit, source, revmap):
-
+ def putcommit(self, files, copies, parents, commit, source, revmap, full):
files = dict(files)
def getfilectx(repo, memctx, f):
- v = files[f]
+ try:
+ v = files[f]
+ except KeyError:
+ return None
data, mode = source.getfile(f, v)
+ if data is None:
+ return None
if f == '.hgtags':
data = self._rewritetags(source, revmap, data)
return context.memfilectx(self.repo, f, data, 'l' in mode,
@@ -191,7 +195,11 @@
while parents:
p1 = p2
p2 = parents.pop(0)
- ctx = context.memctx(self.repo, (p1, p2), text, files.keys(),
+ fileset = set(files)
+ if full:
+ fileset.update(self.repo[p1])
+ fileset.update(self.repo[p2])
+ ctx = context.memctx(self.repo, (p1, p2), text, fileset,
getfilectx, commit.author, commit.date, extra)
self.repo.commitctx(ctx)
text = "(octopus merge fixup)\n"
@@ -299,7 +307,7 @@
raise NoRepo(_("%s is not a local Mercurial repository") % path)
self.lastrev = None
self.lastctx = None
- self._changescache = None
+ self._changescache = None, None
self.convertfp = None
# Restrict converted revisions to startrev descendants
startnode = ui.config('convert', 'hg.startrev')
@@ -351,29 +359,28 @@
try:
fctx = self.changectx(rev)[name]
return fctx.data(), fctx.flags()
- except error.LookupError, err:
- raise IOError(err)
+ except error.LookupError:
+ return None, None
- def getchanges(self, rev):
+ def getchanges(self, rev, full):
ctx = self.changectx(rev)
parents = self.parents(ctx)
- if not parents:
- files = sorted(ctx.manifest())
- # getcopies() is not needed for roots, but it is a simple way to
- # detect missing revlogs and abort on errors or populate
- # self.ignored
- self.getcopies(ctx, parents, files)
- return [(f, rev) for f in files if f not in self.ignored], {}
- if self._changescache and self._changescache[0] == rev:
- m, a, r = self._changescache[1]
- else:
- m, a, r = self.repo.status(parents[0].node(), ctx.node())[:3]
- # getcopies() detects missing revlogs early, run it before
- # filtering the changes.
- copies = self.getcopies(ctx, parents, m + a)
- changes = [(name, rev) for name in m + a + r
- if name not in self.ignored]
- return sorted(changes), copies
+ if full or not parents:
+ files = copyfiles = ctx.manifest()
+ if parents:
+ if self._changescache[0] == rev:
+ m, a, r = self._changescache[1]
+ else:
+ m, a, r = self.repo.status(parents[0].node(), ctx.node())[:3]
+ if not full:
+ files = m + a + r
+ copyfiles = m + a
+ # getcopies() is also run for roots and before filtering so missing
+ # revlogs are detected early
+ copies = self.getcopies(ctx, parents, copyfiles)
+ changes = [(f, rev) for f in files if f not in self.ignored]
+ changes.sort()
+ return changes, copies
def getcopies(self, ctx, parents, files):
copies = {}
--- a/hgext/convert/monotone.py Wed Sep 03 20:42:51 2014 +0200
+++ b/hgext/convert/monotone.py Sun Sep 07 11:46:11 2014 -0500
@@ -224,7 +224,9 @@
else:
return [self.rev]
- def getchanges(self, rev):
+ def getchanges(self, rev, full):
+ if full:
+ raise util.Abort(_("convert from monotone do not support --full"))
revision = self.mtnrun("get_revision", rev).split("\n\n")
files = {}
ignoremove = {}
@@ -282,11 +284,11 @@
def getfile(self, name, rev):
if not self.mtnisfile(name, rev):
- raise IOError # file was deleted or renamed
+ return None, None
try:
data = self.mtnrun("get_file_of", name, r=rev)
except Exception:
- raise IOError # file was deleted or renamed
+ return None, None
self.mtnloadmanifest(rev)
node, attr = self.files.get(name, (None, ""))
return data, attr
--- a/hgext/convert/p4.py Wed Sep 03 20:42:51 2014 +0200
+++ b/hgext/convert/p4.py Sun Sep 07 11:46:11 2014 -0500
@@ -164,6 +164,8 @@
raise IOError(d["generic"], data)
elif code == "stat":
+ if d.get("action") == "purge":
+ return None, None
p4type = self.re_type.match(d["type"])
if p4type:
mode = ""
@@ -181,7 +183,7 @@
contents += data
if mode is None:
- raise IOError(0, "bad stat")
+ return None, None
if keywords:
contents = keywords.sub("$\\1$", contents)
@@ -190,7 +192,9 @@
return contents, mode
- def getchanges(self, rev):
+ def getchanges(self, rev, full):
+ if full:
+ raise util.Abort(_("convert from p4 do not support --full"))
return self.files[rev], {}
def getcommit(self, rev):
--- a/hgext/convert/subversion.py Wed Sep 03 20:42:51 2014 +0200
+++ b/hgext/convert/subversion.py Sun Sep 07 11:46:11 2014 -0500
@@ -347,7 +347,7 @@
% self.module)
self.last_changed = self.revnum(self.head)
- self._changescache = None
+ self._changescache = (None, None)
if os.path.exists(os.path.join(url, '.svn/entries')):
self.wc = url
@@ -444,34 +444,39 @@
return self.heads
- def getchanges(self, rev):
- if self._changescache and self._changescache[0] == rev:
- return self._changescache[1]
- self._changescache = None
+ def _getchanges(self, rev, full):
(paths, parents) = self.paths[rev]
+ copies = {}
if parents:
files, self.removed, copies = self.expandpaths(rev, paths, parents)
- else:
+ if full or not parents:
# Perform a full checkout on roots
uuid, module, revnum = revsplit(rev)
entries = svn.client.ls(self.baseurl + quote(module),
optrev(revnum), True, self.ctx)
files = [n for n, e in entries.iteritems()
if e.kind == svn.core.svn_node_file]
- copies = {}
self.removed = set()
files.sort()
files = zip(files, [rev] * len(files))
+ return (files, copies)
- # caller caches the result, so free it here to release memory
- del self.paths[rev]
+ def getchanges(self, rev, full):
+ # reuse cache from getchangedfiles
+ if self._changescache[0] == rev and not full:
+ (files, copies) = self._changescache[1]
+ else:
+ (files, copies) = self._getchanges(rev, full)
+ # caller caches the result, so free it here to release memory
+ del self.paths[rev]
return (files, copies)
def getchangedfiles(self, rev, i):
- changes = self.getchanges(rev)
- self._changescache = (rev, changes)
- return [f[0] for f in changes[0]]
+ # called from filemap - cache computed values for reuse in getchanges
+ (files, copies) = self._getchanges(rev, False)
+ self._changescache = (rev, (files, copies))
+ return [f[0] for f in files]
def getcommit(self, rev):
if rev not in self.commits:
@@ -490,10 +495,10 @@
self._fetch_revisions(revnum, stop)
if rev not in self.commits:
raise util.Abort(_('svn: revision %s not found') % revnum)
- commit = self.commits[rev]
+ revcommit = self.commits[rev]
# caller caches the result, so free it here to release memory
del self.commits[rev]
- return commit
+ return revcommit
def checkrevformat(self, revstr, mapname='splicemap'):
""" fails if revision format does not match the correct format"""
@@ -933,7 +938,7 @@
def getfile(self, file, rev):
# TODO: ra.get_file transmits the whole file instead of diffs.
if file in self.removed:
- raise IOError
+ return None, None
mode = ''
try:
new_module, revnum = revsplit(rev)[1:]
@@ -954,7 +959,7 @@
notfound = (svn.core.SVN_ERR_FS_NOT_FOUND,
svn.core.SVN_ERR_RA_DAV_PATH_NOT_FOUND)
if e.apr_err in notfound: # File not found
- raise IOError
+ return None, None
raise
if mode == 'l':
link_prefix = "link "
@@ -1211,23 +1216,13 @@
self.xargs(files, 'add', quiet=True)
return files
- def tidy_dirs(self, names):
- deleted = []
- for d in sorted(self.dirs_of(names), reverse=True):
- wd = self.wjoin(d)
- if os.listdir(wd) == '.svn':
- self.run0('delete', d)
- self.manifest.remove(d)
- deleted.append(d)
- return deleted
-
def addchild(self, parent, child):
self.childmap[parent] = child
def revid(self, rev):
return u"svn:%s@%s" % (self.uuid, rev)
- def putcommit(self, files, copies, parents, commit, source, revmap):
+ def putcommit(self, files, copies, parents, commit, source, revmap, full):
for parent in parents:
try:
return self.revid(self.childmap[parent])
@@ -1236,14 +1231,15 @@
# Apply changes to working copy
for f, v in files:
- try:
- data, mode = source.getfile(f, v)
- except IOError:
+ data, mode = source.getfile(f, v)
+ if data is None:
self.delete.append(f)
else:
self.putfile(f, mode, data)
if f in copies:
self.copies.append([copies[f], f])
+ if full:
+ self.delete.extend(sorted(self.manifest.difference(files)))
files = [f[0] for f in files]
entries = set(self.delete)
@@ -1259,7 +1255,6 @@
self.manifest.remove(f)
self.delete = []
entries.update(self.add_files(files.difference(entries)))
- entries.update(self.tidy_dirs(entries))
if self.delexec:
self.xargs(self.delexec, 'propdel', 'svn:executable')
self.delexec = []
--- a/hgext/extdiff.py Wed Sep 03 20:42:51 2014 +0200
+++ b/hgext/extdiff.py Sun Sep 07 11:46:11 2014 -0500
@@ -63,7 +63,7 @@
from mercurial.i18n import _
from mercurial.node import short, nullid
-from mercurial import cmdutil, scmutil, scmutil, util, commands, encoding
+from mercurial import cmdutil, scmutil, util, commands, encoding
import os, shlex, shutil, tempfile, re
cmdtable = {}
--- a/hgext/fetch.py Wed Sep 03 20:42:51 2014 +0200
+++ b/hgext/fetch.py Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/hgext/gpg.py Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/hgext/histedit.py Sun Sep 07 11:46:11 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
#
@@ -180,6 +182,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
#
@@ -209,8 +212,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]
@@ -283,7 +284,7 @@
isexec='x' in flags,
copied=copied.get(path))
return mctx
- raise IOError()
+ return None
if commitopts.get('message'):
message = commitopts['message']
@@ -294,6 +295,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,
@@ -302,7 +306,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):
@@ -335,6 +339,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())
@@ -357,10 +366,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())
@@ -401,9 +413,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,))]
@@ -440,6 +453,8 @@
'edit': edit,
'f': fold,
'fold': fold,
+ 'r': rollup,
+ 'roll': rollup,
'd': drop,
'drop': drop,
'm': message,
@@ -596,11 +611,10 @@
rules = f.read()
f.close()
rules = [l for l in (r.strip() for r in rules.splitlines())
- if l and not l[0] == '#']
+ if l and not l.startswith('#')]
rules = verifyrules(rules, repo, ctxs)
parentctx = repo[root].parents()[0]
- keep = opts.get('keep', False)
replacements = []
@@ -675,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(),
@@ -696,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 Wed Sep 03 20:42:51 2014 +0200
+++ b/hgext/keyword.py Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/hgext/largefiles/lfcommands.py Sun Sep 07 11:46:11 2014 -0500
@@ -146,7 +146,7 @@
try:
fctx = ctx.filectx(lfutil.standin(f))
except error.LookupError:
- raise IOError
+ return None
renamed = fctx.renamed()
if renamed:
renamed = lfutil.splitstandin(renamed[0])
@@ -248,7 +248,7 @@
try:
fctx = ctx.filectx(srcfname)
except error.LookupError:
- raise IOError
+ return None
renamed = fctx.renamed()
if renamed:
# standin is always a largefile because largefile-ness
@@ -298,7 +298,7 @@
try:
fctx = ctx.filectx(f)
except error.LookupError:
- raise IOError
+ return None
renamed = fctx.renamed()
if renamed:
renamed = renamed[0]
@@ -443,6 +443,7 @@
lfiles = set(lfutil.listlfiles(repo)) | set(lfdirstate)
if filelist is not None:
+ filelist = set(filelist)
lfiles = [f for f in lfiles if f in filelist]
update = {}
@@ -510,26 +511,20 @@
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)
+
+ if filelist is not None:
+ # If "local largefile" is chosen at file merging, it is
+ # not listed in "filelist" (= dirstate syncing is
+ # omitted), because the standin file is not changed before and
+ # after merging.
+ # But the status of such files may have to be changed by
+ # merging. For example, locally modified ("M") largefile
+ # has to become re-added("A"), if it is "normal" file in
+ # the target revision of linear-merging.
+ for lfile in lfdirstate:
+ if lfile not in filelist:
+ lfutil.synclfdirstate(repo, lfdirstate, lfile, True)
lfdirstate.write()
if printmessage and lfiles:
--- a/hgext/largefiles/lfutil.py Wed Sep 03 20:42:51 2014 +0200
+++ b/hgext/largefiles/lfutil.py Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/hgext/largefiles/overrides.py Sun Sep 07 11:46:11 2014 -0500
@@ -12,7 +12,7 @@
import copy
from mercurial import hg, commands, util, cmdutil, scmutil, match as match_, \
- archival, merge, pathutil, revset
+ archival, pathutil, revset
from mercurial.i18n import _
from mercurial.node import hex
from hgext import rebase
@@ -369,10 +369,6 @@
lfdirstate.write()
if mod:
raise util.Abort(_('uncommitted changes'))
- # XXX handle removed differently
- if not opts['clean']:
- for lfile in unsure + modified + added:
- lfutil.updatestandin(repo, lfutil.standin(lfile))
return orig(ui, repo, *pats, **opts)
finally:
wlock.release()
@@ -430,6 +426,7 @@
removes = set(a[0] for a in actions['r'])
newglist = []
+ lfmr = [] # LargeFiles: Mark as Removed
for action in actions['g']:
f, args, msg = action
splitstandin = f and lfutil.splitstandin(f)
@@ -456,7 +453,16 @@
'keep (l)argefile or use (n)ormal file?'
'$$ &Largefile $$ &Normal file') % lfile
if repo.ui.promptchoice(msg, 0) == 0:
- actions['r'].append((lfile, None, msg))
+ if branchmerge:
+ # largefile can be restored from standin safely
+ actions['r'].append((lfile, None, msg))
+ else:
+ # "lfile" should be marked as "removed" without
+ # removal of itself
+ lfmr.append((lfile, None, msg))
+
+ # linear-merge should treat this largefile as 're-added'
+ actions['a'].append((standin, None, msg))
else:
actions['r'].append((standin, None, msg))
newglist.append((lfile, (p2.flags(lfile),), msg))
@@ -465,9 +471,22 @@
newglist.sort()
actions['g'] = newglist
+ if lfmr:
+ lfmr.sort()
+ actions['lfmr'] = lfmr
return actions
+def mergerecordupdates(orig, repo, actions, branchmerge):
+ if 'lfmr' in actions:
+ # this should be executed before 'orig', to execute 'remove'
+ # before all other actions
+ for lfile, args, msg in actions['lfmr']:
+ repo.dirstate.remove(lfile)
+
+ return orig(repo, actions, branchmerge)
+
+
# Override filemerge to prompt the user about how they wish to merge
# largefiles. This will handle identical edits without prompting the user.
def overridefilemerge(origfn, repo, mynode, orig, fcd, fco, fca, labels=None):
@@ -695,25 +714,6 @@
finally:
wlock.release()
-def hgupdaterepo(orig, repo, node, overwrite):
- if not overwrite:
- # Only call updatelfiles on the standins that have changed to save time
- oldstandins = lfutil.getstandinsstate(repo)
-
- result = orig(repo, node, overwrite)
-
- filelist = None
- if not overwrite:
- newstandins = lfutil.getstandinsstate(repo)
- filelist = lfutil.getlfilestoupdate(oldstandins, newstandins)
- lfcommands.updatelfiles(repo.ui, repo, filelist=filelist)
- return result
-
-def hgmerge(orig, repo, node, force=None, remind=True):
- result = orig(repo, node, force, remind)
- lfcommands.updatelfiles(repo.ui, repo)
- return result
-
# When we rebase a repository with remotely changed largefiles, we need to
# take some extra care so that the largefiles are correctly updated in the
# working copy
@@ -1157,19 +1157,40 @@
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:
+ before = repo.dirstate.parents()
+ orphans = set(f for f in repo.dirstate
+ if lfutil.isstandin(f) and repo.dirstate[f] != 'r')
+ result = orig(ui, repo, **opts)
+ after = repo.dirstate.parents()
+ if before == after:
+ return result # no need to restore standins
+
+ pctx = repo['.']
+ for f in repo.dirstate:
+ if lfutil.isstandin(f):
+ orphans.discard(f)
+ if repo.dirstate[f] == 'r':
+ repo.wvfs.unlinkpath(f, ignoremissing=True)
+ elif f in pctx:
+ fctx = pctx[f]
+ repo.wwrite(f, fctx.data(), fctx.flags())
+ else:
+ # content of standin is not so important in 'a',
+ # 'm' or 'n' (coming from the 2nd parent) cases
+ lfutil.writestandin(repo, f, '', False)
+ for standin in orphans:
+ repo.wvfs.unlinkpath(standin, ignoremissing=True)
+
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()
@@ -1243,3 +1264,67 @@
def mercurialsinkafter(orig, sink):
sink.repo._isconverting = False
orig(sink)
+
+def mergeupdate(orig, repo, node, branchmerge, force, partial,
+ *args, **kwargs):
+ wlock = repo.wlock()
+ try:
+ # branch | | |
+ # merge | force | partial | action
+ # -------+-------+---------+--------------
+ # x | x | x | linear-merge
+ # o | x | x | branch-merge
+ # x | o | x | overwrite (as clean update)
+ # o | o | x | force-branch-merge (*1)
+ # x | x | o | (*)
+ # o | x | o | (*)
+ # x | o | o | overwrite (as revert)
+ # o | o | o | (*)
+ #
+ # (*) don't care
+ # (*1) deprecated, but used internally (e.g: "rebase --collapse")
+
+ linearmerge = not branchmerge and not force and not partial
+
+ if linearmerge or (branchmerge and force and not partial):
+ # update standins for linear-merge or force-branch-merge,
+ # because largefiles in the working directory may be modified
+ lfdirstate = lfutil.openlfdirstate(repo.ui, repo)
+ s = lfdirstate.status(match_.always(repo.root, repo.getcwd()),
+ [], False, False, False)
+ unsure, modified, added = s[:3]
+ for lfile in unsure + modified + added:
+ lfutil.updatestandin(repo, lfutil.standin(lfile))
+
+ if linearmerge:
+ # Only call updatelfiles on the standins that have changed
+ # to save time
+ oldstandins = lfutil.getstandinsstate(repo)
+
+ result = orig(repo, node, branchmerge, force, partial, *args, **kwargs)
+
+ filelist = None
+ if linearmerge:
+ newstandins = lfutil.getstandinsstate(repo)
+ filelist = lfutil.getlfilestoupdate(oldstandins, newstandins)
+
+ # suppress status message while automated committing
+ printmessage = not (getattr(repo, "_isrebasing", False) or
+ getattr(repo, "_istransplanting", False))
+ lfcommands.updatelfiles(repo.ui, repo, filelist=filelist,
+ printmessage=printmessage,
+ normallookup=partial)
+
+ return result
+ finally:
+ wlock.release()
+
+def scmutilmarktouched(orig, repo, files, *args, **kwargs):
+ result = orig(repo, files, *args, **kwargs)
+
+ filelist = [lfutil.splitstandin(f) for f in files if lfutil.isstandin(f)]
+ if filelist:
+ lfcommands.updatelfiles(repo.ui, repo, filelist=filelist,
+ printmessage=False, normallookup=True)
+
+ return result
--- a/hgext/largefiles/reposetup.py Wed Sep 03 20:42:51 2014 +0200
+++ b/hgext/largefiles/reposetup.py Sun Sep 07 11:46:11 2014 -0500
@@ -272,19 +272,29 @@
wlock = self.wlock()
try:
- # Case 0: Rebase or Transplant
- # We have to take the time to pull down the new largefiles now.
- # Otherwise, any largefiles that were modified in the
- # destination changesets get overwritten, either by the rebase
- # or in the first commit after the rebase or transplant.
- # updatelfiles will update the dirstate to mark any pulled
- # largefiles as modified
+ # Case 0: Automated committing
+ #
+ # While automated committing (like rebase, transplant
+ # and so on), this code path is used to avoid:
+ # (1) updating standins, because standins should
+ # be already updated at this point
+ # (2) aborting when stadnins are matched by "match",
+ # because automated committing may specify them directly
+ #
if getattr(self, "_isrebasing", False) or \
getattr(self, "_istransplanting", False):
- lfcommands.updatelfiles(self.ui, self, filelist=None,
- 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/largefiles/uisetup.py Wed Sep 03 20:42:51 2014 +0200
+++ b/hgext/largefiles/uisetup.py Sun Sep 07 11:46:11 2014 -0500
@@ -99,6 +99,10 @@
overrides.overridecheckunknownfile)
entry = extensions.wrapfunction(merge, 'calculateupdates',
overrides.overridecalculateupdates)
+ entry = extensions.wrapfunction(merge, 'recordupdates',
+ overrides.mergerecordupdates)
+ entry = extensions.wrapfunction(merge, 'update',
+ overrides.mergeupdate)
entry = extensions.wrapfunction(filemerge, 'filemerge',
overrides.overridefilemerge)
entry = extensions.wrapfunction(cmdutil, 'copy',
@@ -115,15 +119,15 @@
entry = extensions.wrapfunction(commands, 'revert',
overrides.overriderevert)
- extensions.wrapfunction(hg, 'updaterepo', overrides.hgupdaterepo)
- extensions.wrapfunction(hg, 'merge', overrides.hgmerge)
-
extensions.wrapfunction(archival, 'archive', overrides.overridearchive)
extensions.wrapfunction(subrepo.hgsubrepo, 'archive',
overrides.hgsubrepoarchive)
extensions.wrapfunction(cmdutil, 'bailifchanged',
overrides.overridebailifchanged)
+ extensions.wrapfunction(scmutil, 'marktouched',
+ overrides.scmutilmarktouched)
+
# create the new wireproto commands ...
wireproto.commands['putlfile'] = (proto.putlfile, 'sha')
wireproto.commands['getlfile'] = (proto.getlfile, 'sha')
--- a/hgext/mq.py Wed Sep 03 20:42:51 2014 +0200
+++ b/hgext/mq.py Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/hgext/purge.py Sun Sep 07 11:46:11 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,27 +95,17 @@
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
+ if removedirs:
+ directories = []
+ match.explicitdir = match.traversedir = directories.append
status = repo.status(match=match, ignored=opts['all'], unknown=True)
if removefiles:
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 Wed Sep 03 20:42:51 2014 +0200
+++ b/hgext/rebase.py Sun Sep 07 11:46:11 2014 -0500
@@ -138,7 +138,6 @@
skipped = set()
targetancestors = set()
- editor = cmdutil.getcommiteditor(**opts)
lock = wlock = None
try:
@@ -354,6 +353,9 @@
p1rev = repo[rev].p1().rev()
cmdutil.duplicatecopies(repo, rev, p1rev, skiprev=target)
if not collapsef:
+ merging = repo[p2].rev() != nullrev
+ editform = cmdutil.mergeeditform(merging, 'rebase')
+ editor = cmdutil.getcommiteditor(editform=editform, **opts)
newrev = concludenode(repo, rev, p1, p2, extrafn=extrafn,
editor=editor)
else:
@@ -376,6 +378,8 @@
if collapsef and not keepopen:
p1, p2 = defineparents(repo, min(state), target,
state, targetancestors)
+ editopt = opts.get('edit')
+ editform = 'rebase.collapse'
if collapsemsg:
commitmsg = collapsemsg
else:
@@ -383,7 +387,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)
+ editopt = True
+ editor = cmdutil.getcommiteditor(edit=editopt, editform=editform)
newrev = concludenode(repo, rev, p1, external, commitmsg=commitmsg,
extrafn=extrafn, editor=editor)
for oldrev in state.iterkeys():
@@ -468,15 +473,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 Wed Sep 03 20:42:51 2014 +0200
+++ b/hgext/shelve.py Sun Sep 07 11:46:11 2014 -0500
@@ -25,7 +25,7 @@
from mercurial.node import nullid, nullrev, bin, hex
from mercurial import changegroup, cmdutil, scmutil, phases, commands
from mercurial import error, hg, mdiff, merge, patch, repair, util
-from mercurial import templatefilters, changegroup, exchange
+from mercurial import templatefilters, exchange
from mercurial import lock as lockmod
from hgext import rebase
import errno
@@ -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))
@@ -266,7 +269,7 @@
wlock = None
try:
wlock = repo.wlock()
- for (name, _) in repo.vfs.readdir('shelved'):
+ for (name, _type) in repo.vfs.readdir('shelved'):
suffix = name.rsplit('.', 1)[-1]
if suffix in ('hg', 'files', 'patch'):
shelvedfile(repo, name).unlink()
@@ -300,7 +303,7 @@
raise
return []
info = []
- for (name, _) in names:
+ for (name, _type) in names:
pfx, sfx = name.rsplit('.', 1)
if not pfx or sfx != 'patch':
continue
@@ -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:
@@ -410,9 +413,11 @@
for file in u:
if file in files:
util.rename(file, file + ".orig")
+ ui.pushbuffer(True)
cmdutil.revert(ui, repo, shelvectx, repo.dirstate.parents(),
*pathtofiles(repo, files),
**{'no_backup': True})
+ ui.popbuffer()
finally:
ui.quiet = oldquiet
@@ -457,7 +462,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 +563,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 +582,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 Wed Sep 03 20:42:51 2014 +0200
+++ b/hgext/strip.py Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/hgext/transplant.py Sun Sep 07 11:46:11 2014 -0500
@@ -86,7 +86,10 @@
self.opener = scmutil.opener(self.path)
self.transplants = transplants(self.path, 'transplants',
opener=self.opener)
- self.editor = cmdutil.getcommiteditor(**opts)
+ def getcommiteditor():
+ editform = cmdutil.mergeeditform(repo[None], 'transplant')
+ return cmdutil.getcommiteditor(editform=editform, **opts)
+ self.getcommiteditor = getcommiteditor
def applied(self, repo, node, parent):
'''returns True if a node is already an ancestor of parent
@@ -286,7 +289,7 @@
m = match.exact(repo.root, '', files)
n = repo.commit(message, user, date, extra=extra, match=m,
- editor=self.editor)
+ editor=self.getcommiteditor())
if not n:
self.ui.warn(_('skipping emptied changeset %s\n') % short(node))
return None
@@ -342,7 +345,7 @@
if merge:
repo.setparents(p1, parents[1])
n = repo.commit(message, user, date, extra=extra,
- editor=self.editor)
+ editor=self.getcommiteditor())
if not n:
raise util.Abort(_('commit failed'))
if not merge:
--- a/i18n/check-translation.py Wed Sep 03 20:42:51 2014 +0200
+++ b/i18n/check-translation.py Sun Sep 07 11:46:11 2014 -0500
@@ -7,7 +7,7 @@
checkers = []
-def checker(level, msgidpat):
+def levelchecker(level, msgidpat):
def decorator(func):
if msgidpat:
match = re.compile(msgidpat).search
@@ -33,7 +33,7 @@
####################
def fatalchecker(msgidpat=None):
- return checker('fatal', msgidpat)
+ return levelchecker('fatal', msgidpat)
@fatalchecker(r'\$\$')
def promptchoice(pe):
@@ -64,7 +64,7 @@
####################
def warningchecker(msgidpat=None):
- return checker('warning', msgidpat)
+ return levelchecker('warning', msgidpat)
@warningchecker()
def taildoublecolons(pe):
--- a/mercurial/ancestor.py Wed Sep 03 20:42:51 2014 +0200
+++ b/mercurial/ancestor.py Sun Sep 07 11:46:11 2014 -0500
@@ -246,6 +246,14 @@
else:
self._containsseen = set()
+ def __nonzero__(self):
+ """False if the set is empty, True otherwise."""
+ try:
+ iter(self).next()
+ return True
+ except StopIteration:
+ return False
+
def __iter__(self):
"""Generate the ancestors of _initrevs in reverse topological order.
--- a/mercurial/bookmarks.py Wed Sep 03 20:42:51 2014 +0200
+++ b/mercurial/bookmarks.py Sun Sep 07 11:46:11 2014 -0500
@@ -228,7 +228,8 @@
w = repo.wlock()
try:
marks = repo._bookmarks
- if hex(marks.get(key, '')) != old:
+ existing = hex(marks.get(key, ''))
+ if existing != old and existing != new:
return False
if new == '':
del marks[key]
--- a/mercurial/branchmap.py Wed Sep 03 20:42:51 2014 +0200
+++ b/mercurial/branchmap.py Sun Sep 07 11:46:11 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,
@@ -241,6 +239,10 @@
newbranches.setdefault(branch, []).append(r)
if closesbranch:
self._closednodes.add(cl.node(r))
+
+ # fetch current topological heads to speed up filtering
+ topoheads = set(cl.headrevs())
+
# if older branchheads are reachable from new ones, they aren't
# really branchheads. Note checking parents is insufficient:
# 1 (branch a) -> 2 (branch b) -> 3 (branch a)
@@ -254,14 +256,13 @@
newheadrevs.sort()
bheadset.update(newheadrevs)
- # This loop prunes out two kinds of heads - heads that are
- # superseded by a head in newheadrevs, and newheadrevs that are not
- # heads because an existing head is their descendant.
- while newheadrevs:
- latest = newheadrevs.pop()
- if latest not in bheadset:
- continue
- ancestors = set(cl.ancestors([latest], min(bheadset)))
+ # This prunes out two kinds of heads - heads that are superseded by
+ # a head in newheadrevs, and newheadrevs that are not heads because
+ # an existing head is their descendant.
+ uncertain = bheadset - topoheads
+ if uncertain:
+ floorrev = min(uncertain)
+ ancestors = set(cl.ancestors(newheadrevs, floorrev))
bheadset -= ancestors
bheadrevs = sorted(bheadset)
self[branch] = [cl.node(rev) for rev in bheadrevs]
--- a/mercurial/bundle2.py Wed Sep 03 20:42:51 2014 +0200
+++ b/mercurial/bundle2.py Sun Sep 07 11:46:11 2014 -0500
@@ -146,6 +146,7 @@
import struct
import urllib
import string
+import obsolete
import pushkey
import changegroup, error
@@ -775,6 +776,23 @@
self.consumed = True
return data
+capabilities = {'HG2X': (),
+ 'b2x:listkeys': (),
+ 'b2x:pushkey': (),
+ 'b2x:changegroup': (),
+ }
+
+def getrepocaps(repo):
+ """return the bundle2 capabilities for a given repo
+
+ Exists to allow extensions (like evolution) to mutate the capabilities.
+ """
+ caps = capabilities.copy()
+ if obsolete._enabled:
+ supportedformat = tuple('V%i' % v for v in obsolete.formats)
+ caps['b2x:obsmarkers'] = supportedformat
+ return caps
+
def bundle2caps(remote):
"""return the bundlecapabilities of a peer as dict"""
raw = remote.capable('bundle2-exp')
@@ -783,6 +801,12 @@
capsblob = urllib.unquote(remote.capable('bundle2-exp'))
return decodecaps(capsblob)
+def obsmarkersversion(caps):
+ """extract the list of supported obsmarkers versions from a bundle2caps dict
+ """
+ obscaps = caps.get('b2x:obsmarkers', ())
+ return [int(c[1:]) for c in obscaps if c.startswith('V')]
+
@parthandler('b2x:changegroup')
def handlechangegroup(op, inpart):
"""apply a changegroup part on the repo
@@ -899,3 +923,24 @@
ret = int(inpart.params['return'])
partid = int(inpart.params['in-reply-to'])
op.records.add('pushkey', {'return': ret}, partid)
+
+@parthandler('b2x:obsmarkers')
+def handleobsmarker(op, inpart):
+ """add a stream of obsmarkers to the repo"""
+ tr = op.gettransaction()
+ new = op.repo.obsstore.mergemarkers(tr, inpart.read())
+ if new:
+ op.repo.ui.status(_('%i new obsolescence markers\n') % new)
+ op.records.add('obsmarkers', {'new': new})
+ if op.reply is not None:
+ rpart = op.reply.newpart('b2x:reply:obsmarkers')
+ rpart.addparam('in-reply-to', str(inpart.id), mandatory=False)
+ rpart.addparam('new', '%i' % new, mandatory=False)
+
+
+@parthandler('b2x:reply:obsmarkers', ('new', 'in-reply-to'))
+def handlepushkeyreply(op, inpart):
+ """retrieve the result of a pushkey request"""
+ ret = int(inpart.params['new'])
+ partid = int(inpart.params['in-reply-to'])
+ op.records.add('obsmarkers', {'new': ret}, partid)
--- a/mercurial/changegroup.py Wed Sep 03 20:42:51 2014 +0200
+++ b/mercurial/changegroup.py Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/mercurial/cmdutil.py Sun Sep 07 11:46:11 2014 -0500
@@ -109,7 +109,25 @@
(logfile, inst.strerror))
return message
-def getcommiteditor(edit=False, finishdesc=None, extramsg=None, **opts):
+def mergeeditform(ctxorbool, baseform):
+ """build appropriate editform from ctxorbool and baseform
+
+ 'cxtorbool' is one of a ctx to be committed, or a bool whether
+ merging is committed.
+
+ This returns editform 'baseform' with '.merge' if merging is
+ committed, or one with '.normal' suffix otherwise.
+ """
+ if isinstance(ctxorbool, bool):
+ if ctxorbool:
+ return baseform + ".merge"
+ elif 1 < len(ctxorbool.parents()):
+ return baseform + ".merge"
+
+ return baseform + ".normal"
+
+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 +140,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 +150,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 +610,6 @@
tmpname, message, user, date, branch, nodeid, p1, p2 = \
patch.extract(ui, hunk)
- editor = getcommiteditor(**opts)
update = not opts.get('bypass')
strip = opts["strip"]
sim = float(opts.get('similarity') or 0)
@@ -667,6 +690,11 @@
m = None
else:
m = scmutil.matchfiles(repo, files or [])
+ editform = mergeeditform(repo[None], 'import.normal')
+ if opts.get('exact'):
+ editor = None
+ else:
+ editor = getcommiteditor(editform=editform, **opts)
n = repo.commit(message, opts.get('user') or user,
opts.get('date') or date, match=m,
editor=editor, force=partial)
@@ -683,12 +711,16 @@
files, eolmode=None)
except patch.PatchError, e:
raise util.Abort(str(e))
+ if opts.get('exact'):
+ editor = None
+ else:
+ 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()
@@ -1180,9 +1212,14 @@
for repl in marker.succnodes():
ui.write(' ')
ui.write(hex(repl))
- ui.write(' %X ' % marker._data[2])
+ ui.write(' %X ' % marker.flags())
+ parents = marker.parentnodes()
+ if parents is not None:
+ ui.write('{%s} ' % ', '.join(hex(p) for p in parents))
+ ui.write('(%s) ' % util.datestr(marker.date()))
ui.write('{%s}' % (', '.join('%r: %r' % t for t in
- sorted(marker.metadata().items()))))
+ sorted(marker.metadata().items())
+ if t[0] != 'date')))
ui.write('\n')
def finddate(ui, repo, date):
@@ -1578,8 +1615,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
@@ -1603,9 +1646,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
@@ -1637,7 +1677,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(),
@@ -2091,7 +2134,7 @@
copied=copied.get(path))
return mctx
except KeyError:
- raise IOError
+ return None
else:
ui.note(_('copying changeset %s to %s\n') % (old, base))
@@ -2100,13 +2143,14 @@
try:
return old.filectx(path)
except KeyError:
- raise IOError
+ return None
user = opts.get('user') or old.user()
date = opts.get('date') or old.date()
- editor = getcommiteditor(**opts)
+ editform = mergeeditform(old, '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()
@@ -2180,24 +2224,31 @@
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)
# run editor in the repository root
olddir = os.getcwd()
os.chdir(repo.root)
- text = repo.ui.edit(committext, ctx.user(), ctx.extra())
+ text = repo.ui.edit(committext, ctx.user(), ctx.extra(), editform=editform)
text = re.sub("(?m)^HG:.*(\n|$)", "", text)
os.chdir(olddir)
@@ -2217,6 +2268,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
@@ -2351,17 +2406,89 @@
# 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,
+ unknown=True, ignored=True, clean=True)
+ modified = set(changes[0])
+ added = set(changes[1])
+ removed = set(changes[2])
+ _deleted = set(changes[3])
+ unknown = set(changes[4])
+ unknown.update(changes[5])
+ clean = set(changes[6])
+
+ # split between files known in target manifest and the others
+ smf = set(mf)
+
+ # determine the exact nature of the deleted changesets
+ _deletedadded = _deleted - smf
+ _deletedmodified = _deleted - _deletedadded
+ added |= _deletedadded
+ modified |= _deletedmodified
+
+ # 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])
+
+ # only take into account for removes between wc and target
+ clean |= dsremoved - removed
+ dsremoved &= removed
+ # distinct between dirstate remove and other
+ removed -= dsremoved
+
+ # tell newly modified apart.
+ dsmodified &= modified
+ dsmodified |= modified & dsadded # dirstate added may needs backup
+ modified -= dsmodified
+
+ # There are three categories of added files
+ #
+ # 1. addition that just happened in the dirstate
+ # (should be forgotten)
+ # 2. file is added since target revision and has local changes
+ # (should be backed up and removed)
+ # 3. file is added since target revision and is clean
+ # (should be removed)
+ #
+ # However we do not need to split them yet. The current revert code
+ # will automatically recognize (1) when performing operation. And
+ # the backup system is currently unabled to handle (2).
+ #
+ # So we just put them all in the same group.
+ dsadded = added
+
+ # in case of merge, files that are actually added can be reported as
+ # modified, we need to post process the result
+ if p2 != nullid:
+ if pmf is None:
+ # only need parent manifest in the merge case,
+ # so do not read by default
+ pmf = repo[parent].manifest()
+ mergeadd = dsmodified - set(pmf)
+ dsadded |= mergeadd
+ dsmodified -= mergeadd
# 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)
+ # XXX should we check for rename down to target node?
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.
@@ -2376,86 +2503,56 @@
actions = {'revert': ([], _('reverting %s\n')),
'add': ([], _('adding %s\n')),
'remove': ([], removeforget),
- 'undelete': ([], _('undeleting %s\n'))}
+ 'undelete': ([], _('undeleting %s\n')),
+ 'noop': (None, _('no changes needed to %s\n')),
+ 'unknown': (None, _('file not managed: %s\n')),
+ }
+
+
+ # should we do a backup?
+ backup = not opts.get('no_backup')
+ discard = False
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
+ (modified, actions['revert'], discard),
+ (dsmodified, actions['revert'], backup),
+ (dsadded, actions['remove'], backup),
+ (removed, actions['add'], backup),
+ (dsremoved, actions['undelete'], backup),
+ (clean, actions['noop'], discard),
+ (unknown, actions['unknown'], discard),
)
for abs, (rel, exact) in sorted(names.items()):
- # hash on file in target manifest (or None if missing from target)
- mfentry = mf.get(abs)
# target file to be touch on disk (relative to cwd)
target = repo.wjoin(abs)
- def handle(xlist, dobackup):
- xlist[0].append(abs)
- if (dobackup and not opts.get('no_backup') and
- os.path.lexists(target) and
- abs in ctx and repo[None][abs].cmp(ctx[abs])):
- bakname = "%s.orig" % rel
- ui.note(_('saving current version of %s as %s\n') %
- (rel, bakname))
- if not opts.get('dry_run'):
- util.rename(target, bakname)
- if ui.verbose or not exact:
- msg = xlist[1]
- if not isinstance(msg, basestring):
- msg = msg(abs)
- ui.status(msg % rel)
# search the entry in the dispatch table.
- # if the file is in any of this sets, it was touched in the working
+ # if the file is in any of these 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, (xlist, msg), dobackup 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 xlist is not None:
+ xlist.append(abs)
+ if (dobackup and os.path.lexists(target) and
+ abs in ctx and repo[None][abs].cmp(ctx[abs])):
+ bakname = "%s.orig" % rel
+ ui.note(_('saving current version of %s as %s\n') %
+ (rel, bakname))
+ if not opts.get('dry_run'):
+ util.rename(target, bakname)
+ if ui.verbose or not exact:
+ if not isinstance(msg, basestring):
+ msg = msg(abs)
+ ui.status(msg % rel)
+ elif exact:
+ ui.warn(msg % rel)
break
- else:
- # Not touched in current dirstate.
-
- # file is unknown in parent, restore older version or ignore.
- if abs not in repo.dirstate:
- if mfentry:
- handle(actions['add'], True)
- elif exact:
- ui.warn(_('file not managed: %s\n') % rel)
- continue
- # parent is target, no changes mean no changes
- if node == parent:
- if exact:
- ui.warn(_('no changes needed to %s\n') % rel)
- continue
- # no change in dirstate but parent and target may differ
- if pmf is None:
- # only need parent manifest in this unlikely case,
- # so do not read by default
- pmf = repo[parent].manifest()
- if abs in pmf and mfentry:
- # if version of file is same in parent and target
- # manifests, do nothing
- if (pmf[abs] != mfentry or
- pmf.flags(abs) != mf.flags(abs)):
- handle(actions['revert'], False)
- else:
- handle(actions['remove'], False)
if not opts.get('dry_run'):
_performrevert(repo, parents, ctx, actions)
--- a/mercurial/commands.py Wed Sep 03 20:42:51 2014 +0200
+++ b/mercurial/commands.py Sun Sep 07 11:46:11 2014 -0500
@@ -260,6 +260,9 @@
Returns 0 on success.
"""
+ if not pats:
+ raise util.Abort(_('at least one filename or pattern is required'))
+
if opts.get('follow'):
# --follow is deprecated and now just an alias for -f/--file
# to mimic the behavior of Mercurial before version 1.5
@@ -267,10 +270,6 @@
datefunc = ui.quiet and util.shortdate or util.datestr
getdate = util.cachefunc(lambda x: datefunc(x[0].date()))
-
- if not pats:
- raise util.Abort(_('at least one filename or pattern is required'))
-
hexfn = ui.debugflag and hex or short
opmap = [('user', ' ', lambda x: ui.shortuser(x[0].user())),
@@ -505,11 +504,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 +1385,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 +1438,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 = cmdutil.mergeeditform(repo[None], '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)
@@ -1912,8 +1912,8 @@
revs = set((int(r) for r in revs))
def events():
for r in rlog:
- yield 'n', (r, list(set(p for p in rlog.parentrevs(r)
- if p != -1)))
+ yield 'n', (r, list(p for p in rlog.parentrevs(r)
+ if p != -1))
if r in revs:
yield 'l', (r, "r%i" % r)
elif repo:
@@ -1932,8 +1932,8 @@
if newb != b:
yield 'a', newb
b = newb
- yield 'n', (r, list(set(p for p in cl.parentrevs(r)
- if p != -1)))
+ yield 'n', (r, list(p for p in cl.parentrevs(r)
+ if p != -1))
if tags:
ls = labels.get(r)
if ls:
@@ -2315,6 +2315,9 @@
@command('debugobsolete',
[('', 'flags', 0, _('markers flag')),
+ ('', 'record-parents', False,
+ _('record parent information for the precursor')),
+ ('r', 'rev', [], _('display markers relevant to REV')),
] + commitopts2,
_('[OBSOLETED [REPLACEMENT] [REPL... ]'))
def debugobsolete(ui, repo, precursor=None, *successors, **opts):
@@ -2336,9 +2339,9 @@
'node identifiers')
if precursor is not None:
+ if opts['rev']:
+ raise util.Abort('cannot select revision when creating marker')
metadata = {}
- if 'date' in opts:
- metadata['date'] = opts['date']
metadata['user'] = opts['user'] or ui.username()
succs = tuple(parsenodeid(succ) for succ in successors)
l = repo.lock()
@@ -2346,8 +2349,22 @@
tr = repo.transaction('debugobsolete')
try:
try:
- repo.obsstore.create(tr, parsenodeid(precursor), succs,
- opts['flags'], metadata)
+ date = opts.get('date')
+ if date:
+ date = util.parsedate(date)
+ else:
+ date = None
+ prec = parsenodeid(precursor)
+ parents = None
+ if opts['record_parents']:
+ if prec not in repo.unfiltered():
+ raise util.Abort('cannot used --record-parents on '
+ 'unknown changesets')
+ parents = repo.unfiltered()[prec].parents()
+ parents = tuple(p.node() for p in parents)
+ repo.obsstore.create(tr, prec, succs, opts['flags'],
+ parents=parents, date=date,
+ metadata=metadata)
tr.close()
except ValueError, exc:
raise util.Abort(_('bad obsmarker input: %s') % exc)
@@ -2356,7 +2373,15 @@
finally:
l.release()
else:
- for m in obsolete.allmarkers(repo):
+ if opts['rev']:
+ revs = scmutil.revrange(repo, opts['rev'])
+ nodes = [repo[r].node() for r in revs]
+ markers = list(obsolete.getmarkers(repo, nodes=nodes))
+ markers.sort(key=lambda x: x._data)
+ else:
+ markers = obsolete.getmarkers(repo)
+
+ for m in markers:
cmdutil.showmarker(ui, m)
@command('debugpathcomplete',
@@ -2518,24 +2543,36 @@
if opts.get("dump"):
numrevs = len(r)
ui.write("# rev p1rev p2rev start end deltastart base p1 p2"
- " rawsize totalsize compression heads\n")
+ " rawsize totalsize compression heads chainlen\n")
ts = 0
heads = set()
+ rindex = r.index
+
+ def chainbaseandlen(rev):
+ clen = 0
+ base = rindex[rev][3]
+ while base != rev:
+ clen += 1
+ rev = base
+ base = rindex[rev][3]
+ return base, clen
+
for rev in xrange(numrevs):
dbase = r.deltaparent(rev)
if dbase == -1:
dbase = rev
- cbase = r.chainbase(rev)
+ cbase, clen = chainbaseandlen(rev)
p1, p2 = r.parentrevs(rev)
rs = r.rawsize(rev)
ts = ts + rs
heads -= set(r.parentrevs(rev))
heads.add(rev)
- ui.write("%5d %5d %5d %5d %5d %10d %4d %4d %4d %7d %9d %11d %5d\n" %
+ ui.write("%5d %5d %5d %5d %5d %10d %4d %4d %4d %7d %9d "
+ "%11d %5d %8d\n" %
(rev, p1, p2, r.start(rev), r.end(rev),
r.start(dbase), r.start(cbase),
r.start(p1), r.start(p2),
- rs, ts, ts / r.end(rev), len(heads)))
+ rs, ts, ts / r.end(rev), len(heads), clen))
return 0
v = r.version
@@ -3064,6 +3101,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,
@@ -3087,6 +3125,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
@@ -3094,7 +3136,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
@@ -3131,7 +3174,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']:
@@ -3160,61 +3203,68 @@
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:
- try:
- r = repo[n].rev()
- except error.RepoLookupError:
- r = None
- 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:
+ try:
+ r = repo[n].rev()
+ except error.RepoLookupError:
+ r = None
+ if r in revs:
+ ui.warn(_('skipping revision %s (already grafted to %s)\n')
+ % (r, rev))
+ revs.remove(r)
+ elif ids[n] in revs:
+ if r is None:
+ ui.warn(_('skipping already grafted revision %s '
+ '(%s also has unknown origin %s)\n')
+ % (ids[n], rev, n))
+ else:
+ 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:
- if r is None:
- ui.warn(_('skipping already grafted revision %s '
- '(%s also has unknown origin %s)\n')
- % (ids[n], rev, n))
- else:
- 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:
@@ -3858,6 +3908,8 @@
raise util.Abort(_('similarity must be between 0 and 100'))
if sim and not update:
raise util.Abort(_('cannot use --similarity with --bypass'))
+ if opts.get('exact') and opts.get('edit'):
+ raise util.Abort(_('cannot use --exact with --edit'))
if update:
cmdutil.checkunfinished(repo)
@@ -4046,11 +4098,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:
@@ -4579,17 +4631,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
@@ -5593,7 +5650,7 @@
ui.write(_('commit: %s\n') % t.strip())
# all ancestors of branch heads - all ancestors of parent = new csets
- new = len(repo.changelog.findmissing([ctx.node() for ctx in parents],
+ new = len(repo.changelog.findmissing([pctx.node() for pctx in parents],
bheads))
if new == 0:
@@ -5804,7 +5861,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 Wed Sep 03 20:42:51 2014 +0200
+++ b/mercurial/config.py Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/mercurial/context.py Sun Sep 07 11:46:11 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,
@@ -347,7 +347,10 @@
def makememctx(repo, parents, text, user, date, branch, files, store,
editor=None):
def getfilectx(repo, memctx, path):
- data, (islink, isexec), copied = store.getfile(path)
+ data, mode, copied = store.getfile(path)
+ if data is None:
+ return None
+ islink, isexec = mode
return memfilectx(repo, path, data, islink=islink, isexec=isexec,
copied=copied, memctx=memctx)
extra = {}
@@ -600,6 +603,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
@@ -713,6 +719,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
@@ -730,9 +740,9 @@
return True
def parents(self):
- p = self._path
+ _path = self._path
fl = self._filelog
- pl = [(p, n, fl) for n in self._filelog.parents(self._filenode)]
+ pl = [(_path, n, fl) for n in self._filelog.parents(self._filenode)]
r = self._filelog.renamed(self._filenode)
if r:
@@ -762,19 +772,16 @@
this returns fixed value(False is used) as linenumber,
if "linenumber" parameter is "False".'''
- def decorate_compat(text, rev):
- return ([rev] * len(text.splitlines()), text)
-
- def without_linenumber(text, rev):
- return ([(rev, False)] * len(text.splitlines()), text)
-
- def with_linenumber(text, rev):
- size = len(text.splitlines())
- return ([(rev, i) for i in xrange(1, size + 1)], text)
-
- decorate = (((linenumber is None) and decorate_compat) or
- (linenumber and with_linenumber) or
- without_linenumber)
+ if linenumber is None:
+ def decorate(text, rev):
+ return ([rev] * len(text.splitlines()), text)
+ elif linenumber:
+ def decorate(text, rev):
+ size = len(text.splitlines())
+ return ([(rev, i) for i in xrange(1, size + 1)], text)
+ else:
+ def decorate(text, rev):
+ return ([(rev, False)] * len(text.splitlines()), text)
def pair(parent, child):
blocks = mdiff.allblocks(parent[1], child[1], opts=diffopts,
@@ -1146,6 +1153,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]):
@@ -1548,6 +1558,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().
@@ -1575,6 +1593,12 @@
supported by util.parsedate() and defaults to current date, extra
is a dictionary of metadata or is left empty.
"""
+
+ # Mercurial <= 3.1 expects the filectxfn to raise IOError for missing files.
+ # Extensions that need to retain compatibility across Mercurial 3.1 can use
+ # this field to determine what to do in filectxfn.
+ _returnnoneformissingfiles = True
+
def __init__(self, repo, parents, text, files, filectxfn, user=None,
date=None, extra=None, editor=False):
super(memctx, self).__init__(repo, text, user, date, extra)
@@ -1588,6 +1612,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'
@@ -1597,7 +1635,9 @@
self._repo.savecommitmessage(self._text)
def filectx(self, path, filelog=None):
- """get a file context from the working directory"""
+ """get a file context from the working directory
+
+ Returns None if file doesn't exist and should be removed."""
return self._filectxfn(self._repo, self, path)
def commit(self):
@@ -1615,7 +1655,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:
@@ -1652,9 +1692,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 Wed Sep 03 20:42:51 2014 +0200
+++ b/mercurial/dirstate.py Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/mercurial/dispatch.py Sun Sep 07 11:46:11 2014 -0500
@@ -58,6 +58,8 @@
if len(inst.args) > 1:
ferr.write(_("hg: parse error at %s: %s\n") %
(inst.args[1], inst.args[0]))
+ if (inst.args[0][0] == ' '):
+ ferr.write(_("unexpected leading whitespace\n"))
else:
ferr.write(_("hg: parse error: %s\n") % inst.args[0])
return -1
@@ -155,6 +157,8 @@
if len(inst.args) > 1:
ui.warn(_("hg: parse error at %s: %s\n") %
(inst.args[1], inst.args[0]))
+ if (inst.args[0][0] == ' '):
+ ui.warn(_("unexpected leading whitespace\n"))
else:
ui.warn(_("hg: parse error: %s\n") % inst.args[0])
return -1
@@ -331,17 +335,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 +381,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 +399,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 +407,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 +438,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/error.py Wed Sep 03 20:42:51 2014 +0200
+++ b/mercurial/error.py Sun Sep 07 11:46:11 2014 -0500
@@ -43,13 +43,13 @@
self.hint = kw.get('hint')
class ConfigError(Abort):
- 'Exception raised when parsing config files'
+ """Exception raised when parsing config files"""
class OutOfBandError(Exception):
- 'Exception raised when a remote repo reports failure'
+ """Exception raised when a remote repo reports failure"""
class ParseError(Exception):
- 'Exception raised when parsing config files (msg[, pos])'
+ """Exception raised when parsing config files (msg[, pos])"""
class RepoError(Exception):
def __init__(self, *args, **kw):
--- a/mercurial/exchange.py Wed Sep 03 20:42:51 2014 +0200
+++ b/mercurial/exchange.py Sun Sep 07 11:46:11 2014 -0500
@@ -37,6 +37,20 @@
else:
raise util.Abort(_('%s: unknown bundle version %s') % (fname, version))
+def buildobsmarkerspart(bundler, markers):
+ """add an obsmarker part to the bundler with <markers>
+
+ No part is created if markers is empty.
+ Raises ValueError if the bundler doesn't support any known obsmarker format.
+ """
+ if markers:
+ remoteversions = bundle2.obsmarkersversion(bundler.capabilities)
+ version = obsolete.commonversion(remoteversions)
+ if version is None:
+ raise ValueError('bundler do not support common obsmarker format')
+ stream = obsolete.encodemarkers(markers, True, version=version)
+ return bundler.newpart('B2X:OBSMARKERS', data=stream)
+ return None
class pushoperation(object):
"""A object that represent a single push operation
@@ -77,8 +91,59 @@
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()
+ # outgoing bookmarks
+ self.outbookmarks = []
+
+ @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,9 +201,9 @@
and pushop.remote.capable('bundle2-exp')):
_pushbundle2(pushop)
_pushchangeset(pushop)
- _pushcomputecommonheads(pushop)
_pushsyncphase(pushop)
_pushobsolete(pushop)
+ _pushbookmark(pushop)
finally:
if lock is not None:
lock.release()
@@ -146,11 +211,41 @@
if locallock is not None:
locallock.release()
- _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 +257,70 @@
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):
+ if (obsolete._enabled
+ and pushop.repo.obsstore
+ and 'obsolete' in pushop.remote.listkeys('namespaces')):
+ repo = pushop.repo
+ # very naive computation, that can be quite expensive on big repo.
+ # However: evolution is currently slow on them anyway.
+ nodes = (c.node() for c in repo.set('::%ln', pushop.futureheads))
+ pushop.outobsmarkers = pushop.repo.obsstore.relevantmarkers(nodes)
+
+@pushdiscovery('bookmarks')
+def _pushdiscoverybookmarks(pushop):
+ ui = pushop.ui
+ repo = pushop.repo.unfiltered()
+ remote = pushop.remote
+ ui.debug("checking for updated bookmarks\n")
+ ancestors = ()
+ if pushop.revs:
+ revnums = map(repo.changelog.rev, pushop.revs)
+ ancestors = repo.changelog.ancestors(revnums, inclusive=True)
+ remotebookmark = remote.listkeys('bookmarks')
+
+ comp = bookmarks.compare(repo, repo._bookmarks, remotebookmark, srchex=hex)
+ addsrc, adddst, advsrc, advdst, diverge, differ, invalid = comp
+ for b, scid, dcid in advsrc:
+ if not ancestors or repo[scid].rev() in ancestors:
+ pushop.outbookmarks.append((b, dcid, scid))
+
def _pushcheckoutgoing(pushop):
outgoing = pushop.outgoing
unfi = pushop.repo.unfiltered()
@@ -201,6 +360,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
@@ -210,7 +394,6 @@
return
pushop.stepsdone.add('changesets')
# Send known heads to the server for race detection.
- pushop.stepsdone.add('changesets')
if not _pushcheckoutgoing(pushop):
return
pushop.repo.prepushoutgoinghooks(pushop.repo,
@@ -227,8 +410,82 @@
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
+
+@b2partsgenerator('obsmarkers')
+def _pushb2obsmarkers(pushop, bundler):
+ if 'obsmarkers' in pushop.stepsdone:
+ return
+ remoteversions = bundle2.obsmarkersversion(bundler.capabilities)
+ if obsolete.commonversion(remoteversions) is None:
+ return
+ pushop.stepsdone.add('obsmarkers')
+ if pushop.outobsmarkers:
+ buildobsmarkerspart(bundler, pushop.outobsmarkers)
+
+@b2partsgenerator('bookmarks')
+def _pushb2bookmarks(pushop, bundler):
+ """handle phase push through bundle2"""
+ if 'bookmarks' in pushop.stepsdone:
+ return
+ b2caps = bundle2.bundle2caps(pushop.remote)
+ if 'b2x:pushkey' not in b2caps:
+ return
+ pushop.stepsdone.add('bookmarks')
+ part2book = []
+ enc = pushkey.encode
+ for book, old, new in pushop.outbookmarks:
+ part = bundler.newpart('b2x:pushkey')
+ part.addparam('namespace', enc('bookmarks'))
+ part.addparam('key', enc(book))
+ part.addparam('old', enc(old))
+ part.addparam('new', enc(new))
+ part2book.append((part.id, book))
+ def handlereply(op):
+ for partid, book in part2book:
+ partrep = op.records.getreplies(partid)
+ results = partrep['pushkey']
+ assert len(results) <= 1
+ if not results:
+ pushop.ui.warn(_('server ignored bookmark %s update\n') % book)
+ else:
+ ret = int(results[0]['return'])
+ if ret:
+ pushop.ui.status(_("updating bookmark %s\n") % book)
+ else:
+ pushop.ui.warn(_('updating bookmark %s failed!\n') % book)
+ return handlereply
+
def _pushbundle2(pushop):
"""push data to the remote using bundle2
@@ -237,10 +494,11 @@
evolve in the future."""
bundler = bundle2.bundle20(pushop.ui, bundle2.bundle2caps(pushop.remote))
# create reply capability
- capsblob = bundle2.encodecaps(pushop.repo.bundle2caps)
+ capsblob = bundle2.encodecaps(bundle2.getrepocaps(pushop.repo))
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 +565,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,19 +599,25 @@
_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
#
# This will eventually be unified with the changesets bundle2 push
bundler = bundle2.bundle20(pushop.ui, b2caps)
- capsblob = bundle2.encodecaps(pushop.repo.bundle2caps)
+ capsblob = bundle2.encodecaps(bundle2.getrepocaps(pushop.repo))
bundler.newpart('b2x:replycaps', data=capsblob)
part2node = []
enc = pushkey.encode
@@ -431,7 +660,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 +678,15 @@
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
- if (obsolete._enabled and repo.obsstore and
- 'obsolete' in remote.listkeys('namespaces')):
+ pushop.stepsdone.add('obsmarkers')
+ if pushop.outobsmarkers:
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]
@@ -461,20 +697,13 @@
def _pushbookmark(pushop):
"""Update bookmark position on remote"""
+ if pushop.ret == 0 or 'bookmarks' in pushop.stepsdone:
+ return
+ pushop.stepsdone.add('bookmarks')
ui = pushop.ui
- repo = pushop.repo.unfiltered()
remote = pushop.remote
- ui.debug("checking for updated bookmarks\n")
- revnums = map(repo.changelog.rev, pushop.revs or [])
- ancestors = [a for a in repo.changelog.ancestors(revnums, inclusive=True)]
- (addsrc, adddst, advsrc, advdst, diverge, differ, invalid
- ) = bookmarks.compare(repo, repo._bookmarks, remote.listkeys('bookmarks'),
- srchex=hex)
-
- for b, scid, dcid in advsrc:
- if ancestors and repo[scid].rev() not in ancestors:
- continue
- if remote.pushkey('bookmarks', b, dcid, scid):
+ for b, old, new in pushop.outbookmarks:
+ if remote.pushkey('bookmarks', b, old, new):
ui.status(_("updating bookmark %s\n") % b)
else:
ui.warn(_('updating bookmark %s failed!\n') % b)
@@ -597,6 +826,7 @@
kwargs['common'] = pullop.common
kwargs['heads'] = pullop.heads or pullop.rheads
+ kwargs['cg'] = pullop.fetch
if 'b2x:listkeys' in remotecaps:
kwargs['listkeys'] = ['phase']
if not pullop.fetch:
@@ -605,6 +835,11 @@
else:
if pullop.heads is None and list(pullop.common) == [nullid]:
pullop.repo.ui.status(_("requesting all changes\n"))
+ if obsolete._enabled:
+ remoteversions = bundle2.obsmarkersversion(remotecaps)
+ if obsolete.commonversion(remoteversions) is not None:
+ kwargs['obsmarkers'] = True
+ pullop.todosteps.remove('obsmarkers')
_pullbundle2extraprepare(pullop, kwargs)
if kwargs.keys() == ['format']:
return # nothing to pull
@@ -673,14 +908,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
@@ -707,7 +957,7 @@
def caps20to10(repo):
"""return a set with appropriate options to use bundle20 during getbundle"""
caps = set(['HG2X'])
- capsblob = bundle2.encodecaps(repo.bundle2caps)
+ capsblob = bundle2.encodecaps(bundle2.getrepocaps(repo))
caps.add('bundle2=' + urllib.quote(capsblob))
return caps
@@ -726,9 +976,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')
@@ -750,10 +1004,21 @@
part.addparam('namespace', namespace)
keys = repo.listkeys(namespace).items()
part.data = pushkey.encodekeys(keys)
+ _getbundleobsmarkerpart(bundler, repo, source, heads=heads, common=common,
+ bundlecaps=bundlecaps, **kwargs)
_getbundleextrapart(bundler, repo, source, heads=heads, common=common,
bundlecaps=bundlecaps, **kwargs)
return util.chunkbuffer(bundler.getchunks())
+def _getbundleobsmarkerpart(bundler, repo, source, heads=None, common=None,
+ bundlecaps=None, **kwargs):
+ if kwargs.get('obsmarkers', False):
+ if heads is None:
+ heads = repo.heads()
+ subset = [c.node() for c in repo.set('::%ln', heads)]
+ markers = repo.obsstore.relevantmarkers(subset)
+ buildobsmarkerspart(bundler, markers)
+
def _getbundleextrapart(bundler, repo, source, heads=None, common=None,
bundlecaps=None, **kwargs):
"""hook function to let extensions add parts to the requested bundle"""
--- a/mercurial/filemerge.py Wed Sep 03 20:42:51 2014 +0200
+++ b/mercurial/filemerge.py Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/mercurial/help.py Sun Sep 07 11:46:11 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)
@@ -235,11 +236,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
@@ -277,31 +280,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
@@ -367,30 +366,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):
@@ -409,8 +403,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:
@@ -441,8 +435,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:
@@ -453,8 +447,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):
@@ -465,8 +459,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 Wed Sep 03 20:42:51 2014 +0200
+++ b/mercurial/help/config.txt Sun Sep 07 11:46:11 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,57 @@
- :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.merge`` for :hg:`commit --amend` on merges
+- ``changeset.commit.amend.normal`` for :hg:`commit --amend` on other
+- ``changeset.commit.normal.merge`` for :hg:`commit` on merges
+- ``changeset.commit.normal.normal`` for :hg:`commit` on other
+- ``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.merge`` for :hg:`import` on merges
+- ``changeset.import.normal.normal`` for :hg:`import` on other
+- ``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.merge`` for :hg:`rebase` on merges
+- ``changeset.rebase.normal`` for :hg:`rebase` on other
+- ``changeset.shelve.shelve`` for :hg:`shelve`
+- ``changeset.tag.add`` for :hg:`tag` without ``--remove``
+- ``changeset.tag.remove`` for :hg:`tag --remove`
+- ``changeset.transplant.merge`` for :hg:`transplant` on merges
+- ``changeset.transplant.normal`` for :hg:`transplant` on other
+
+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.
+
+At the external editor invocation for committing, corresponding
+dot-separated list of names without ``changeset.`` prefix
+(e.g. ``commit.normal.normal``) is in ``HGEDITFORM`` environment variable.
+
+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 +964,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/hg.py Wed Sep 03 20:42:51 2014 +0200
+++ b/mercurial/hg.py Sun Sep 07 11:46:11 2014 -0500
@@ -11,7 +11,7 @@
from node import hex, nullid
import localrepo, bundlerepo, unionrepo, httppeer, sshpeer, statichttprepo
import bookmarks, lock, util, extensions, error, node, scmutil, phases, url
-import cmdutil, discovery
+import cmdutil, discovery, repoview
import merge as mergemod
import verify as verifymod
import errno, os, shutil
@@ -366,13 +366,20 @@
# Recomputing branch cache might be slow on big repos,
# so just copy it
+ def copybranchcache(fname):
+ srcbranchcache = srcrepo.join('cache/%s' % fname)
+ dstbranchcache = os.path.join(dstcachedir, fname)
+ if os.path.exists(srcbranchcache):
+ if not os.path.exists(dstcachedir):
+ os.mkdir(dstcachedir)
+ util.copyfile(srcbranchcache, dstbranchcache)
+
dstcachedir = os.path.join(destpath, 'cache')
- srcbranchcache = srcrepo.sjoin('cache/branch2')
- dstbranchcache = os.path.join(dstcachedir, 'branch2')
- if os.path.exists(srcbranchcache):
- if not os.path.exists(dstcachedir):
- os.mkdir(dstcachedir)
- util.copyfile(srcbranchcache, dstbranchcache)
+ # In local clones we're copying all nodes, not just served
+ # ones. Therefore copy all branchcaches over.
+ copybranchcache('branch2')
+ for cachename in repoview.filtertable:
+ copybranchcache('branch2-%s' % cachename)
# we need to re-init the repo after manually copying the data
# into it
--- a/mercurial/hgweb/hgweb_mod.py Wed Sep 03 20:42:51 2014 +0200
+++ b/mercurial/hgweb/hgweb_mod.py Sun Sep 07 11:46:11 2014 -0500
@@ -110,7 +110,7 @@
# compare changelog size in addition to mtime to catch
# rollbacks made less than a second ago
if st.st_mtime != self.mtime or st.st_size != self.size:
- r = hg.repository(self.repo.baseui, self.repo.root)
+ r = hg.repository(self.repo.baseui, self.repo.url())
self.repo = self._getview(r)
self.maxchanges = int(self.config("web", "maxchanges", 10))
self.stripecount = int(self.config("web", "stripes", 1))
@@ -392,5 +392,5 @@
}
def check_perm(self, req, op):
- for hook in permhooks:
- hook(self, req, op)
+ for permhook in permhooks:
+ permhook(self, req, op)
--- a/mercurial/hgweb/webcommands.py Wed Sep 03 20:42:51 2014 +0200
+++ b/mercurial/hgweb/webcommands.py Sun Sep 07 11:46:11 2014 -0500
@@ -1069,7 +1069,7 @@
topicname = req.form.get('node', [None])[0]
if not topicname:
def topics(**map):
- for entries, summary, _ in helpmod.helptable:
+ for entries, summary, _doc in helpmod.helptable:
yield {'topic': entries[0], 'summary': summary}
early, other = [], []
--- a/mercurial/i18n.py Wed Sep 03 20:42:51 2014 +0200
+++ b/mercurial/i18n.py Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/mercurial/localrepo.py Sun Sep 07 11:46:11 2014 -0500
@@ -180,10 +180,6 @@
requirements = ['revlogv1']
filtername = None
- bundle2caps = {'HG2X': (),
- 'b2x:listkeys': (),
- 'b2x:pushkey': ()}
-
# a list of (ui, featureset) functions.
# only functions defined in module of enabled extensions are invoked
featuresetupfuncs = set()
@@ -309,7 +305,7 @@
# required by the tests (or some brave tester)
if self.ui.configbool('experimental', 'bundle2-exp', False):
caps = set(caps)
- capsblob = bundle2.encodecaps(self.bundle2caps)
+ capsblob = bundle2.encodecaps(bundle2.getrepocaps(self))
caps.add('bundle2-exp=' + urllib.quote(capsblob))
return caps
@@ -674,8 +670,7 @@
if not self._tagscache.tagslist:
l = []
for t, n in self.tags().iteritems():
- r = self.changelog.rev(n)
- l.append((r, t, n))
+ l.append((self.changelog.rev(n), t, n))
self._tagscache.tagslist = [(t, n) for r, t, n in sorted(l)]
return self._tagscache.tagslist
@@ -744,11 +739,11 @@
# if publishing we can't copy if there is filtered content
return not self.filtered('visible').changelog.filteredrevs
- def join(self, f):
- return os.path.join(self.path, f)
+ def join(self, f, *insidef):
+ return os.path.join(self.path, f, *insidef)
- def wjoin(self, f):
- return os.path.join(self.root, f)
+ def wjoin(self, f, *insidef):
+ return os.path.join(self.root, f, *insidef)
def file(self, f):
if f[0] == '/':
@@ -1087,8 +1082,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
@@ -1395,9 +1388,12 @@
self.ui.note(f + "\n")
try:
fctx = ctx[f]
- new[f] = self._filecommit(fctx, m1, m2, linkrev, trp,
- changed)
- m1.set(f, fctx.flags())
+ if fctx is None:
+ removed.append(f)
+ else:
+ new[f] = self._filecommit(fctx, m1, m2, linkrev,
+ trp, changed)
+ m1.set(f, fctx.flags())
except OSError, inst:
self.ui.warn(_("trouble committing %s!\n") % f)
raise
@@ -1405,9 +1401,7 @@
errcode = getattr(inst, 'errno', errno.ENOENT)
if error or errcode and errcode != errno.ENOENT:
self.ui.warn(_("trouble committing %s!\n") % f)
- raise
- else:
- removed.append(f)
+ raise
# update manifest
m1.update(new)
@@ -1440,7 +1434,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/merge.py Wed Sep 03 20:42:51 2014 +0200
+++ b/mercurial/merge.py Sun Sep 07 11:46:11 2014 -0500
@@ -10,7 +10,7 @@
from node import nullid, nullrev, hex, bin
from i18n import _
from mercurial import obsolete
-import error, util, filemerge, copies, subrepo, worker, dicthelpers
+import error as errormod, util, filemerge, copies, subrepo, worker, dicthelpers
import errno, os, shutil
_pack = struct.pack
@@ -1011,7 +1011,7 @@
# but currently we are only checking the branch tips.
try:
node = repo.branchtip(wc.branch())
- except error.RepoLookupError:
+ except errormod.RepoLookupError:
if wc.branch() == "default": # no default branch!
node = repo.lookup("tip") # update to tip
else:
--- a/mercurial/obsolete.py Wed Sep 03 20:42:51 2014 +0200
+++ b/mercurial/obsolete.py Sun Sep 07 11:46:11 2014 -0500
@@ -99,11 +99,11 @@
_enabled = False
# data used for parsing and writing
-_fmversion = 0
-_fmfixed = '>BIB20s'
-_fmnode = '20s'
-_fmfsize = struct.calcsize(_fmfixed)
-_fnodesize = struct.calcsize(_fmnode)
+_fm0version = 0
+_fm0fixed = '>BIB20s'
+_fm0node = '20s'
+_fm0fsize = struct.calcsize(_fm0fixed)
+_fm0fnodesize = struct.calcsize(_fm0node)
### obsolescence marker flag
@@ -142,23 +142,34 @@
off = 0
diskversion = _unpack('>B', data[off:off + 1])[0]
off += 1
- if diskversion != _fmversion:
+ if diskversion not in formats:
raise util.Abort(_('parsing obsolete marker: unknown version %r')
% diskversion)
+ return diskversion, formats[diskversion][0](data, off)
+def encodemarkers(markers, addheader=False, version=_fm0version):
+ # Kept separate from flushmarkers(), it will be reused for
+ # markers exchange.
+ encodeone = formats[version][1]
+ if addheader:
+ yield _pack('>B', _fm0version)
+ for marker in markers:
+ yield encodeone(marker)
+
+def _fm0readmarkers(data, off=0):
# Loop on markers
l = len(data)
- while off + _fmfsize <= l:
+ while off + _fm0fsize <= l:
# read fixed part
- cur = data[off:off + _fmfsize]
- off += _fmfsize
- nbsuc, mdsize, flags, pre = _unpack(_fmfixed, cur)
+ cur = data[off:off + _fm0fsize]
+ off += _fm0fsize
+ nbsuc, mdsize, flags, pre = _unpack(_fm0fixed, cur)
# read replacement
sucs = ()
if nbsuc:
- s = (_fnodesize * nbsuc)
+ s = (_fm0fnodesize * nbsuc)
cur = data[off:off + s]
- sucs = _unpack(_fmnode * nbsuc, cur)
+ sucs = _unpack(_fm0node * nbsuc, cur)
off += s
# read metadata
# (metadata will be decoded on demand)
@@ -168,7 +179,55 @@
'short, %d bytes expected, got %d')
% (mdsize, len(metadata)))
off += mdsize
- yield (pre, sucs, flags, metadata)
+ meta = decodemeta(metadata)
+ try:
+ when, offset = decodemeta(metadata).pop('date', '0 0').split(' ')
+ date = float(when), int(offset)
+ except ValueError:
+ date = (0., 0)
+ parents = None
+ if 'p2' in meta:
+ parents = (meta.pop('p1', None), meta.pop('p2', None))
+ elif 'p1' in meta:
+ parents = (meta.pop('p1', None),)
+ elif 'p0' in meta:
+ parents = ()
+ if parents is not None:
+ try:
+ parents = tuple(node.bin(p) for p in parents)
+ # if parent content is not a nodeid, drop the data
+ for p in parents:
+ if len(p) != 20:
+ parents = None
+ break
+ except TypeError:
+ # if content cannot be translated to nodeid drop the data.
+ parents = None
+
+ metadata = encodemeta(meta)
+
+ yield (pre, sucs, flags, metadata, date, parents)
+
+def _fm0encodeonemarker(marker):
+ pre, sucs, flags, metadata, date, parents = marker
+ metadata = decodemeta(metadata)
+ metadata['date'] = '%d %i' % date
+ if parents is not None:
+ if not parents:
+ # mark that we explicitly recorded no parents
+ metadata['p0'] = ''
+ for i, p in enumerate(parents):
+ metadata['p%i' % (i + 1)] = node.hex(p)
+ metadata = encodemeta(metadata)
+ nbsuc = len(sucs)
+ format = _fm0fixed + (_fm0node * nbsuc)
+ data = [nbsuc, len(metadata), flags, pre]
+ data.extend(sucs)
+ return _pack(format, *data) + metadata
+
+# mapping to read/write various marker formats
+# <version> -> (decoder, encoder)
+formats = {0: (_fm0readmarkers, _fm0encodeonemarker)}
def encodemeta(meta):
"""Return encoded metadata string to string mapping.
@@ -215,6 +274,10 @@
"""List of successor changesets node identifiers"""
return self._data[1]
+ def parentnodes(self):
+ """Parents of the precursors (None if not recorded)"""
+ return self._data[5]
+
def metadata(self):
"""Decoded metadata dictionary"""
if self._decodedmeta is None:
@@ -223,8 +286,11 @@
def date(self):
"""Creation date as (unixtime, offset)"""
- parts = self.metadata()['date'].split(' ')
- return (float(parts[0]), int(parts[1]))
+ return self._data[4]
+
+ def flags(self):
+ """The flags field of the marker"""
+ return self._data[2]
class obsstore(object):
"""Store obsolete markers
@@ -232,19 +298,31 @@
Markers can be accessed with two mappings:
- precursors[x] -> set(markers on precursors edges of x)
- successors[x] -> set(markers on successors edges of x)
+ - children[x] -> set(markers on precursors edges of children(x)
"""
+ fields = ('prec', 'succs', 'flag', 'meta', 'date', 'parents')
+ # prec: nodeid, precursor changesets
+ # succs: tuple of nodeid, successor changesets (0-N length)
+ # flag: integer, flag field carrying modifier for the markers (see doc)
+ # meta: binary blob, encoded metadata dictionary
+ # date: (float, int) tuple, date of marker creation
+ # parents: (tuple of nodeid) or None, parents of precursors
+ # None is used when no data has been recorded
+
def __init__(self, sopener):
# caches for various obsolescence related cache
self.caches = {}
self._all = []
- # new markers to serialize
self.precursors = {}
self.successors = {}
+ self.children = {}
self.sopener = sopener
data = sopener.tryread('obsstore')
+ self._version = _fm0version
if data:
- self._load(_readmarkers(data))
+ self._version, markers = _readmarkers(data)
+ self._load(markers)
def __iter__(self):
return iter(self._all)
@@ -255,7 +333,8 @@
def __nonzero__(self):
return bool(self._all)
- def create(self, transaction, prec, succs=(), flag=0, metadata=None):
+ def create(self, transaction, prec, succs=(), flag=0, parents=None,
+ date=None, metadata=None):
"""obsolete: add a new obsolete marker
* ensuring it is hashable
@@ -270,8 +349,12 @@
"""
if metadata is None:
metadata = {}
- if 'date' not in metadata:
- metadata['date'] = "%d %d" % util.makedate()
+ if date is None:
+ if 'date' in metadata:
+ # as a courtesy for out-of-tree extensions
+ date = util.parsedate(metadata.pop('date'))
+ else:
+ date = util.makedate()
if len(prec) != 20:
raise ValueError(prec)
for succ in succs:
@@ -279,7 +362,8 @@
raise ValueError(succ)
if prec in succs:
raise ValueError(_('in-marker cycle with %s') % node.hex(prec))
- marker = (str(prec), tuple(succs), int(flag), encodemeta(metadata))
+ marker = (str(prec), tuple(succs), int(flag), encodemeta(metadata),
+ date, parents)
return bool(self.add(transaction, [marker]))
def add(self, transaction, markers):
@@ -307,7 +391,7 @@
offset = f.tell()
transaction.add('obsstore', offset)
# offset == 0: new file - add the version header
- for bytes in _encodemarkers(new, offset == 0):
+ for bytes in encodemarkers(new, offset == 0, self._version):
f.write(bytes)
finally:
# XXX: f.close() == filecache invalidation == obsstore rebuilt.
@@ -316,11 +400,17 @@
self._load(new)
# new marker *may* have changed several set. invalidate the cache.
self.caches.clear()
+ # records the number of new markers for the transaction hooks
+ previous = int(transaction.hookargs.get('new_obsmarkers', '0'))
+ transaction.hookargs['new_obsmarkers'] = str(previous + len(new))
return len(new)
def mergemarkers(self, transaction, data):
- markers = _readmarkers(data)
- self.add(transaction, markers)
+ """merge a binary stream of markers inside the obsstore
+
+ Returns the number of new markers added."""
+ version, markers = _readmarkers(data)
+ return self.add(transaction, markers)
def _load(self, markers):
for mark in markers:
@@ -329,26 +419,53 @@
self.successors.setdefault(pre, set()).add(mark)
for suc in sucs:
self.precursors.setdefault(suc, set()).add(mark)
+ parents = mark[5]
+ if parents is not None:
+ for p in parents:
+ self.children.setdefault(p, set()).add(mark)
if node.nullid in self.precursors:
raise util.Abort(_('bad obsolescence marker detected: '
'invalid successors nullid'))
+ def relevantmarkers(self, nodes):
+ """return a set of all obsolescence markers relevant to a set of nodes.
-def _encodemarkers(markers, addheader=False):
- # Kept separate from flushmarkers(), it will be reused for
- # markers exchange.
- if addheader:
- yield _pack('>B', _fmversion)
- for marker in markers:
- yield _encodeonemarker(marker)
+ "relevant" to a set of nodes mean:
+
+ - marker that use this changeset as successor
+ - prune marker of direct children on this changeset
+ - recursive application of the two rules on precursors of these markers
+
+ It is a set so you cannot rely on order."""
+ pendingnodes = set(nodes)
+ seenmarkers = set()
+ seennodes = set(pendingnodes)
+ precursorsmarkers = self.precursors
+ children = self.children
+ while pendingnodes:
+ direct = set()
+ for current in pendingnodes:
+ direct.update(precursorsmarkers.get(current, ()))
+ pruned = [m for m in children.get(current, ()) if not m[1]]
+ direct.update(pruned)
+ direct -= seenmarkers
+ pendingnodes = set([m[0] for m in direct])
+ seenmarkers |= direct
+ pendingnodes -= seennodes
+ seennodes |= pendingnodes
+ return seenmarkers
-def _encodeonemarker(marker):
- pre, sucs, flags, metadata = marker
- nbsuc = len(sucs)
- format = _fmfixed + (_fmnode * nbsuc)
- data = [nbsuc, len(metadata), flags, pre]
- data.extend(sucs)
- return _pack(format, *data) + metadata
+def commonversion(versions):
+ """Return the newest version listed in both versions and our local formats.
+
+ Returns None if no common version exists.
+ """
+ versions.sort(reverse=True)
+ # search for highest version known on both side
+ for v in versions:
+ if v in formats:
+ return v
+ return None
# arbitrary picked to fit into 8K limit from HTTP server
# you have to take in account:
@@ -365,7 +482,7 @@
parts = []
currentlen = _maxpayload * 2 # ensure we create a new part
for marker in markers:
- nextdata = _encodeonemarker(marker)
+ nextdata = _fm0encodeonemarker(marker)
if (len(nextdata) + currentlen > _maxpayload):
currentpart = []
currentlen = 0
@@ -373,7 +490,7 @@
currentpart.append(nextdata)
currentlen += len(nextdata)
for idx, part in enumerate(reversed(parts)):
- data = ''.join([_pack('>B', _fmversion)] + part)
+ data = ''.join([_pack('>B', _fm0version)] + part)
keys['dump%i' % idx] = base85.b85encode(data)
return keys
@@ -404,11 +521,25 @@
finally:
lock.release()
-def allmarkers(repo):
- """all obsolete markers known in a repository"""
- for markerdata in repo.obsstore:
+def getmarkers(repo, nodes=None):
+ """returns markers known in a repository
+
+ If <nodes> is specified, only markers "relevant" to those nodes are are
+ returned"""
+ if nodes is None:
+ rawmarkers = repo.obsstore
+ else:
+ rawmarkers = repo.obsstore.relevantmarkers(nodes)
+
+ for markerdata in rawmarkers:
yield marker(repo, markerdata)
+def relevantmarkers(repo, node):
+ """all obsolete markers relevant to some revision"""
+ for markerdata in repo.obsstore.relevantmarkers(node):
+ yield marker(repo, markerdata)
+
+
def precursormarkers(ctx):
"""obsolete marker marking this changeset as a successors"""
for data in ctx._repo.obsstore.precursors.get(ctx.node(), ()):
@@ -750,8 +881,8 @@
obs = set()
getrev = repo.changelog.nodemap.get
getphase = repo._phasecache.phase
- for node in repo.obsstore.successors:
- rev = getrev(node)
+ for n in repo.obsstore.successors:
+ rev = getrev(n)
if rev is not None and getphase(repo, rev):
obs.add(rev)
return obs
@@ -825,7 +956,7 @@
return divergent
-def createmarkers(repo, relations, flag=0, metadata=None):
+def createmarkers(repo, relations, flag=0, date=None, metadata=None):
"""Add obsolete markers between changesets in a repo
<relations> must be an iterable of (<old>, (<new>, ...)[,{metadata}])
@@ -844,8 +975,6 @@
# prepare metadata
if metadata is None:
metadata = {}
- if 'date' not in metadata:
- metadata['date'] = '%i %i' % util.makedate()
if 'user' not in metadata:
metadata['user'] = repo.ui.username()
tr = repo.transaction('add-obsolescence-marker')
@@ -862,9 +991,13 @@
% prec)
nprec = prec.node()
nsucs = tuple(s.node() for s in sucs)
+ npare = None
+ if not nsucs:
+ npare = tuple(p.node() for p in prec.parents())
if nprec in nsucs:
raise util.Abort("changeset %s cannot obsolete itself" % prec)
- repo.obsstore.create(tr, nprec, nsucs, flag, localmetadata)
+ repo.obsstore.create(tr, nprec, nsucs, flag, parents=npare,
+ date=date, metadata=localmetadata)
repo.filteredrevcache.clear()
tr.close()
finally:
--- a/mercurial/patch.py Wed Sep 03 20:42:51 2014 +0200
+++ b/mercurial/patch.py Sun Sep 07 11:46:11 2014 -0500
@@ -382,7 +382,7 @@
def getfile(self, fname):
"""Return target file data and flags as a (data, (islink,
- isexec)) tuple.
+ isexec)) tuple. Data is None if file is missing/deleted.
"""
raise NotImplementedError
@@ -426,7 +426,12 @@
except OSError, e:
if e.errno != errno.ENOENT:
raise
- return (self.opener.read(fname), (False, isexec))
+ try:
+ return (self.opener.read(fname), (False, isexec))
+ except IOError, e:
+ if e.errno != errno.ENOENT:
+ raise
+ return None, None
def setfile(self, fname, data, mode, copysource):
islink, isexec = mode
@@ -528,7 +533,7 @@
if fname in self.data:
return self.data[fname]
if not self.opener or fname not in self.files:
- raise IOError
+ return None, None, None
fn, mode, copied = self.files[fname]
return self.opener.read(fn), mode, copied
@@ -554,7 +559,7 @@
try:
fctx = self.ctx[fname]
except error.LookupError:
- raise IOError
+ return None, None
flags = fctx.flags()
return fctx.data(), ('l' in flags, 'x' in flags)
@@ -597,13 +602,12 @@
self.copysource = gp.oldpath
self.create = gp.op in ('ADD', 'COPY', 'RENAME')
self.remove = gp.op == 'DELETE'
- try:
- if self.copysource is None:
- data, mode = backend.getfile(self.fname)
- self.exists = True
- else:
- data, mode = store.getfile(self.copysource)[:2]
- self.exists = backend.exists(self.fname)
+ if self.copysource is None:
+ data, mode = backend.getfile(self.fname)
+ else:
+ data, mode = store.getfile(self.copysource)[:2]
+ if data is not None:
+ self.exists = self.copysource is None or backend.exists(self.fname)
self.missing = False
if data:
self.lines = mdiff.splitnewlines(data)
@@ -622,7 +626,7 @@
l = l[:-2] + '\n'
nlines.append(l)
self.lines = nlines
- except IOError:
+ else:
if self.create:
self.missing = False
if self.mode is None:
@@ -1380,6 +1384,8 @@
data, mode = None, None
if gp.op in ('RENAME', 'COPY'):
data, mode = store.getfile(gp.oldpath)[:2]
+ # FIXME: failing getfile has never been handled here
+ assert data is not None
if gp.mode:
mode = gp.mode
if gp.op == 'ADD':
@@ -1404,15 +1410,13 @@
elif state == 'git':
for gp in values:
path = pstrip(gp.oldpath)
- try:
- data, mode = backend.getfile(path)
- except IOError, e:
- if e.errno != errno.ENOENT:
- raise
+ data, mode = backend.getfile(path)
+ if data is None:
# The error ignored here will trigger a getfile()
# error in a place more appropriate for error
# handling, and will not interrupt the patching
# process.
+ pass
else:
store.setfile(path, data, mode)
else:
--- a/mercurial/phases.py Wed Sep 03 20:42:51 2014 +0200
+++ b/mercurial/phases.py Sun Sep 07 11:46:11 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/posix.py Wed Sep 03 20:42:51 2014 +0200
+++ b/mercurial/posix.py Sun Sep 07 11:46:11 2014 -0500
@@ -8,6 +8,7 @@
from i18n import _
import encoding
import os, sys, errno, stat, getpass, pwd, grp, socket, tempfile, unicodedata
+import fcntl
posixfile = open
normpath = os.path.normpath
@@ -432,7 +433,7 @@
def termwidth():
try:
- import termios, array, fcntl
+ import termios, array
for dev in (sys.stderr, sys.stdout, sys.stdin):
try:
try:
@@ -567,3 +568,27 @@
def statisexec(st):
'''check whether a stat result is an executable file'''
return st and (st.st_mode & 0100 != 0)
+
+def readpipe(pipe):
+ """Read all available data from a pipe."""
+ # We can't fstat() a pipe because Linux will always report 0.
+ # So, we set the pipe to non-blocking mode and read everything
+ # that's available.
+ flags = fcntl.fcntl(pipe, fcntl.F_GETFL)
+ flags |= os.O_NONBLOCK
+ oldflags = fcntl.fcntl(pipe, fcntl.F_SETFL, flags)
+
+ try:
+ chunks = []
+ while True:
+ try:
+ s = pipe.read()
+ if not s:
+ break
+ chunks.append(s)
+ except IOError:
+ break
+
+ return ''.join(chunks)
+ finally:
+ fcntl.fcntl(pipe, fcntl.F_SETFL, oldflags)
--- a/mercurial/repair.py Wed Sep 03 20:42:51 2014 +0200
+++ b/mercurial/repair.py Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/mercurial/repoview.py Sun Sep 07 11:46:11 2014 -0500
@@ -7,11 +7,13 @@
# GNU General Public License version 2 or any later version.
import copy
+import error
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 +21,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 +36,124 @@
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 = util.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:
+ 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/revlog.py Wed Sep 03 20:42:51 2014 +0200
+++ b/mercurial/revlog.py Sun Sep 07 11:46:11 2014 -0500
@@ -306,6 +306,8 @@
def rev(self, node):
try:
return self._nodecache[node]
+ except TypeError:
+ raise
except RevlogError:
# parsers.c radix tree lookup failed
raise LookupError(node, self.indexfile, _('no node'))
--- a/mercurial/simplemerge.py Wed Sep 03 20:42:51 2014 +0200
+++ b/mercurial/simplemerge.py Sun Sep 07 11:46:11 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/sshpeer.py Wed Sep 03 20:42:51 2014 +0200
+++ b/mercurial/sshpeer.py Sun Sep 07 11:46:11 2014 -0500
@@ -103,13 +103,8 @@
return self._caps
def readerr(self):
- while True:
- size = util.fstat(self.pipee).st_size
- if size == 0:
- break
- s = self.pipee.read(size)
- if not s:
- break
+ s = util.readpipe(self.pipee)
+ if s:
for l in s.splitlines():
self.ui.status(_("remote: "), l, '\n')
--- a/mercurial/tagmerge.py Wed Sep 03 20:42:51 2014 +0200
+++ b/mercurial/tagmerge.py Sun Sep 07 11:46:11 2014 -0500
@@ -71,7 +71,7 @@
# - put blocks whose nodes come all from p2 first
# - write the tag blocks in the sorted order
-import tags
+import tags as tagsmod
import util
from node import nullid, hex
from i18n import _
@@ -85,8 +85,8 @@
with each tag. Rhis is done because only the line numbers of the first
parent are useful for merging
'''
- filetags = tags._readtaghist(ui, repo, lines, fn=fn, recode=None,
- calcnodelines=True)[1]
+ filetags = tagsmod._readtaghist(ui, repo, lines, fn=fn, recode=None,
+ calcnodelines=True)[1]
for tagname, taginfo in filetags.items():
if not keeplinenums:
for el in taginfo:
--- a/mercurial/templater.py Wed Sep 03 20:42:51 2014 +0200
+++ b/mercurial/templater.py Sun Sep 07 11:46:11 2014 -0500
@@ -8,6 +8,7 @@
from i18n import _
import sys, os, re
import util, config, templatefilters, templatekw, parser, error
+import revset as revsetmod
import types
import minirst
@@ -370,16 +371,20 @@
ctx = mapping['ctx']
repo = ctx._repo
+ def query(expr):
+ m = revsetmod.match(repo.ui, expr)
+ return m(repo, revsetmod.spanset(repo))
+
if len(args) > 1:
formatargs = list([a[0](context, mapping, a[1]) for a in args[1:]])
- revs = repo.revs(raw, *formatargs)
+ revs = query(revsetmod.formatspec(raw, *formatargs))
revs = list([str(r) for r in revs])
else:
revsetcache = mapping['cache'].setdefault("revsetcache", {})
if raw in revsetcache:
revs = revsetcache[raw]
else:
- revs = repo.revs(raw)
+ revs = query(raw)
revs = list([str(r) for r in revs])
revsetcache[raw] = revs
--- a/mercurial/transaction.py Wed Sep 03 20:42:51 2014 +0200
+++ b/mercurial/transaction.py Sun Sep 07 11:46:11 2014 -0500
@@ -24,7 +24,7 @@
return _active
def _playback(journal, report, opener, entries, backupentries, unlink=True):
- for f, o, ignore in entries:
+ for f, o, _ignore in entries:
if o or not unlink:
try:
fp = opener(f, 'a')
@@ -41,7 +41,7 @@
raise
backupfiles = []
- for f, b, ignore in backupentries:
+ for f, b, _ignore in backupentries:
filepath = opener.join(f)
backuppath = opener.join(b)
try:
@@ -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()
@@ -112,10 +115,10 @@
offsets = []
backups = []
- for f, o, _ in q[0]:
+ for f, o, _data in q[0]:
offsets.append((f, o))
- for f, b, _ in q[1]:
+ for f, b, _data in q[1]:
backups.append((f, b))
d = ''.join(['%s\0%d\n' % (f, o) for f, o in offsets])
@@ -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()
@@ -228,7 +265,7 @@
self.opener.unlink(self.journal)
if self.opener.isfile(self.backupjournal):
self.opener.unlink(self.backupjournal)
- for f, b, _ in self.backupentries:
+ for _f, b, _ignore in self.backupentries:
self.opener.unlink(b)
self.backupentries = []
self.journal = None
--- a/mercurial/ui.py Wed Sep 03 20:42:51 2014 +0200
+++ b/mercurial/ui.py Sun Sep 07 11:46:11 2014 -0500
@@ -626,6 +626,8 @@
oldout = sys.stdout
sys.stdin = self.fin
sys.stdout = self.fout
+ # prompt ' ' must exist; otherwise readline may delete entire line
+ # - http://bugs.python.org/issue12833
line = raw_input(' ')
sys.stdin = oldin
sys.stdout = oldout
@@ -728,7 +730,7 @@
if self.debugflag:
opts['label'] = opts.get('label', '') + ' ui.debug'
self.write(*msg, **opts)
- def edit(self, text, user, extra={}):
+ def edit(self, text, user, extra={}, editform=None):
(fd, name) = tempfile.mkstemp(prefix="hg-editor-", suffix=".txt",
text=True)
try:
@@ -743,6 +745,8 @@
if label in extra:
environ.update({'HGREVISION': extra[label]})
break
+ if editform:
+ environ.update({'HGEDITFORM': editform})
editor = self.geteditor()
--- a/mercurial/util.py Wed Sep 03 20:42:51 2014 +0200
+++ b/mercurial/util.py Sun Sep 07 11:46:11 2014 -0500
@@ -53,6 +53,7 @@
popen = platform.popen
posixfile = platform.posixfile
quotecommand = platform.quotecommand
+readpipe = platform.readpipe
rename = platform.rename
samedevice = platform.samedevice
samefile = platform.samefile
--- a/mercurial/windows.py Wed Sep 03 20:42:51 2014 +0200
+++ b/mercurial/windows.py Sun Sep 07 11:46:11 2014 -0500
@@ -336,3 +336,18 @@
def statisexec(st):
'''check whether a stat result is an executable file'''
return False
+
+def readpipe(pipe):
+ """Read all available data from a pipe."""
+ chunks = []
+ while True:
+ size = os.fstat(pipe.fileno()).st_size
+ if not size:
+ break
+
+ s = pipe.read(size)
+ if not s:
+ break
+ chunks.append(s)
+
+ return ''.join(chunks)
--- a/mercurial/wireproto.py Wed Sep 03 20:42:51 2014 +0200
+++ b/mercurial/wireproto.py Sun Sep 07 11:46:11 2014 -0500
@@ -202,8 +202,10 @@
# :plain: string with no transformation needed.
gboptsmap = {'heads': 'nodes',
'common': 'nodes',
+ 'obsmarkers': 'boolean',
'bundlecaps': 'csv',
- 'listkeys': 'csv'}
+ 'listkeys': 'csv',
+ 'cg': 'boolean'}
# client side
@@ -248,7 +250,7 @@
yield {'nodes': encodelist(nodes)}, f
d = f.value
try:
- yield [bool(int(f)) for f in d]
+ yield [bool(int(b)) for b in d]
except ValueError:
self._abort(error.ResponseError(_("unexpected response:"), d))
@@ -349,6 +351,8 @@
value = encodelist(value)
elif keytype == 'csv':
value = ','.join(value)
+ elif keytype == 'boolean':
+ value = '%i' % bool(value)
elif keytype != 'plain':
raise KeyError('unknown getbundle option type %s'
% keytype)
@@ -606,7 +610,7 @@
else:
caps.append('streamreqs=%s' % ','.join(requiredformats))
if repo.ui.configbool('experimental', 'bundle2-exp', False):
- capsblob = bundle2.encodecaps(repo.bundle2caps)
+ capsblob = bundle2.encodecaps(bundle2.getrepocaps(repo))
caps.append('bundle2-exp=' + urllib.quote(capsblob))
caps.append('unbundle=%s' % ','.join(changegroupmod.bundlepriority))
caps.append('httpheader=1024')
@@ -652,6 +656,8 @@
opts[k] = decodelist(v)
elif keytype == 'csv':
opts[k] = set(v.split(','))
+ elif keytype == 'boolean':
+ opts[k] = bool(v)
elif keytype != 'plain':
raise KeyError('unknown getbundle option type %s'
% keytype)
--- a/mercurial/worker.py Wed Sep 03 20:42:51 2014 +0200
+++ b/mercurial/worker.py Sun Sep 07 11:46:11 2014 -0500
@@ -105,7 +105,7 @@
if err.errno != errno.ESRCH:
raise
def waitforworkers():
- for _ in pids:
+ for _pid in pids:
st = _exitstatus(os.wait()[1])
if st and not problem[0]:
problem[0] = st
--- a/setup.py Wed Sep 03 20:42:51 2014 +0200
+++ b/setup.py Sun Sep 07 11:46:11 2014 -0500
@@ -33,12 +33,14 @@
except ImportError:
try:
import sha
+ sha.sha # silence unused import warning
except ImportError:
raise SystemExit(
"Couldn't import standard hashlib (incomplete Python install).")
try:
import zlib
+ zlib.compressobj # silence unused import warning
except ImportError:
raise SystemExit(
"Couldn't import standard zlib (incomplete Python install).")
@@ -56,6 +58,7 @@
else:
try:
import bz2
+ bz2.BZ2Compressor # silence unused import warning
except ImportError:
raise SystemExit(
"Couldn't import standard bz2 (incomplete Python install).")
@@ -129,6 +132,7 @@
# py2exe needs to be installed to work
try:
import py2exe
+ py2exe.Distribution # silence unused import warning
py2exeloaded = True
# import py2exe's patched Distribution class
from distutils.core import Distribution
@@ -579,7 +583,7 @@
cmdclass=cmdclass,
distclass=hgdist,
options={'py2exe': {'packages': ['hgext', 'email']},
- 'bdist_mpkg': {'zipdist': True,
+ 'bdist_mpkg': {'zipdist': False,
'license': 'COPYING',
'readme': 'contrib/macosx/Readme.html',
'welcome': 'contrib/macosx/Welcome.html',
--- a/tests/hghave.py Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/hghave.py Sun Sep 07 11:46:11 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,22 +144,28 @@
finally:
os.remove(path)
+@check("lsprof", "python lsprof module")
def has_lsprof():
try:
import _lsprof
+ _lsprof.Profiler # silence unused import warning
return True
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
+ publish_cmdline # silence unused import
return True
except ImportError:
return False
@@ -146,16 +176,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 +200,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 +217,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 +233,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,51 +258,64 @@
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
+ pygments.highlight # silence unused import warning
return True
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
+ ssl.wrap_socket # silence unused import warning
import OpenSSL
OpenSSL.SSL.Context
return True
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 +324,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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/run-tests.py Sun Sep 07 11:46:11 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:
@@ -522,7 +546,7 @@
missing, failed = TTest.parsehghaveoutput(out)
if not missing:
- missing = ['irrelevant']
+ missing = ['skipped']
if failed:
self.fail('hg have failed checking for %s' % failed[-1])
@@ -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:
@@ -1152,17 +1201,18 @@
self.stream.write(line)
self.stream.flush()
- # handle interactive prompt without releasing iolock
- if self._options.interactive:
- self.stream.write('Accept this change? [n] ')
- answer = sys.stdin.readline().strip()
- if answer.lower() in ('y', 'yes'):
- if test.name.endswith('.t'):
- rename(test.errpath, test.path)
- else:
- rename(test.errpath, '%s.out' % test.path)
- accepted = True
-
+ # handle interactive prompt without releasing iolock
+ if self._options.interactive:
+ self.stream.write('Accept this change? [n] ')
+ answer = sys.stdin.readline().strip()
+ if answer.lower() in ('y', 'yes'):
+ if test.name.endswith('.t'):
+ rename(test.errpath, test.path)
+ 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-acl.t Sun Sep 07 11:46:11 2014 -0500
@@ -82,6 +82,9 @@
query 1; heads
searching for changes
all remote heads known locally
+ listing keys for "phases"
+ checking for updated bookmarks
+ listing keys for "bookmarks"
listing keys for "bookmarks"
3 changesets found
list of changesets:
@@ -119,8 +122,6 @@
updating the branch cache
listing keys for "phases"
try to push obsolete markers to remote
- checking for updated bookmarks
- listing keys for "bookmarks"
repository tip rolled back to revision 0 (undo push)
0:6675d58eff77
@@ -140,6 +141,9 @@
query 1; heads
searching for changes
all remote heads known locally
+ listing keys for "phases"
+ checking for updated bookmarks
+ listing keys for "bookmarks"
invalid branchheads cache (served): tip differs
listing keys for "bookmarks"
3 changesets found
@@ -180,8 +184,6 @@
updating the branch cache
listing keys for "phases"
try to push obsolete markers to remote
- checking for updated bookmarks
- listing keys for "bookmarks"
repository tip rolled back to revision 0 (undo push)
0:6675d58eff77
@@ -202,6 +204,9 @@
query 1; heads
searching for changes
all remote heads known locally
+ listing keys for "phases"
+ checking for updated bookmarks
+ listing keys for "bookmarks"
invalid branchheads cache (served): tip differs
listing keys for "bookmarks"
3 changesets found
@@ -252,8 +257,6 @@
updating the branch cache
listing keys for "phases"
try to push obsolete markers to remote
- checking for updated bookmarks
- listing keys for "bookmarks"
repository tip rolled back to revision 0 (undo push)
0:6675d58eff77
@@ -274,6 +277,9 @@
query 1; heads
searching for changes
all remote heads known locally
+ listing keys for "phases"
+ checking for updated bookmarks
+ listing keys for "bookmarks"
invalid branchheads cache (served): tip differs
listing keys for "bookmarks"
3 changesets found
@@ -341,6 +347,9 @@
query 1; heads
searching for changes
all remote heads known locally
+ listing keys for "phases"
+ checking for updated bookmarks
+ listing keys for "bookmarks"
invalid branchheads cache (served): tip differs
listing keys for "bookmarks"
3 changesets found
@@ -413,6 +422,9 @@
query 1; heads
searching for changes
all remote heads known locally
+ listing keys for "phases"
+ checking for updated bookmarks
+ listing keys for "bookmarks"
invalid branchheads cache (served): tip differs
listing keys for "bookmarks"
3 changesets found
@@ -482,6 +494,9 @@
query 1; heads
searching for changes
all remote heads known locally
+ listing keys for "phases"
+ checking for updated bookmarks
+ listing keys for "bookmarks"
invalid branchheads cache (served): tip differs
listing keys for "bookmarks"
3 changesets found
@@ -556,6 +571,9 @@
query 1; heads
searching for changes
all remote heads known locally
+ listing keys for "phases"
+ checking for updated bookmarks
+ listing keys for "bookmarks"
invalid branchheads cache (served): tip differs
listing keys for "bookmarks"
3 changesets found
@@ -627,6 +645,9 @@
query 1; heads
searching for changes
all remote heads known locally
+ listing keys for "phases"
+ checking for updated bookmarks
+ listing keys for "bookmarks"
invalid branchheads cache (served): tip differs
listing keys for "bookmarks"
3 changesets found
@@ -700,6 +721,9 @@
query 1; heads
searching for changes
all remote heads known locally
+ listing keys for "phases"
+ checking for updated bookmarks
+ listing keys for "bookmarks"
invalid branchheads cache (served): tip differs
listing keys for "bookmarks"
3 changesets found
@@ -750,8 +774,6 @@
updating the branch cache
listing keys for "phases"
try to push obsolete markers to remote
- checking for updated bookmarks
- listing keys for "bookmarks"
repository tip rolled back to revision 0 (undo push)
0:6675d58eff77
@@ -779,6 +801,9 @@
query 1; heads
searching for changes
all remote heads known locally
+ listing keys for "phases"
+ checking for updated bookmarks
+ listing keys for "bookmarks"
invalid branchheads cache (served): tip differs
listing keys for "bookmarks"
3 changesets found
@@ -859,6 +884,9 @@
query 1; heads
searching for changes
all remote heads known locally
+ listing keys for "phases"
+ checking for updated bookmarks
+ listing keys for "bookmarks"
invalid branchheads cache (served): tip differs
listing keys for "bookmarks"
3 changesets found
@@ -896,10 +924,10 @@
added 3 changesets with 3 changes to 3 files
calling hook pretxnchangegroup.acl: hgext.acl.hook
acl: checking access for user "barney"
- error: pretxnchangegroup.acl hook raised an exception: [Errno *] *: '../acl.config' (glob)
+ error: pretxnchangegroup.acl hook raised an exception: [Errno 2] No such file or directory: '../acl.config'
transaction abort!
rollback completed
- abort: *: ../acl.config (glob)
+ abort: No such file or directory: ../acl.config
no rollback information available
0:6675d58eff77
@@ -934,6 +962,9 @@
query 1; heads
searching for changes
all remote heads known locally
+ listing keys for "phases"
+ checking for updated bookmarks
+ listing keys for "bookmarks"
invalid branchheads cache (served): tip differs
listing keys for "bookmarks"
3 changesets found
@@ -1020,6 +1051,9 @@
query 1; heads
searching for changes
all remote heads known locally
+ listing keys for "phases"
+ checking for updated bookmarks
+ listing keys for "bookmarks"
invalid branchheads cache (served): tip differs
listing keys for "bookmarks"
3 changesets found
@@ -1070,8 +1104,6 @@
updating the branch cache
listing keys for "phases"
try to push obsolete markers to remote
- checking for updated bookmarks
- listing keys for "bookmarks"
repository tip rolled back to revision 0 (undo push)
0:6675d58eff77
@@ -1100,6 +1132,9 @@
query 1; heads
searching for changes
all remote heads known locally
+ listing keys for "phases"
+ checking for updated bookmarks
+ listing keys for "bookmarks"
invalid branchheads cache (served): tip differs
listing keys for "bookmarks"
3 changesets found
@@ -1150,8 +1185,6 @@
updating the branch cache
listing keys for "phases"
try to push obsolete markers to remote
- checking for updated bookmarks
- listing keys for "bookmarks"
repository tip rolled back to revision 0 (undo push)
0:6675d58eff77
@@ -1176,6 +1209,9 @@
query 1; heads
searching for changes
all remote heads known locally
+ listing keys for "phases"
+ checking for updated bookmarks
+ listing keys for "bookmarks"
invalid branchheads cache (served): tip differs
listing keys for "bookmarks"
3 changesets found
@@ -1252,6 +1288,9 @@
query 1; heads
searching for changes
all remote heads known locally
+ listing keys for "phases"
+ checking for updated bookmarks
+ listing keys for "bookmarks"
invalid branchheads cache (served): tip differs
listing keys for "bookmarks"
3 changesets found
@@ -1303,8 +1342,6 @@
updating the branch cache
listing keys for "phases"
try to push obsolete markers to remote
- checking for updated bookmarks
- listing keys for "bookmarks"
repository tip rolled back to revision 0 (undo push)
0:6675d58eff77
@@ -1329,6 +1366,9 @@
query 1; heads
searching for changes
all remote heads known locally
+ listing keys for "phases"
+ checking for updated bookmarks
+ listing keys for "bookmarks"
invalid branchheads cache (served): tip differs
listing keys for "bookmarks"
3 changesets found
@@ -1444,6 +1484,9 @@
query 1; heads
searching for changes
all remote heads known locally
+ listing keys for "phases"
+ checking for updated bookmarks
+ listing keys for "bookmarks"
listing keys for "bookmarks"
4 changesets found
list of changesets:
@@ -1504,8 +1547,6 @@
updating the branch cache
listing keys for "phases"
try to push obsolete markers to remote
- checking for updated bookmarks
- listing keys for "bookmarks"
repository tip rolled back to revision 2 (undo push)
2:fb35475503ef
@@ -1527,6 +1568,9 @@
query 1; heads
searching for changes
all remote heads known locally
+ listing keys for "phases"
+ checking for updated bookmarks
+ listing keys for "bookmarks"
listing keys for "bookmarks"
4 changesets found
list of changesets:
@@ -1606,6 +1650,9 @@
query 1; heads
searching for changes
all remote heads known locally
+ listing keys for "phases"
+ checking for updated bookmarks
+ listing keys for "bookmarks"
listing keys for "bookmarks"
4 changesets found
list of changesets:
@@ -1681,6 +1728,9 @@
query 1; heads
searching for changes
all remote heads known locally
+ listing keys for "phases"
+ checking for updated bookmarks
+ listing keys for "bookmarks"
listing keys for "bookmarks"
4 changesets found
list of changesets:
@@ -1750,6 +1800,9 @@
query 1; heads
searching for changes
all remote heads known locally
+ listing keys for "phases"
+ checking for updated bookmarks
+ listing keys for "bookmarks"
listing keys for "bookmarks"
4 changesets found
list of changesets:
@@ -1810,8 +1863,6 @@
updating the branch cache
listing keys for "phases"
try to push obsolete markers to remote
- checking for updated bookmarks
- listing keys for "bookmarks"
repository tip rolled back to revision 2 (undo push)
2:fb35475503ef
@@ -1838,6 +1889,9 @@
query 1; heads
searching for changes
all remote heads known locally
+ listing keys for "phases"
+ checking for updated bookmarks
+ listing keys for "bookmarks"
listing keys for "bookmarks"
4 changesets found
list of changesets:
@@ -1898,8 +1952,6 @@
updating the branch cache
listing keys for "phases"
try to push obsolete markers to remote
- checking for updated bookmarks
- listing keys for "bookmarks"
repository tip rolled back to revision 2 (undo push)
2:fb35475503ef
@@ -1925,6 +1977,9 @@
query 1; heads
searching for changes
all remote heads known locally
+ listing keys for "phases"
+ checking for updated bookmarks
+ listing keys for "bookmarks"
listing keys for "bookmarks"
4 changesets found
list of changesets:
@@ -1999,6 +2054,9 @@
query 1; heads
searching for changes
all remote heads known locally
+ listing keys for "phases"
+ checking for updated bookmarks
+ listing keys for "bookmarks"
listing keys for "bookmarks"
4 changesets found
list of changesets:
@@ -2059,8 +2117,6 @@
updating the branch cache
listing keys for "phases"
try to push obsolete markers to remote
- checking for updated bookmarks
- listing keys for "bookmarks"
repository tip rolled back to revision 2 (undo push)
2:fb35475503ef
@@ -2080,6 +2136,9 @@
query 1; heads
searching for changes
all remote heads known locally
+ listing keys for "phases"
+ checking for updated bookmarks
+ listing keys for "bookmarks"
listing keys for "bookmarks"
4 changesets found
list of changesets:
--- a/tests/test-alias.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-alias.t Sun Sep 07 11:46:11 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-ancestor.py Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-ancestor.py Sun Sep 07 11:46:11 2014 -0500
@@ -91,6 +91,10 @@
s = genlazyancestors([11, 13])
printlazyancestors(s, [11, 13, 7, 9, 8, 3, 6, 4, 1, -1, 0])
+ # Standard with ancestry in the initial set (1 is ancestor of 3)
+ s = genlazyancestors([1, 3])
+ printlazyancestors(s, [1, -1, 0])
+
# Including revs
s = genlazyancestors([11, 13], inclusive=True)
printlazyancestors(s, [11, 13, 7, 9, 8, 3, 6, 4, 1, -1, 0])
--- a/tests/test-ancestor.py.out Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-ancestor.py.out Sun Sep 07 11:46:11 2014 -0500
@@ -38,6 +38,8 @@
[]
% lazy ancestor set for [11, 13], stoprev = 0, inclusive = False
[7, 8, 3, 4, 1, 0]
+% lazy ancestor set for [1, 3], stoprev = 0, inclusive = False
+[1, 0]
% lazy ancestor set for [11, 13], stoprev = 0, inclusive = True
[11, 13, 7, 8, 3, 4, 1, 0]
% lazy ancestor set for [11, 13], stoprev = 6, inclusive = False
--- a/tests/test-archive-symlinks.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-archive-symlinks.t Sun Sep 07 11:46:11 2014 -0500
@@ -1,4 +1,4 @@
- $ "$TESTDIR/hghave" symlink || exit 80
+#require symlink
$ origdir=`pwd`
--- a/tests/test-archive.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-archive.t Sun Sep 07 11:46:11 2014 -0500
@@ -1,4 +1,4 @@
- $ "$TESTDIR/hghave" serve || exit 80
+#require serve
$ hg init test
$ cd test
--- a/tests/test-bad-pull.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-bad-pull.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-bookmarks-pushpull.t Sun Sep 07 11:46:11 2014 -0500
@@ -1,4 +1,4 @@
- $ "$TESTDIR/hghave" serve || exit 80
+#require serve
$ cat << EOF >> $HGRCPATH
> [ui]
--- a/tests/test-bundle.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-bundle.t Sun Sep 07 11:46:11 2014 -0500
@@ -422,7 +422,7 @@
$ rm -r full-clone
When cloning from a non-copiable repository into '', do not
-recurse infinitely (issue 2528)
+recurse infinitely (issue2528)
$ hg clone full.hg ''
abort: empty destination path is not valid
--- a/tests/test-bundle2.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-bundle2.t Sun Sep 07 11:46:11 2014 -0500
@@ -1,3 +1,7 @@
+
+ $ getmainid() {
+ > hg -R main log --template '{node}\n' --rev "$1"
+ > }
Create an extension to test bundle2 API
@@ -16,6 +20,9 @@
> from mercurial import discovery
> from mercurial import changegroup
> from mercurial import error
+ > from mercurial import obsolete
+ >
+ > obsolete._enabled = True
>
> try:
> import msvcrt
@@ -191,7 +198,7 @@
> bundle2-exp=True
> [ui]
> ssh=python "$TESTDIR/dummyssh"
- > logtemplate={rev}:{node|short} {phase} {author} {desc|firstline}
+ > logtemplate={rev}:{node|short} {phase} {author} {bookmarks} {desc|firstline}
> [web]
> push_ssl = false
> allow_push = *
@@ -668,23 +675,23 @@
(run 'hg heads' to see heads, 'hg merge' to merge)
$ hg log -G
- o 8:02de42196ebe draft Nicolas Dumazet <nicdumz.commits@gmail.com> H
+ o 8:02de42196ebe draft Nicolas Dumazet <nicdumz.commits@gmail.com> H
|
- | o 7:eea13746799a draft Nicolas Dumazet <nicdumz.commits@gmail.com> G
+ | o 7:eea13746799a draft Nicolas Dumazet <nicdumz.commits@gmail.com> G
|/|
- o | 6:24b6387c8c8c draft Nicolas Dumazet <nicdumz.commits@gmail.com> F
+ o | 6:24b6387c8c8c draft Nicolas Dumazet <nicdumz.commits@gmail.com> F
| |
- | o 5:9520eea781bc draft Nicolas Dumazet <nicdumz.commits@gmail.com> E
+ | o 5:9520eea781bc draft Nicolas Dumazet <nicdumz.commits@gmail.com> E
|/
- | o 4:32af7686d403 draft Nicolas Dumazet <nicdumz.commits@gmail.com> D
+ | o 4:32af7686d403 draft Nicolas Dumazet <nicdumz.commits@gmail.com> D
| |
- | o 3:5fddd98957c8 draft Nicolas Dumazet <nicdumz.commits@gmail.com> C
+ | o 3:5fddd98957c8 draft Nicolas Dumazet <nicdumz.commits@gmail.com> C
| |
- | o 2:42ccdea3bb16 draft Nicolas Dumazet <nicdumz.commits@gmail.com> B
+ | o 2:42ccdea3bb16 draft Nicolas Dumazet <nicdumz.commits@gmail.com> B
|/
- o 1:cd010b8cd998 draft Nicolas Dumazet <nicdumz.commits@gmail.com> A
+ o 1:cd010b8cd998 draft Nicolas Dumazet <nicdumz.commits@gmail.com> A
- @ 0:3903775176ed draft test a
+ @ 0:3903775176ed draft test a
$ hg bundle2 --debug --rev '8+7+5+4' ../rev.hg2
@@ -758,26 +765,34 @@
added 0 changesets with 0 changes to 3 files
\x00\x00\x00\x00\x00\x00 (no-eol) (esc)
+ $ cd ..
+
Real world exchange
=====================
+Add more obsolescence information
+
+ $ hg -R main debugobsolete -d '0 0' 1111111111111111111111111111111111111111 `getmainid 9520eea781bc`
+ $ hg -R main debugobsolete -d '0 0' 2222222222222222222222222222222222222222 `getmainid 24b6387c8c8c`
clone --pull
- $ cd ..
$ hg -R main phase --public cd010b8cd998
$ hg clone main other --pull --rev 9520eea781bc
adding changesets
adding manifests
adding file changes
added 2 changesets with 2 changes to 2 files
+ 1 new obsolescence markers
updating to branch default
2 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ hg -R other log -G
- @ 1:9520eea781bc draft Nicolas Dumazet <nicdumz.commits@gmail.com> E
+ @ 1:9520eea781bc draft Nicolas Dumazet <nicdumz.commits@gmail.com> E
|
- o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> A
+ o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> A
+ $ hg -R other debugobsolete
+ 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
pull
@@ -789,14 +804,18 @@
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files (+1 heads)
+ 1 new obsolescence markers
(run 'hg heads' to see heads, 'hg merge' to merge)
$ hg -R other log -G
- o 2:24b6387c8c8c draft Nicolas Dumazet <nicdumz.commits@gmail.com> F
+ o 2:24b6387c8c8c draft Nicolas Dumazet <nicdumz.commits@gmail.com> F
|
- | @ 1:9520eea781bc draft Nicolas Dumazet <nicdumz.commits@gmail.com> E
+ | @ 1:9520eea781bc draft Nicolas Dumazet <nicdumz.commits@gmail.com> E
|/
- o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> A
+ o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> A
+ $ hg -R other debugobsolete
+ 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+ 2222222222222222222222222222222222222222 24b6387c8c8cae37178880f3fa95ded3cb1cf785 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
pull empty (with phase movement)
@@ -805,95 +824,155 @@
pulling from $TESTTMP/main (glob)
no changes found
$ hg -R other log -G
- o 2:24b6387c8c8c public Nicolas Dumazet <nicdumz.commits@gmail.com> F
+ o 2:24b6387c8c8c public Nicolas Dumazet <nicdumz.commits@gmail.com> F
|
- | @ 1:9520eea781bc draft Nicolas Dumazet <nicdumz.commits@gmail.com> E
+ | @ 1:9520eea781bc draft Nicolas Dumazet <nicdumz.commits@gmail.com> E
|/
- o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> A
+ o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> A
+ $ hg -R other debugobsolete
+ 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+ 2222222222222222222222222222222222222222 24b6387c8c8cae37178880f3fa95ded3cb1cf785 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+
pull empty
$ hg -R other pull -r 24b6387c8c8c
pulling from $TESTTMP/main (glob)
no changes found
$ hg -R other log -G
- o 2:24b6387c8c8c public Nicolas Dumazet <nicdumz.commits@gmail.com> F
+ o 2:24b6387c8c8c public Nicolas Dumazet <nicdumz.commits@gmail.com> F
|
- | @ 1:9520eea781bc draft Nicolas Dumazet <nicdumz.commits@gmail.com> E
+ | @ 1:9520eea781bc draft Nicolas Dumazet <nicdumz.commits@gmail.com> E
|/
- o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> A
+ o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> A
+ $ hg -R other debugobsolete
+ 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+ 2222222222222222222222222222222222222222 24b6387c8c8cae37178880f3fa95ded3cb1cf785 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+
+add extra data to test their exchange during push
+
+ $ hg -R main bookmark --rev eea13746799a book_eea1
+ $ hg -R main debugobsolete -d '0 0' 3333333333333333333333333333333333333333 `getmainid eea13746799a`
+ $ hg -R main bookmark --rev 02de42196ebe book_02de
+ $ hg -R main debugobsolete -d '0 0' 4444444444444444444444444444444444444444 `getmainid 02de42196ebe`
+ $ hg -R main bookmark --rev 42ccdea3bb16 book_42cc
+ $ hg -R main debugobsolete -d '0 0' 5555555555555555555555555555555555555555 `getmainid 42ccdea3bb16`
+ $ hg -R main bookmark --rev 5fddd98957c8 book_5fdd
+ $ hg -R main debugobsolete -d '0 0' 6666666666666666666666666666666666666666 `getmainid 5fddd98957c8`
+ $ hg -R main bookmark --rev 32af7686d403 book_32af
+ $ hg -R main debugobsolete -d '0 0' 7777777777777777777777777777777777777777 `getmainid 32af7686d403`
+
+ $ hg -R other bookmark --rev cd010b8cd998 book_eea1
+ $ hg -R other bookmark --rev cd010b8cd998 book_02de
+ $ hg -R other bookmark --rev cd010b8cd998 book_42cc
+ $ hg -R other bookmark --rev cd010b8cd998 book_5fdd
+ $ hg -R other bookmark --rev cd010b8cd998 book_32af
+
+ $ hg -R main phase --public eea13746799a
push
-
- $ hg -R main phase --public eea13746799a
- $ hg -R main push other --rev eea13746799a
+ $ hg -R main push other --rev eea13746799a --bookmark book_eea1
pushing to other
searching for changes
remote: adding changesets
remote: adding manifests
remote: adding file changes
remote: added 1 changesets with 0 changes to 0 files (-1 heads)
+ remote: 1 new obsolescence markers
+ updating bookmark book_eea1
+ exporting bookmark book_eea1
$ hg -R other log -G
- o 3:eea13746799a public Nicolas Dumazet <nicdumz.commits@gmail.com> G
+ o 3:eea13746799a public Nicolas Dumazet <nicdumz.commits@gmail.com> book_eea1 G
|\
- | o 2:24b6387c8c8c public Nicolas Dumazet <nicdumz.commits@gmail.com> F
+ | o 2:24b6387c8c8c public Nicolas Dumazet <nicdumz.commits@gmail.com> F
| |
- @ | 1:9520eea781bc public Nicolas Dumazet <nicdumz.commits@gmail.com> E
+ @ | 1:9520eea781bc public Nicolas Dumazet <nicdumz.commits@gmail.com> E
|/
- o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> A
+ o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> book_02de book_32af book_42cc book_5fdd A
+ $ hg -R other debugobsolete
+ 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+ 2222222222222222222222222222222222222222 24b6387c8c8cae37178880f3fa95ded3cb1cf785 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+ 3333333333333333333333333333333333333333 eea13746799a9e0bfd88f29d3c2e9dc9389f524f 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
pull over ssh
- $ hg -R other pull ssh://user@dummy/main -r 02de42196ebe --traceback
+ $ hg -R other pull ssh://user@dummy/main -r 02de42196ebe --bookmark book_02de
pulling from ssh://user@dummy/main
searching for changes
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files (+1 heads)
+ 1 new obsolescence markers
+ updating bookmark book_02de
(run 'hg heads' to see heads, 'hg merge' to merge)
+ importing bookmark book_02de
+ $ hg -R other debugobsolete
+ 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+ 2222222222222222222222222222222222222222 24b6387c8c8cae37178880f3fa95ded3cb1cf785 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+ 3333333333333333333333333333333333333333 eea13746799a9e0bfd88f29d3c2e9dc9389f524f 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+ 4444444444444444444444444444444444444444 02de42196ebee42ef284b6780a87cdc96e8eaab6 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
pull over http
$ hg -R main serve -p $HGPORT -d --pid-file=main.pid -E main-error.log
$ cat main.pid >> $DAEMON_PIDS
- $ hg -R other pull http://localhost:$HGPORT/ -r 42ccdea3bb16
+ $ hg -R other pull http://localhost:$HGPORT/ -r 42ccdea3bb16 --bookmark book_42cc
pulling from http://localhost:$HGPORT/
searching for changes
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files (+1 heads)
+ 1 new obsolescence markers
+ updating bookmark book_42cc
(run 'hg heads .' to see heads, 'hg merge' to merge)
+ importing bookmark book_42cc
$ cat main-error.log
+ $ hg -R other debugobsolete
+ 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+ 2222222222222222222222222222222222222222 24b6387c8c8cae37178880f3fa95ded3cb1cf785 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+ 3333333333333333333333333333333333333333 eea13746799a9e0bfd88f29d3c2e9dc9389f524f 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+ 4444444444444444444444444444444444444444 02de42196ebee42ef284b6780a87cdc96e8eaab6 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+ 5555555555555555555555555555555555555555 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
push over ssh
- $ hg -R main push ssh://user@dummy/other -r 5fddd98957c8
+ $ hg -R main push ssh://user@dummy/other -r 5fddd98957c8 --bookmark book_5fdd
pushing to ssh://user@dummy/other
searching for changes
remote: adding changesets
remote: adding manifests
remote: adding file changes
remote: added 1 changesets with 1 changes to 1 files
+ remote: 1 new obsolescence markers
+ updating bookmark book_5fdd
+ exporting bookmark book_5fdd
$ hg -R other log -G
- o 6:5fddd98957c8 draft Nicolas Dumazet <nicdumz.commits@gmail.com> C
+ o 6:5fddd98957c8 draft Nicolas Dumazet <nicdumz.commits@gmail.com> book_5fdd C
|
- o 5:42ccdea3bb16 draft Nicolas Dumazet <nicdumz.commits@gmail.com> B
+ o 5:42ccdea3bb16 draft Nicolas Dumazet <nicdumz.commits@gmail.com> book_42cc B
|
- | o 4:02de42196ebe draft Nicolas Dumazet <nicdumz.commits@gmail.com> H
+ | o 4:02de42196ebe draft Nicolas Dumazet <nicdumz.commits@gmail.com> book_02de H
| |
- | | o 3:eea13746799a public Nicolas Dumazet <nicdumz.commits@gmail.com> G
+ | | o 3:eea13746799a public Nicolas Dumazet <nicdumz.commits@gmail.com> book_eea1 G
| |/|
- | o | 2:24b6387c8c8c public Nicolas Dumazet <nicdumz.commits@gmail.com> F
+ | o | 2:24b6387c8c8c public Nicolas Dumazet <nicdumz.commits@gmail.com> F
|/ /
- | @ 1:9520eea781bc public Nicolas Dumazet <nicdumz.commits@gmail.com> E
+ | @ 1:9520eea781bc public Nicolas Dumazet <nicdumz.commits@gmail.com> E
|/
- o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> A
+ o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> book_32af A
+ $ hg -R other debugobsolete
+ 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+ 2222222222222222222222222222222222222222 24b6387c8c8cae37178880f3fa95ded3cb1cf785 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+ 3333333333333333333333333333333333333333 eea13746799a9e0bfd88f29d3c2e9dc9389f524f 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+ 4444444444444444444444444444444444444444 02de42196ebee42ef284b6780a87cdc96e8eaab6 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+ 5555555555555555555555555555555555555555 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+ 6666666666666666666666666666666666666666 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
push over http
@@ -901,34 +980,45 @@
$ cat other.pid >> $DAEMON_PIDS
$ hg -R main phase --public 32af7686d403
- $ hg -R main push http://localhost:$HGPORT2/ -r 32af7686d403
+ $ hg -R main push http://localhost:$HGPORT2/ -r 32af7686d403 --bookmark book_32af
pushing to http://localhost:$HGPORT2/
searching for changes
remote: adding changesets
remote: adding manifests
remote: adding file changes
remote: added 1 changesets with 1 changes to 1 files
+ remote: 1 new obsolescence markers
+ updating bookmark book_32af
+ exporting bookmark book_32af
$ cat other-error.log
Check final content.
$ hg -R other log -G
- o 7:32af7686d403 public Nicolas Dumazet <nicdumz.commits@gmail.com> D
+ o 7:32af7686d403 public Nicolas Dumazet <nicdumz.commits@gmail.com> book_32af D
|
- o 6:5fddd98957c8 public Nicolas Dumazet <nicdumz.commits@gmail.com> C
+ o 6:5fddd98957c8 public Nicolas Dumazet <nicdumz.commits@gmail.com> book_5fdd C
|
- o 5:42ccdea3bb16 public Nicolas Dumazet <nicdumz.commits@gmail.com> B
+ o 5:42ccdea3bb16 public Nicolas Dumazet <nicdumz.commits@gmail.com> book_42cc B
|
- | o 4:02de42196ebe draft Nicolas Dumazet <nicdumz.commits@gmail.com> H
+ | o 4:02de42196ebe draft Nicolas Dumazet <nicdumz.commits@gmail.com> book_02de H
| |
- | | o 3:eea13746799a public Nicolas Dumazet <nicdumz.commits@gmail.com> G
+ | | o 3:eea13746799a public Nicolas Dumazet <nicdumz.commits@gmail.com> book_eea1 G
| |/|
- | o | 2:24b6387c8c8c public Nicolas Dumazet <nicdumz.commits@gmail.com> F
+ | o | 2:24b6387c8c8c public Nicolas Dumazet <nicdumz.commits@gmail.com> F
|/ /
- | @ 1:9520eea781bc public Nicolas Dumazet <nicdumz.commits@gmail.com> E
+ | @ 1:9520eea781bc public Nicolas Dumazet <nicdumz.commits@gmail.com> E
|/
- o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> A
+ o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> A
+ $ hg -R other debugobsolete
+ 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+ 2222222222222222222222222222222222222222 24b6387c8c8cae37178880f3fa95ded3cb1cf785 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+ 3333333333333333333333333333333333333333 eea13746799a9e0bfd88f29d3c2e9dc9389f524f 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+ 4444444444444444444444444444444444444444 02de42196ebee42ef284b6780a87cdc96e8eaab6 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+ 5555555555555555555555555555555555555555 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+ 6666666666666666666666666666666666666666 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+ 7777777777777777777777777777777777777777 32af7686d403cf45b5d95f2d70cebea587ac806a 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
Error Handling
==============
@@ -964,7 +1054,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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-casecollision-merge.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-casecollision.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-casefolding.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-changelog-exec.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-check-code-hg.t Sun Sep 07 11:46:11 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 Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-check-pyflakes.t Sun Sep 07 11:46:11 2014 -0500
@@ -1,4 +1,4 @@
-#if test-repo pyflakes
+#require test-repo pyflakes
$ cd "`dirname "$TESTDIR"`"
@@ -7,16 +7,6 @@
$ hg locate 'set:**.py or grep("^!#.*python")' 2>/dev/null \
> | xargs pyflakes 2>/dev/null | "$TESTDIR/filterpyflakes.py"
- contrib/win32/hgwebdir_wsgi.py:*: 'win32traceutil' imported but unused (glob)
- setup.py:*: 'sha' imported but unused (glob)
- setup.py:*: 'zlib' imported but unused (glob)
- setup.py:*: 'bz2' imported but unused (glob)
- setup.py:*: 'py2exe' imported but unused (glob)
- tests/hghave.py:*: '_lsprof' imported but unused (glob)
- tests/hghave.py:*: 'publish_cmdline' imported but unused (glob)
- tests/hghave.py:*: 'pygments' imported but unused (glob)
- tests/hghave.py:*: 'ssl' imported but unused (glob)
- 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-clone-cgi.t Sun Sep 07 11:46:11 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-clone.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-clone.t Sun Sep 07 11:46:11 2014 -0500
@@ -25,12 +25,25 @@
.hg/store/data/b.d
.hg/store/data/b.i
+Trigger branchcache creation:
+
+ $ hg branches
+ default 10:a7949464abda
+ $ ls .hg/cache
+ branch2-served
+
Default operation:
$ hg clone . ../b
updating to branch default
2 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ cd ../b
+
+Ensure branchcache got copied over:
+
+ $ ls .hg/cache
+ branch2-served
+
$ cat a
a
$ hg verify
@@ -58,6 +71,12 @@
listing keys for "bookmarks"
#endif
$ cd ../c
+
+Ensure branchcache got copied over:
+
+ $ ls .hg/cache
+ branch2-served
+
$ cat a 2>/dev/null || echo "a not present"
a not present
$ hg verify
--- a/tests/test-command-template.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-command-template.t Sun Sep 07 11:46:11 2014 -0500
@@ -1834,6 +1834,15 @@
1 Parents: 0
0 Parents:
+ $ cat >> .hg/hgrc <<EOF
+ > [revsetalias]
+ > myparents(\$1) = parents(\$1)
+ > EOF
+ $ hg log --template '{rev} Parents: {revset("myparents(%s)", rev)}\n'
+ 2 Parents: 1
+ 1 Parents: 0
+ 0 Parents:
+
$ hg log --template 'Rev: {rev}\n{revset("::%s", rev) % "Ancestor: {revision}\n"}\n'
Rev: 2
Ancestor: 0
--- a/tests/test-commandserver.py.out Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-commandserver.py.out Sun Sep 07 11:46:11 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-amend.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-commit-amend.t Sun Sep 07 11:46:11 2014 -0500
@@ -145,7 +145,12 @@
Test -u/-d:
- $ hg ci --amend -u foo -d '1 0'
+ $ cat > .hg/checkeditform.sh <<EOF
+ > env | grep HGEDITFORM
+ > true
+ > EOF
+ $ HGEDITOR="sh .hg/checkeditform.sh" hg ci --amend -u foo -d '1 0'
+ HGEDITFORM=commit.amend.normal
saved backup bundle to $TESTTMP/.hg/strip-backup/1cd866679df8-amend-backup.hg (glob)
$ echo a >> a
$ hg ci --amend -u foo -d '1 0'
@@ -619,7 +624,8 @@
zz renamed from z:69a1b67522704ec122181c0890bd16e9d3e7516a
$ hg debugrename cc
cc not renamed
- $ hg ci --amend -m 'merge bar (amend message)'
+ $ HGEDITOR="sh .hg/checkeditform.sh" hg ci --amend -m 'merge bar (amend message)' --edit
+ HGEDITFORM=commit.amend.merge
$ hg log --config diff.git=1 -pr .
changeset: 24:832b50f2c271
tag: tip
--- a/tests/test-commit.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-commit.t Sun Sep 07 11:46:11 2014 -0500
@@ -4,7 +4,12 @@
$ cd test
$ echo foo > foo
$ hg add foo
- $ HGEDITOR=true hg commit -m ""
+ $ cat > $TESTTMP/checkeditform.sh <<EOF
+ > env | grep HGEDITFORM
+ > true
+ > EOF
+ $ HGEDITOR="sh $TESTTMP/checkeditform.sh" hg commit -m ""
+ HGEDITFORM=commit.normal.normal
abort: empty commit message
[255]
$ hg commit -d '0 0' -m commit-1
@@ -277,7 +282,8 @@
should succeed
- $ hg ci -mmerge
+ $ HGEDITOR="sh $TESTTMP/checkeditform.sh" hg ci -mmerge --edit
+ HGEDITFORM=commit.normal.merge
$ cd ..
@@ -359,6 +365,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 +393,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 +401,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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-completion.t Sun Sep 07 11:46:11 2014 -0500
@@ -244,7 +244,7 @@
debuginstall:
debugknown:
debuglabelcomplete:
- debugobsolete: flags, date, user
+ debugobsolete: flags, record-parents, rev, date, user
debugpathcomplete: full, normal, added, removed
debugpushkey:
debugpvec:
@@ -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-config.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-config.t Sun Sep 07 11:46:11 2014 -0500
@@ -1,6 +1,47 @@
hide outer repo
$ hg init
+Invalid syntax: no value
+
+ $ cat > .hg/hgrc << EOF
+ > novaluekey
+ > EOF
+ $ hg showconfig
+ hg: parse error at $TESTTMP/.hg/hgrc:1: novaluekey
+ [255]
+
+Invalid syntax: no key
+
+ $ cat > .hg/hgrc << EOF
+ > =nokeyvalue
+ > EOF
+ $ hg showconfig
+ hg: parse error at $TESTTMP/.hg/hgrc:1: =nokeyvalue
+ [255]
+
+Test hint about invalid syntax from leading white space
+
+ $ cat > .hg/hgrc << EOF
+ > key=value
+ > EOF
+ $ hg showconfig
+ hg: parse error at $TESTTMP/.hg/hgrc:1: key=value
+ unexpected leading whitespace
+ [255]
+
+ $ cat > .hg/hgrc << EOF
+ > [section]
+ > key=value
+ > EOF
+ $ hg showconfig
+ hg: parse error at $TESTTMP/.hg/hgrc:1: [section]
+ unexpected leading whitespace
+ [255]
+
+Reset hgrc
+
+ $ echo > .hg/hgrc
+
Test case sensitive configuration
$ echo '[Section]' >> $HGRCPATH
--- a/tests/test-conflict.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-conflict.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-contrib.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-convert-baz.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-convert-bzr-114.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-convert-cvs-branch.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-convert-cvs-detectmerge.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-convert-cvs-synthetic.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-convert-cvs.t Sun Sep 07 11:46:11 2014 -0500
@@ -1,5 +1,5 @@
+#require cvs
- $ "$TESTDIR/hghave" cvs || exit 80
$ cvscall()
> {
> cvs -f "$@"
--- a/tests/test-convert-cvsnt-mergepoints.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-convert-cvsnt-mergepoints.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-convert-darcs.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-convert-git.t Sun Sep 07 11:46:11 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
@@ -33,8 +33,7 @@
$ git add a d
$ commit -a -m t1
-Remove the directory, then try to replace it with a file
-(issue 754)
+Remove the directory, then try to replace it with a file (issue754)
$ git rm -f d/b
rm 'd/b'
@@ -206,7 +205,7 @@
9277c9cc8dd4576fc01a17939b4351e5ada93466 644 foo
88dfeab657e8cf2cef3dec67b914f49791ae76b1 644 quux
-test binary conversion (issue 1359)
+test binary conversion (issue1359)
$ mkdir git-repo3
$ cd git-repo3
--- a/tests/test-convert-hg-sink.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-convert-hg-sink.t Sun Sep 07 11:46:11 2014 -0500
@@ -537,3 +537,16 @@
|
o 0 0 (a-only f)
+Convert with --full adds and removes files that didn't change
+
+ $ echo f >> 0/f
+ $ hg -R 0 ci -m "f"
+ $ hg convert --filemap filemap-b --full 0 a --config convert.hg.revs=1::
+ scanning source...
+ sorting...
+ converting...
+ 0 f
+ $ hg -R a status --change tip
+ M f
+ A b-only
+ R a-only
--- a/tests/test-convert-hg-svn.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-convert-hg-svn.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-convert-mtn.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-convert-p4-filetypes.t Sun Sep 07 11:46:11 2014 -0500
@@ -1,4 +1,4 @@
- $ "$TESTDIR/hghave" p4 execbit symlink || exit 80
+#require p4 execbit symlink
$ echo "[extensions]" >> $HGRCPATH
$ echo "convert = " >> $HGRCPATH
@@ -8,7 +8,7 @@
$ P4AUDIT=$P4ROOT/audit; export P4AUDIT
$ P4JOURNAL=$P4ROOT/journal; export P4JOURNAL
$ P4LOG=$P4ROOT/log; export P4LOG
- $ P4PORT=localhost:16661; export P4PORT
+ $ P4PORT=localhost:$HGPORT; export P4PORT
$ P4DEBUG=1; export P4DEBUG
$ P4CHARSET=utf8; export P4CHARSET
--- a/tests/test-convert-p4.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-convert-p4.t Sun Sep 07 11:46:11 2014 -0500
@@ -1,4 +1,4 @@
- $ "$TESTDIR/hghave" p4 || exit 80
+#require p4
$ echo "[extensions]" >> $HGRCPATH
$ echo "convert = " >> $HGRCPATH
@@ -8,7 +8,7 @@
$ P4AUDIT=$P4ROOT/audit; export P4AUDIT
$ P4JOURNAL=$P4ROOT/journal; export P4JOURNAL
$ P4LOG=$P4ROOT/log; export P4LOG
- $ P4PORT=localhost:16661; export P4PORT
+ $ P4PORT=localhost:$HGPORT; export P4PORT
$ P4DEBUG=1; export P4DEBUG
start the p4 server
--- a/tests/test-convert-svn-branches.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-convert-svn-branches.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-convert-svn-encoding.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-convert-svn-move.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-convert-svn-sink.t Sun Sep 07 11:46:11 2014 -0500
@@ -1,4 +1,4 @@
- $ "$TESTDIR/hghave" svn13 || exit 80
+#require svn13
$ svnupanddisplay()
> {
@@ -247,6 +247,31 @@
#endif
+Convert with --full adds and removes files that didn't change
+
+ $ touch a/f
+ $ hg -R a ci -Aqmf
+ $ echo "rename c d" > filemap
+ $ hg convert -d svn a --filemap filemap --full
+ assuming destination a-hg
+ initializing svn working copy 'a-hg-wc'
+ scanning source...
+ sorting...
+ converting...
+ 0 f
+ $ svnupanddisplay a-hg-wc 1
+ 9 9 test .
+ 9 9 test d
+ 9 9 test f
+ revision: 9
+ author: test
+ msg: f
+ D /c
+ A /d
+ D /d1
+ A /f
+ D /newlink
+
$ rm -rf a a-hg a-hg-wc
--- a/tests/test-convert-svn-source.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-convert-svn-source.t Sun Sep 07 11:46:11 2014 -0500
@@ -1,5 +1,4 @@
-
- $ "$TESTDIR/hghave" svn svn-bindings || exit 80
+#require svn svn-bindings
$ cat >> $HGRCPATH <<EOF
> [extensions]
@@ -169,6 +168,27 @@
|
o 0 second letter files: letter2.txt
+Convert with --full adds and removes files that didn't change
+
+ $ cd B
+ $ echo >> "letter .txt"
+ $ svn ci -m 'nothing'
+ Sending letter .txt
+ Transmitting file data .
+ Committed revision 9.
+ $ cd ..
+
+ $ echo 'rename letter2.txt letter3.txt' > filemap
+ $ hg convert --filemap filemap --full "$SVNREPOURL/proj%20B/mytrunk" fmap
+ scanning source...
+ sorting...
+ converting...
+ 0 nothing
+ $ hg -R fmap st --change tip
+ A letter .txt
+ A letter3.txt
+ R letter2.txt
+
test invalid splicemap1
$ cat > splicemap <<EOF
--- a/tests/test-convert-svn-startrev.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-convert-svn-startrev.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-convert-svn-tags.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-convert-tagsbranch-topology.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-convert-tla.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-convert.t Sun Sep 07 11:46:11 2014 -0500
@@ -91,6 +91,13 @@
directory if it is converted. To rename from a subdirectory into the root
of the repository, use "." as the path to rename to.
+ "--full" will make sure the converted changesets contain exactly the right
+ files with the right content. It will make a full conversion of all files,
+ not just the ones that have changed. Files that already are correct will
+ not be changed. This can be used to apply filemap changes when converting
+ incrementally. This is currently only supported for Mercurial and
+ Subversion.
+
The splicemap is a file that allows insertion of synthetic history,
letting you specify the parents of a revision. This is useful if you want
to e.g. give a Subversion merge two parents, or graft two disconnected
@@ -265,6 +272,7 @@
-r --rev REV import up to source revision REV
-A --authormap FILE remap usernames using this file
--filemap FILE remap file names using contents of file
+ --full apply filemap changes by converting all files again
--splicemap FILE splice synthesized history into place
--branchmap FILE change branch names while converting
--branchsort try to sort changesets by branches
@@ -272,7 +280,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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-diff-upgrade.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-dispatch.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-encoding-align.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-encoding-textwrap.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-eolfilename.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-execute-bit.t Sun Sep 07 11:46:11 2014 -0500
@@ -1,4 +1,4 @@
- $ "$TESTDIR/hghave" execbit || exit 80
+#require execbit
$ hg init
$ echo a > a
--- a/tests/test-extdiff.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-extdiff.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-extension.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-fetch.t Sun Sep 07 11:46:11 2014 -0500
@@ -1,4 +1,4 @@
- $ "$TESTDIR/hghave" serve || exit 80
+#require serve
$ echo "[extensions]" >> $HGRCPATH
$ echo "fetch=" >> $HGRCPATH
--- a/tests/test-flags.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-flags.t Sun Sep 07 11:46:11 2014 -0500
@@ -1,4 +1,4 @@
- $ "$TESTDIR/hghave" execbit || exit 80
+#require execbit
$ umask 027
--- a/tests/test-gendoc.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-gendoc.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-getbundle.t Sun Sep 07 11:46:11 2014 -0500
@@ -1,4 +1,4 @@
- $ "$TESTDIR/hghave" serve || exit 80
+#require serve
= Test the getbundle() protocol function =
--- a/tests/test-globalopts.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-globalopts.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-glog.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-gpg.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-graft.t Sun Sep 07 11:46:11 2014 -0500
@@ -632,6 +632,52 @@
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
Continue testing same origin policy, using revision numbers from test above
but do some destructive editing of the repo:
--- a/tests/test-hardlinks.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-hardlinks.t Sun Sep 07 11:46:11 2014 -0500
@@ -1,4 +1,4 @@
- $ "$TESTDIR/hghave" hardlink || exit 80
+#require hardlink
$ cat > nlinks.py <<EOF
> import sys
--- a/tests/test-help.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-help.t Sun Sep 07 11:46:11 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-hgrc.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-hgrc.t Sun Sep 07 11:46:11 2014 -0500
@@ -43,6 +43,7 @@
$ echo ' x = y' >> $HGRC
$ hg version
hg: parse error at $TESTTMP/hgrc:2: x = y
+ unexpected leading whitespace
[255]
$ python -c "print '[foo]\nbar = a\n b\n c \n de\n fg \nbaz = bif cb \n'" \
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-hgweb-bundle.t Sun Sep 07 11:46:11 2014 -0500
@@ -0,0 +1,37 @@
+#require serve
+
+ $ hg init server
+ $ cd server
+ $ cat >> .hg/hgrc << EOF
+ > [extensions]
+ > strip=
+ > EOF
+
+ $ echo 1 > foo
+ $ hg commit -A -m 'first'
+ adding foo
+ $ echo 2 > bar
+ $ hg commit -A -m 'second'
+ adding bar
+
+Produce a bundle to use
+
+ $ hg strip -r 1
+ 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+ saved backup bundle to $TESTTMP/server/.hg/strip-backup/ed602e697e0f-backup.hg (glob)
+
+Serve from a bundle file
+
+ $ hg serve -R .hg/strip-backup/ed602e697e0f-backup.hg -d -p $HGPORT --pid-file=hg.pid
+ $ cat hg.pid >> $DAEMON_PIDS
+
+Ensure we're serving from the bundle
+
+ $ ("$TESTDIR/get-with-headers.py" localhost:$HGPORT 'file/tip/?style=raw')
+ 200 Script output follows
+
+
+ -rw-r--r-- 2 bar
+ -rw-r--r-- 2 foo
+
+
--- a/tests/test-hgweb-commands.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-hgweb-commands.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-hgweb-descend-empties.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-hgweb-diffs.t Sun Sep 07 11:46:11 2014 -0500
@@ -1,4 +1,4 @@
- $ "$TESTDIR/hghave" serve || exit 80
+#require serve
setting up repo
--- a/tests/test-hgweb-empty.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-hgweb-empty.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-hgweb-filelog.t Sun Sep 07 11:46:11 2014 -0500
@@ -1,4 +1,4 @@
- $ "$TESTDIR/hghave" serve || exit 80
+#require serve
$ hg init test
$ cd test
--- a/tests/test-hgweb-raw.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-hgweb-raw.t Sun Sep 07 11:46:11 2014 -0500
@@ -1,4 +1,4 @@
- $ "$TESTDIR/hghave" serve || exit 80
+#require serve
Test raw style of hgweb
--- a/tests/test-hgweb-removed.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-hgweb-removed.t Sun Sep 07 11:46:11 2014 -0500
@@ -1,4 +1,4 @@
- $ "$TESTDIR/hghave" serve || exit 80
+#require serve
setting up repo
--- a/tests/test-hgweb.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-hgweb.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-hgwebdir.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-hgwebdirsym.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-highlight.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-histedit-arguments.t Sun Sep 07 11:46:11 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
#
@@ -265,6 +266,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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-histedit-bookmark-motion.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-histedit-commute.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-histedit-fold-non-commute.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-histedit-fold.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-histedit-obsolete.t Sun Sep 07 11:46:11 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
#
@@ -89,11 +90,11 @@
o 0:cb9a9f314b8b a
$ hg debugobsolete
- d2ae7f538514cd87c17547b0de4cea71fe1af9fb 0 {'date': '* *', 'user': 'test'} (glob)
- 177f92b773850b59254aa5e923436f921b55483b b346ab9a313db8537ecf96fca3ca3ca984ef3bd7 0 {'date': '* *', 'user': 'test'} (glob)
- 055a42cdd88768532f9cf79daa407fc8d138de9b 59d9f330561fd6c88b1a6b32f0e45034d88db784 0 {'date': '* *', 'user': 'test'} (glob)
- e860deea161a2f77de56603b340ebbb4536308ae 59d9f330561fd6c88b1a6b32f0e45034d88db784 0 {'date': '* *', 'user': 'test'} (glob)
- 652413bf663ef2a641cab26574e46d5f5a64a55a cacdfd884a9321ec4e1de275ef3949fa953a1f83 0 {'date': '* *', 'user': 'test'} (glob)
+ d2ae7f538514cd87c17547b0de4cea71fe1af9fb 0 {cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b} (*) {'user': 'test'} (glob)
+ 177f92b773850b59254aa5e923436f921b55483b b346ab9a313db8537ecf96fca3ca3ca984ef3bd7 0 (*) {'user': 'test'} (glob)
+ 055a42cdd88768532f9cf79daa407fc8d138de9b 59d9f330561fd6c88b1a6b32f0e45034d88db784 0 (*) {'user': 'test'} (glob)
+ e860deea161a2f77de56603b340ebbb4536308ae 59d9f330561fd6c88b1a6b32f0e45034d88db784 0 (*) {'user': 'test'} (glob)
+ 652413bf663ef2a641cab26574e46d5f5a64a55a cacdfd884a9321ec4e1de275ef3949fa953a1f83 0 (*) {'user': 'test'} (glob)
Ensure hidden revision does not prevent histedit
--- a/tests/test-histedit-outgoing.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-histedit-outgoing.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-hook.t Sun Sep 07 11:46:11 2014 -0500
@@ -210,10 +210,11 @@
$ hg push -B baz ../a
pushing to ../a
searching for changes
+ listkeys hook: HG_NAMESPACE=phases HG_VALUES={'cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b': '1', 'publishing': 'True'}
+ listkeys hook: HG_NAMESPACE=bookmarks HG_VALUES={'bar': '0000000000000000000000000000000000000000', 'foo': '0000000000000000000000000000000000000000'}
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'}
- listkeys hook: HG_NAMESPACE=bookmarks HG_VALUES={'bar': '0000000000000000000000000000000000000000', 'foo': '0000000000000000000000000000000000000000'}
exporting bookmark baz
prepushkey.forbid hook: HG_KEY=baz HG_NAMESPACE=bookmarks HG_NEW=0000000000000000000000000000000000000000
abort: prepushkey hook exited with status 1
--- a/tests/test-http-branchmap.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-http-branchmap.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-http-clone-r.t Sun Sep 07 11:46:11 2014 -0500
@@ -1,4 +1,4 @@
- $ "$TESTDIR/hghave" serve || exit 80
+#require serve
creating 'remote
--- a/tests/test-http-proxy.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-http-proxy.t Sun Sep 07 11:46:11 2014 -0500
@@ -1,4 +1,4 @@
- $ "$TESTDIR/hghave" serve || exit 80
+#require serve
$ hg init a
$ cd a
--- a/tests/test-http.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-http.t Sun Sep 07 11:46:11 2014 -0500
@@ -1,4 +1,4 @@
- $ "$TESTDIR/hghave" serve || exit 80
+#require serve
$ hg init test
$ cd test
@@ -261,13 +261,14 @@
"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=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks
"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
- "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks
#endif
$ cd ..
--- a/tests/test-https.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-https.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-hup.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-i18n.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-identify.t Sun Sep 07 11:46:11 2014 -0500
@@ -1,4 +1,4 @@
- $ "$TESTDIR/hghave" serve || exit 80
+#require serve
#if no-outer-repo
--- a/tests/test-import-bypass.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-import-bypass.t Sun Sep 07 11:46:11 2014 -0500
@@ -22,10 +22,13 @@
0 files updated, 0 files merged, 1 files removed, 0 files unresolved
Test importing an existing revision
-(this also tests that editor is not invoked for '--bypass', if the
-patch contains the commit message, regardless of '--edit')
+(this also tests that "hg import" disallows combination of '--exact'
+and '--edit')
- $ HGEDITOR=cat hg import --bypass --exact --edit ../test.diff
+ $ hg import --bypass --exact --edit ../test.diff
+ abort: cannot use --exact with --edit
+ [255]
+ $ hg import --bypass --exact ../test.diff
applying ../test.diff
$ shortlog
o 1:4e322f7ce8e3 test 0 0 - foo - changea
@@ -66,8 +69,10 @@
repository tip rolled back to revision 1 (undo import)
Test --import-branch
+(this also tests that editor is not invoked for '--bypass', if the
+patch contains the commit message, regardless of '--edit')
- $ hg import --bypass --import-branch ../test.diff
+ $ HGEDITOR=cat hg import --bypass --import-branch --edit ../test.diff
applying ../test.diff
$ shortlog
o 1:4e322f7ce8e3 test 0 0 - foo - changea
@@ -221,6 +226,25 @@
$ cd ..
+Test avoiding editor invocation at applying the patch with --exact
+even if commit message is empty
+
+ $ cd repo-options
+
+ $ echo a >> a
+ $ hg commit -m ' '
+ $ hg tip -T "{node}\n"
+ 1b77bc7d1db9f0e7f1716d515b630516ab386c89
+ $ hg export -o ../empty-log.diff .
+ $ hg update -q -C ".^1"
+ $ hg --config extensions.strip= strip -q tip
+ $ HGEDITOR=cat hg import --exact --bypass ../empty-log.diff
+ applying ../empty-log.diff
+ $ hg tip -T "{node}\n"
+ 1b77bc7d1db9f0e7f1716d515b630516ab386c89
+
+ $ cd ..
+
#if symlink execbit
Test complicated patch with --exact
--- a/tests/test-import-merge.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-import-merge.t Sun Sep 07 11:46:11 2014 -0500
@@ -30,6 +30,7 @@
(branch merge, don't forget to commit)
$ hg ci -m merge
$ hg export . > ../merge.diff
+ $ grep -v '^merge$' ../merge.diff > ../merge.nomsg.diff
$ cd ..
$ hg clone -r2 repo repo2
adding changesets
@@ -52,8 +53,13 @@
$ hg up 1
0 files updated, 0 files merged, 1 files removed, 0 files unresolved
- $ hg import ../merge.diff
- applying ../merge.diff
+ $ cat > $TESTTMP/editor.sh <<EOF
+ > env | grep HGEDITFORM
+ > echo merge > \$1
+ > EOF
+ $ HGEDITOR="sh $TESTTMP/editor.sh" hg import --edit ../merge.nomsg.diff
+ applying ../merge.nomsg.diff
+ HGEDITFORM=import.normal.merge
$ tipparents
1:540395c44225 changea
3:102a90ea7b4a addb
--- a/tests/test-import.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-import.t Sun Sep 07 11:46:11 2014 -0500
@@ -90,8 +90,13 @@
added 1 changesets with 2 changes to 2 files
updating to branch default
2 files updated, 0 files merged, 0 files removed, 0 files unresolved
- $ HGEDITOR=cat hg --cwd b import ../diffed-tip.patch
+ $ cat > $TESTTMP/editor.sh <<EOF
+ > env | grep HGEDITFORM
+ > cat \$1
+ > EOF
+ $ HGEDITOR="sh $TESTTMP/editor.sh" hg --cwd b import ../diffed-tip.patch
applying ../diffed-tip.patch
+ HGEDITFORM=import.normal.normal
HG: Enter commit message. Lines beginning with 'HG:' are removed.
@@ -102,6 +107,22 @@
HG: changed a
abort: empty commit message
[255]
+
+Test avoiding editor invocation at applying the patch with --exact,
+even if commit message is empty
+
+ $ echo a >> b/a
+ $ hg --cwd b commit -m ' '
+ $ hg --cwd b tip -T "{node}\n"
+ d8804f3f5396d800812f579c8452796a5993bdb2
+ $ hg --cwd b export -o ../empty-log.diff .
+ $ hg --cwd b update -q -C ".^1"
+ $ hg --cwd b --config extensions.strip= strip -q tip
+ $ HGEDITOR=cat hg --cwd b import --exact ../empty-log.diff
+ applying ../empty-log.diff
+ $ hg --cwd b tip -T "{node}\n"
+ d8804f3f5396d800812f579c8452796a5993bdb2
+
$ rm -r b
--- a/tests/test-incoming-outgoing.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-incoming-outgoing.t Sun Sep 07 11:46:11 2014 -0500
@@ -1,4 +1,4 @@
- $ "$TESTDIR/hghave" serve || exit 80
+#require serve
$ hg init test
$ cd test
--- a/tests/test-inherit-mode.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-inherit-mode.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-issue1438.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-issue1802.t Sun Sep 07 11:46:11 2014 -0500
@@ -1,4 +1,4 @@
- $ "$TESTDIR/hghave" execbit || exit 80
+#require execbit
Create extension that can disable exec checks:
--- a/tests/test-issue3084.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-issue3084.t Sun Sep 07 11:46:11 2014 -0500
@@ -29,10 +29,10 @@
$ echo "n" | hg merge --config ui.interactive=Yes
remote turned local normal file foo into a largefile
- use (l)argefile or keep (n)ormal file? 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+ use (l)argefile or keep (n)ormal file? getting changed largefiles
+ 0 largefiles updated, 0 removed
+ 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
(branch merge, don't forget to commit)
- getting changed largefiles
- 0 largefiles updated, 0 removed
$ hg status
$ cat foo
@@ -43,10 +43,10 @@
$ hg update -q -C
$ echo "l" | hg merge --config ui.interactive=Yes
remote turned local normal file foo into a largefile
- use (l)argefile or keep (n)ormal file? 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+ use (l)argefile or keep (n)ormal file? getting changed largefiles
+ 1 largefiles updated, 0 removed
+ 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
(branch merge, don't forget to commit)
- getting changed largefiles
- 1 largefiles updated, 0 removed
$ hg status
M foo
@@ -71,10 +71,10 @@
$ hg update -q -C -r 1
$ echo "n" | hg merge --config ui.interactive=Yes
remote turned local largefile foo into a normal file
- keep (l)argefile or use (n)ormal file? 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+ keep (l)argefile or use (n)ormal file? getting changed largefiles
+ 0 largefiles updated, 0 removed
+ 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
(branch merge, don't forget to commit)
- getting changed largefiles
- 0 largefiles updated, 0 removed
$ hg status
M foo
@@ -99,10 +99,10 @@
$ hg update -q -C -r 1
$ echo "l" | hg merge --config ui.interactive=Yes
remote turned local largefile foo into a normal file
- keep (l)argefile or use (n)ormal file? 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+ keep (l)argefile or use (n)ormal file? getting changed largefiles
+ 1 largefiles updated, 0 removed
+ 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
(branch merge, don't forget to commit)
- getting changed largefiles
- 1 largefiles updated, 0 removed
$ hg status
@@ -206,10 +206,10 @@
$ hg up -Cqr normal=
$ hg merge -r large
+ getting changed largefiles
+ 1 largefiles updated, 0 removed
1 files updated, 0 files merged, 1 files removed, 0 files unresolved
(branch merge, don't forget to commit)
- getting changed largefiles
- 1 largefiles updated, 0 removed
$ cat f
large
@@ -217,10 +217,10 @@
$ hg up -Cqr large
$ hg merge -r normal=
+ getting changed largefiles
+ 0 largefiles updated, 0 removed
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)
- getting changed largefiles
- 0 largefiles updated, 0 removed
$ cat f
large
@@ -233,10 +233,10 @@
use (c)hanged version or (d)elete? c
remote turned local normal file f into a largefile
use (l)argefile or keep (n)ormal file? l
+ getting changed largefiles
+ 1 largefiles updated, 0 removed
1 files updated, 0 files merged, 1 files removed, 0 files unresolved
(branch merge, don't forget to commit)
- getting changed largefiles
- 1 largefiles updated, 0 removed
$ cat f
large
@@ -244,20 +244,20 @@
$ ( echo c; echo n ) | hg merge -r large --config ui.interactive=Yes
local changed f which remote deleted
use (c)hanged version or (d)elete? remote turned local normal file f into a largefile
- use (l)argefile or keep (n)ormal file? 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+ use (l)argefile or keep (n)ormal file? getting changed largefiles
+ 0 largefiles updated, 0 removed
+ 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
(branch merge, don't forget to commit)
- getting changed largefiles
- 0 largefiles updated, 0 removed
$ cat f
normal2
$ hg up -Cqr normal2
$ echo d | hg merge -r large --config ui.interactive=Yes
local changed f which remote deleted
- use (c)hanged version or (d)elete? 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+ use (c)hanged version or (d)elete? getting changed largefiles
+ 1 largefiles updated, 0 removed
+ 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
(branch merge, don't forget to commit)
- getting changed largefiles
- 1 largefiles updated, 0 removed
$ cat f
large
@@ -269,10 +269,10 @@
use (c)hanged version or leave (d)eleted? c
remote turned local largefile f into a normal file
keep (l)argefile or use (n)ormal file? l
+ getting changed largefiles
+ 1 largefiles updated, 0 removed
1 files updated, 0 files merged, 1 files removed, 0 files unresolved
(branch merge, don't forget to commit)
- getting changed largefiles
- 1 largefiles updated, 0 removed
$ cat f
large
@@ -280,20 +280,20 @@
$ ( echo c; echo n ) | hg merge -r normal2 --config ui.interactive=Yes
remote changed f which local deleted
use (c)hanged version or leave (d)eleted? remote turned local largefile f into a normal file
- keep (l)argefile or use (n)ormal file? 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
+ keep (l)argefile or use (n)ormal file? getting changed largefiles
+ 0 largefiles updated, 0 removed
+ 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
(branch merge, don't forget to commit)
- getting changed largefiles
- 0 largefiles updated, 0 removed
$ cat f
normal2
$ hg up -Cqr large
$ echo d | hg merge -r normal2 --config ui.interactive=Yes
remote changed f which local deleted
- use (c)hanged version or leave (d)eleted? 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ use (c)hanged version or leave (d)eleted? getting changed largefiles
+ 0 largefiles updated, 0 removed
+ 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)
- getting changed largefiles
- 0 largefiles updated, 0 removed
$ cat f
large
@@ -301,10 +301,10 @@
$ hg up -Cqr large=
$ hg merge -r normal
+ getting changed largefiles
+ 0 largefiles updated, 0 removed
1 files updated, 0 files merged, 1 files removed, 0 files unresolved
(branch merge, don't forget to commit)
- getting changed largefiles
- 0 largefiles updated, 0 removed
$ cat f
normal
@@ -326,20 +326,20 @@
use (c)hanged version or (d)elete? c
remote turned local largefile f into a normal file
keep (l)argefile or use (n)ormal file? l
+ getting changed largefiles
+ 1 largefiles updated, 0 removed
0 files updated, 0 files merged, 1 files removed, 0 files unresolved
(branch merge, don't forget to commit)
- getting changed largefiles
- 1 largefiles updated, 0 removed
$ cat f
large2
$ hg up -Cqr large2
$ echo d | hg merge -r normal --config ui.interactive=Yes
local changed .hglf/f which remote deleted
- use (c)hanged version or (d)elete? 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+ use (c)hanged version or (d)elete? getting changed largefiles
+ 0 largefiles updated, 0 removed
+ 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
(branch merge, don't forget to commit)
- getting changed largefiles
- 0 largefiles updated, 0 removed
$ cat f
normal
@@ -351,10 +351,10 @@
use (c)hanged version or leave (d)eleted? c
remote turned local normal file f into a largefile
use (l)argefile or keep (n)ormal file? l
+ getting changed largefiles
+ 1 largefiles updated, 0 removed
2 files updated, 0 files merged, 1 files removed, 0 files unresolved
(branch merge, don't forget to commit)
- getting changed largefiles
- 1 largefiles updated, 0 removed
$ cat f
large2
--- a/tests/test-known.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-known.t Sun Sep 07 11:46:11 2014 -0500
@@ -1,4 +1,4 @@
- $ "$TESTDIR/hghave" killdaemons || exit 80
+#require killdaemons
= Test the known() protocol function =
--- a/tests/test-largefiles-misc.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-largefiles-misc.t Sun Sep 07 11:46:11 2014 -0500
@@ -659,10 +659,10 @@
R d1/f
$ hg merge
merging d2/f and d1/f to d2/f
+ getting changed largefiles
+ 0 largefiles updated, 0 removed
1 files updated, 1 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)
- getting changed largefiles
- 0 largefiles updated, 0 removed
$ cd ..
@@ -725,10 +725,10 @@
ancestor was 09d2af8dd22201dd8d48e5dcfcaed281ff9422c7
keep (l)ocal e5fa44f2b31c1fb553b6021e7360d07d5d91ff5e or
take (o)ther 7448d8798a4380162d4b56f9b452e2f6f9e24e7a? l
+ getting changed largefiles
+ 1 largefiles updated, 0 removed
0 files updated, 4 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)
- getting changed largefiles
- 1 largefiles updated, 0 removed
$ cat f-different
1
$ cat f-same
--- a/tests/test-largefiles-update.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-largefiles-update.t Sun Sep 07 11:46:11 2014 -0500
@@ -36,10 +36,10 @@
$ cat .hglf/large1
4669e532d5b2c093a78eca010077e708a071bb64
$ hg merge --config debug.dirstate.delaywrite=2
+ getting changed largefiles
+ 1 largefiles updated, 0 removed
2 files updated, 0 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)
- getting changed largefiles
- 1 largefiles updated, 0 removed
$ hg status -A large1
M large1
$ cat large1
@@ -67,10 +67,10 @@
take (o)ther 58e24f733a964da346e2407a2bee99d9001184f5? merging normal1
warning: conflicts during merge.
merging normal1 incomplete! (edit conflicts, then use 'hg resolve --mark')
+ getting changed largefiles
+ 1 largefiles updated, 0 removed
0 files updated, 1 files merged, 0 files removed, 1 files unresolved
use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
- getting changed largefiles
- 1 largefiles updated, 0 removed
[1]
$ hg status -A large1
M large1
@@ -99,4 +99,421 @@
$ cat .hglf/large1
58e24f733a964da346e2407a2bee99d9001184f5
+Test that "hg rollback" restores status of largefiles correctly
+
+ $ hg update -C -q
+ $ hg remove large1
+ $ test -f .hglf/large1
+ [1]
+ $ hg forget large2
+ $ test -f .hglf/large2
+ [1]
+ $ echo largeX > largeX
+ $ hg add --large largeX
+ $ cat .hglf/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
+ $ test -f .hglf/large1
+ [1]
+ $ hg status -A large2
+ R large2
+ $ test -f .hglf/large2
+ [1]
+ $ hg status -A largeX
+ A largeX
+ $ cat .hglf/largeX
+
+ $ hg status -A largeY
+ ? largeY
+ $ test -f .hglf/largeY
+ [1]
+
+Test that "hg rollback" restores standins correctly
+
+ $ hg commit -m 'will be rollback-ed soon'
+ $ hg update -q -C 2
+ $ cat large1
+ large1
+ $ cat .hglf/large1
+ 4669e532d5b2c093a78eca010077e708a071bb64
+ $ cat large2
+ large2 in #2
+ $ cat .hglf/large2
+ 3cfce6277e7668985707b6887ce56f9f62f6ccd9
+
+ $ hg rollback -q -f
+ $ cat large1
+ large1
+ $ cat .hglf/large1
+ 4669e532d5b2c093a78eca010077e708a071bb64
+ $ cat large2
+ large2 in #2
+ $ cat .hglf/large2
+ 3cfce6277e7668985707b6887ce56f9f62f6ccd9
+
+(rollback the parent of the working directory, when the parent of it
+is not branch-tip)
+
+ $ hg update -q -C 1
+ $ cat .hglf/large1
+ 58e24f733a964da346e2407a2bee99d9001184f5
+ $ cat .hglf/large2
+ 1deebade43c8c498a3c8daddac0244dc55d1331d
+
+ $ echo normalX > normalX
+ $ hg add normalX
+ $ hg commit -m 'will be rollback-ed soon'
+ $ hg rollback -q
+
+ $ cat .hglf/large1
+ 58e24f733a964da346e2407a2bee99d9001184f5
+ $ cat .hglf/large2
+ 1deebade43c8c498a3c8daddac0244dc55d1331d
+
+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
+
+Test that linear merge can detect modification (and conflict) correctly
+
+(linear merge without conflict)
+
+ $ echo 'large2 for linear merge (no conflict)' > large2
+ $ hg update 3 --config debug.dirstate.delaywrite=2
+ getting changed largefiles
+ 1 largefiles updated, 0 removed
+ 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ $ hg status -A large2
+ M large2
+ $ cat large2
+ large2 for linear merge (no conflict)
+ $ cat .hglf/large2
+ 9c4bf8f1b33536d6e5f89447e10620cfe52ea710
+
+(linear merge with conflict, choosing "other")
+
+ $ hg update -q -C 2
+ $ echo 'large1 for linear merge (conflict)' > large1
+ $ hg update 3 --config ui.interactive=True <<EOF
+ > o
+ > EOF
+ largefile large1 has a merge conflict
+ ancestor was 4669e532d5b2c093a78eca010077e708a071bb64
+ keep (l)ocal ba94c2efe5b7c5e0af8d189295ce00553b0612b7 or
+ take (o)ther e5bb990443d6a92aaf7223813720f7566c9dd05b? getting changed largefiles
+ 1 largefiles updated, 0 removed
+ 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
+ $ hg status -A large1
+ C large1
+ $ cat large1
+ large1 in #3
+ $ cat .hglf/large1
+ e5bb990443d6a92aaf7223813720f7566c9dd05b
+
+(linear merge with conflict, choosing "local")
+
+ $ hg update -q -C 2
+ $ echo 'large1 for linear merge (conflict)' > large1
+ $ hg update 3 --config debug.dirstate.delaywrite=2
+ largefile large1 has a merge conflict
+ ancestor was 4669e532d5b2c093a78eca010077e708a071bb64
+ keep (l)ocal ba94c2efe5b7c5e0af8d189295ce00553b0612b7 or
+ take (o)ther e5bb990443d6a92aaf7223813720f7566c9dd05b? l
+ 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
+ $ hg status -A large1
+ M large1
+ $ cat large1
+ large1 for linear merge (conflict)
+ $ cat .hglf/large1
+ ba94c2efe5b7c5e0af8d189295ce00553b0612b7
+
+Test a linear merge to a revision containing same-name normal file
+
+ $ hg update -q -C 3
+ $ hg remove large2
+ $ echo 'large2 as normal file' > large2
+ $ hg add large2
+ $ echo 'large3 as normal file' > large3
+ $ hg add large3
+ $ hg commit -m '#5'
+ $ hg manifest
+ .hglf/large1
+ large2
+ large3
+ normal1
+
+(modified largefile is already switched to normal)
+
+ $ hg update -q -C 2
+ $ echo 'modified large2 for linear merge' > large2
+ $ hg update -q 5
+ local changed .hglf/large2 which remote deleted
+ use (c)hanged version or (d)elete? c
+ remote turned local largefile large2 into a normal file
+ keep (l)argefile or use (n)ormal file? l
+ $ hg debugdirstate --nodates | grep large2
+ a 0 -1 .hglf/large2
+ r 0 0 large2
+ $ hg status -A large2
+ A large2
+ $ cat large2
+ modified large2 for linear merge
+
+(added largefile is already committed as normal)
+
+ $ hg update -q -C 2
+ $ echo 'large3 as large file for linear merge' > large3
+ $ hg add --large large3
+ $ hg update -q 5
+ remote turned local largefile large3 into a normal file
+ keep (l)argefile or use (n)ormal file? l
+ $ hg debugdirstate --nodates | grep large3
+ a 0 -1 .hglf/large3
+ r 0 0 large3
+ $ hg status -A large3
+ A large3
+ $ cat large3
+ large3 as large file for linear merge
+ $ rm -f large3 .hglf/large3
+
+Test that the internal linear merging works correctly
+(both heads are stripped to keep pairing of revision number and commit log)
+
+ $ hg update -q -C 2
+ $ hg strip 3 4
+ saved backup bundle to $TESTTMP/repo/.hg/strip-backup/9530e27857f7-backup.hg (glob)
+ $ mv .hg/strip-backup/9530e27857f7-backup.hg $TESTTMP
+
+(internal linear merging at "hg pull --update")
+
+ $ echo 'large1 for linear merge (conflict)' > large1
+ $ echo 'large2 for linear merge (conflict with normal file)' > large2
+ $ hg pull --update --config debug.dirstate.delaywrite=2 $TESTTMP/9530e27857f7-backup.hg
+ pulling from $TESTTMP/9530e27857f7-backup.hg (glob)
+ searching for changes
+ adding changesets
+ adding manifests
+ adding file changes
+ added 3 changesets with 5 changes to 5 files
+ local changed .hglf/large2 which remote deleted
+ use (c)hanged version or (d)elete? c
+ remote turned local largefile large2 into a normal file
+ keep (l)argefile or use (n)ormal file? l
+ largefile large1 has a merge conflict
+ ancestor was 4669e532d5b2c093a78eca010077e708a071bb64
+ keep (l)ocal ba94c2efe5b7c5e0af8d189295ce00553b0612b7 or
+ take (o)ther e5bb990443d6a92aaf7223813720f7566c9dd05b? l
+ 2 files updated, 1 files merged, 0 files removed, 0 files unresolved
+
+ $ hg status -A large1
+ M large1
+ $ cat large1
+ large1 for linear merge (conflict)
+ $ cat .hglf/large1
+ ba94c2efe5b7c5e0af8d189295ce00553b0612b7
+ $ hg status -A large2
+ A large2
+ $ cat large2
+ large2 for linear merge (conflict with normal file)
+ $ cat .hglf/large2
+ d7591fe9be0f6227d90bddf3e4f52ff41fc1f544
+
+(internal linear merging at "hg unbundle --update")
+
+ $ hg update -q -C 2
+ $ hg rollback -q
+
+ $ echo 'large1 for linear merge (conflict)' > large1
+ $ echo 'large2 for linear merge (conflict with normal file)' > large2
+ $ hg unbundle --update --config debug.dirstate.delaywrite=2 $TESTTMP/9530e27857f7-backup.hg
+ adding changesets
+ adding manifests
+ adding file changes
+ added 3 changesets with 5 changes to 5 files
+ local changed .hglf/large2 which remote deleted
+ use (c)hanged version or (d)elete? c
+ remote turned local largefile large2 into a normal file
+ keep (l)argefile or use (n)ormal file? l
+ largefile large1 has a merge conflict
+ ancestor was 4669e532d5b2c093a78eca010077e708a071bb64
+ keep (l)ocal ba94c2efe5b7c5e0af8d189295ce00553b0612b7 or
+ take (o)ther e5bb990443d6a92aaf7223813720f7566c9dd05b? l
+ 2 files updated, 1 files merged, 0 files removed, 0 files unresolved
+
+ $ hg status -A large1
+ M large1
+ $ cat large1
+ large1 for linear merge (conflict)
+ $ cat .hglf/large1
+ ba94c2efe5b7c5e0af8d189295ce00553b0612b7
+ $ hg status -A large2
+ A large2
+ $ cat large2
+ large2 for linear merge (conflict with normal file)
+ $ cat .hglf/large2
+ d7591fe9be0f6227d90bddf3e4f52ff41fc1f544
+
+(internal linear merging in subrepo at "hg update")
+
$ cd ..
+ $ hg init subparent
+ $ cd subparent
+
+ $ hg clone -q -u 2 ../repo sub
+ $ cat > .hgsub <<EOF
+ > sub = sub
+ > EOF
+ $ hg add .hgsub
+ $ hg commit -m '#0@parent'
+ $ cat .hgsubstate
+ f74e50bd9e5594b7cf1e6c5cbab86ddd25f3ca2f sub
+ $ hg -R sub update -q
+ $ hg commit -m '#1@parent'
+ $ cat .hgsubstate
+ d65e59e952a9638e2ce863b41a420ca723dd3e8d sub
+ $ hg update -q 0
+
+ $ echo 'large1 for linear merge (conflict)' > sub/large1
+ $ echo 'large2 for linear merge (conflict with normal file)' > sub/large2
+ $ hg update --config ui.interactive=True --config debug.dirstate.delaywrite=2 <<EOF
+ > m
+ > r
+ > c
+ > l
+ > l
+ > EOF
+ subrepository sub diverged (local revision: f74e50bd9e55, remote revision: d65e59e952a9)
+ (M)erge, keep (l)ocal or keep (r)emote? subrepository sources for sub differ (in checked out version)
+ use (l)ocal source (f74e50bd9e55) or (r)emote source (d65e59e952a9)?
+ local changed .hglf/large2 which remote deleted
+ use (c)hanged version or (d)elete? remote turned local largefile large2 into a normal file
+ keep (l)argefile or use (n)ormal file? largefile large1 has a merge conflict
+ ancestor was 4669e532d5b2c093a78eca010077e708a071bb64
+ keep (l)ocal ba94c2efe5b7c5e0af8d189295ce00553b0612b7 or
+ take (o)ther e5bb990443d6a92aaf7223813720f7566c9dd05b? 2 files updated, 1 files merged, 0 files removed, 0 files unresolved
+ 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+ $ hg -R sub status -A sub/large1
+ M sub/large1
+ $ cat sub/large1
+ large1 for linear merge (conflict)
+ $ cat sub/.hglf/large1
+ ba94c2efe5b7c5e0af8d189295ce00553b0612b7
+ $ hg -R sub status -A sub/large2
+ A sub/large2
+ $ cat sub/large2
+ large2 for linear merge (conflict with normal file)
+ $ cat sub/.hglf/large2
+ d7591fe9be0f6227d90bddf3e4f52ff41fc1f544
+
+ $ cd ..
+ $ cd repo
+
+Test that rebase updates largefiles in the working directory even if
+it is aborted by conflict.
+
+ $ hg update -q -C 3
+ $ cat .hglf/large1
+ e5bb990443d6a92aaf7223813720f7566c9dd05b
+ $ cat large1
+ large1 in #3
+ $ hg rebase -s 1 -d 3 --keep --config ui.interactive=True <<EOF
+ > o
+ > EOF
+ largefile large1 has a merge conflict
+ ancestor was 4669e532d5b2c093a78eca010077e708a071bb64
+ keep (l)ocal e5bb990443d6a92aaf7223813720f7566c9dd05b or
+ take (o)ther 58e24f733a964da346e2407a2bee99d9001184f5? merging normal1
+ warning: conflicts during merge.
+ merging normal1 incomplete! (edit conflicts, then use 'hg resolve --mark')
+ unresolved conflicts (see hg resolve, then hg rebase --continue)
+ [1]
+ $ cat .hglf/large1
+ 58e24f733a964da346e2407a2bee99d9001184f5
+ $ cat large1
+ large1 in #1
+
+ $ hg rebase -q --abort
+ rebase aborted
+
+Test that transplant updates largefiles, of which standins are safely
+changed, even if it is aborted by conflict of other.
+
+ $ hg update -q -C 5
+ $ cat .hglf/large1
+ e5bb990443d6a92aaf7223813720f7566c9dd05b
+ $ cat large1
+ large1 in #3
+ $ hg diff -c 4 .hglf/largeX | grep '^[+-][0-9a-z]'
+ +fa44618ea25181aff4f48b70428294790cec9f61
+ $ hg transplant 4
+ applying 07d6153b5c04
+ patching file .hglf/large1
+ Hunk #1 FAILED at 0
+ 1 out of 1 hunks FAILED -- saving rejects to file .hglf/large1.rej
+ patch failed to apply
+ abort: fix up the merge and run hg transplant --continue
+ [255]
+ $ hg status -A large1
+ C large1
+ $ cat .hglf/large1
+ e5bb990443d6a92aaf7223813720f7566c9dd05b
+ $ cat large1
+ large1 in #3
+ $ hg status -A largeX
+ A largeX
+ $ cat .hglf/largeX
+ fa44618ea25181aff4f48b70428294790cec9f61
+ $ cat largeX
+ largeX
+
+ $ cd ..
--- a/tests/test-largefiles.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-largefiles.t Sun Sep 07 11:46:11 2014 -0500
@@ -598,7 +598,7 @@
C sub2/large6
C sub2/large7
-Test commit -A (issue 3542)
+Test commit -A (issue3542)
$ echo large8 > large8
$ hg add --large large8
$ hg ci -Am 'this used to add large8 as normal and commit both'
@@ -1496,7 +1496,6 @@
$ cat sub2/large6
large6
$ hg revert --no-backup -C -r '.^' sub2
- reverting .hglf/sub2/large6 (glob)
$ hg revert --no-backup sub2
reverting .hglf/sub2/large6 (glob)
$ hg status
@@ -1604,11 +1603,11 @@
A f
created new head
$ hg merge -r 6
- 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
- (branch merge, don't forget to commit)
getting changed largefiles
large3: largefile 7838695e10da2bb75ac1156565f40a2595fa2fa0 not available from file:/*/$TESTTMP/d (glob)
1 largefiles updated, 0 removed
+ 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ (branch merge, don't forget to commit)
$ hg rollback -q
$ hg up -Cq
@@ -1662,10 +1661,10 @@
ancestor was 971fb41e78fea4f8e0ba5244784239371cb00591
keep (l)ocal d846f26643bfa8ec210be40cc93cc6b7ff1128ea or
take (o)ther e166e74c7303192238d60af5a9c4ce9bef0b7928? l
+ getting changed largefiles
+ 1 largefiles updated, 0 removed
3 files updated, 1 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)
- getting changed largefiles
- 1 largefiles updated, 0 removed
$ hg commit -m "Merge repos e and f"
Invoking status precommit hook
M normal3
@@ -1696,10 +1695,10 @@
M normal3
created new head
$ hg merge
+ getting changed largefiles
+ 1 largefiles updated, 0 removed
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)
- getting changed largefiles
- 1 largefiles updated, 0 removed
$ hg status
M large
@@ -1743,7 +1742,7 @@
adding file changes
added 1 changesets with 2 changes to 2 files
getting changed largefiles
- 1 largefiles updated, 0 removed
+ 0 largefiles updated, 0 removed
$ hg log --template '{rev}:{node|short} {desc|firstline}\n'
9:598410d3eb9a modify normal file largefile in repo d
8:a381d2c8c80e modify normal file and largefile in repo b
--- a/tests/test-lock-badness.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-lock-badness.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-log.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-merge-tools.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-merge-types.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-mq-qclone-http.t Sun Sep 07 11:46:11 2014 -0500
@@ -1,4 +1,4 @@
- $ "$TESTDIR/hghave" killdaemons || exit 80
+#require killdaemons
hide outer repo
$ hg init
--- a/tests/test-mq-qimport.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-mq-qimport.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-mq-qrefresh-interactive.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-mq-qrefresh-replace-log-message.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-mq-subrepo-svn.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-mq-symlinks.t Sun Sep 07 11:46:11 2014 -0500
@@ -1,4 +1,4 @@
- $ "$TESTDIR/hghave" symlink || exit 80
+#require symlink
$ echo "[extensions]" >> $HGRCPATH
$ echo "mq=" >> $HGRCPATH
--- a/tests/test-mq.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-mq.t Sun Sep 07 11:46:11 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-newbranch.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-newbranch.t Sun Sep 07 11:46:11 2014 -0500
@@ -51,11 +51,28 @@
date: Thu Jan 01 00:00:00 1970 +0000
summary: clear branch name
+Merging and branches
$ hg co foo
0 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ hg branch
foo
+
+ set existing branch name fails unless force - setting existing parent branch works without force:
+
+ $ hg branch bar
+ abort: a branch of the same name already exists
+ (use 'hg update' to switch to it)
+ [255]
+
+ $ hg branch -f bar
+ marked working directory as branch bar
+ (branches are permanent and global, did you want a bookmark?)
+
+ $ hg branch foo
+ marked working directory as branch foo
+ (branches are permanent and global, did you want a bookmark?)
+
$ echo bleah > a
$ hg ci -m "modify a branch"
@@ -65,46 +82,40 @@
$ hg branch
foo
+
+ set existing branch name where branch head is ancestor:
+
+ $ hg branch bar
+ abort: a branch of the same name already exists
+ (use 'hg update' to switch to it)
+ [255]
+
+ set (other) parent branch as branch name
+
+ $ hg branch default
+ marked working directory as branch default
+ (branches are permanent and global, did you want a bookmark?)
+
+ set (first) parent branch as branch name
+
+ $ hg branch foo
+ marked working directory as branch foo
+ (branches are permanent and global, did you want a bookmark?)
+
$ hg ci -m "merge"
- $ hg log
- changeset: 5:530046499edf
- branch: foo
- tag: tip
- parent: 4:adf1a74a7f7b
- parent: 3:1c28f494dae6
- user: test
- date: Thu Jan 01 00:00:00 1970 +0000
- summary: merge
-
- changeset: 4:adf1a74a7f7b
- branch: foo
- parent: 1:6c0e42da283a
- user: test
- date: Thu Jan 01 00:00:00 1970 +0000
- summary: modify a branch
-
- changeset: 3:1c28f494dae6
- user: test
- date: Thu Jan 01 00:00:00 1970 +0000
- summary: clear branch name
-
- changeset: 2:c21617b13b22
- branch: bar
- user: test
- date: Thu Jan 01 00:00:00 1970 +0000
- summary: change branch name
-
- changeset: 1:6c0e42da283a
- branch: foo
- user: test
- date: Thu Jan 01 00:00:00 1970 +0000
- summary: add branch name
-
- changeset: 0:db01e8ea3388
- user: test
- date: Thu Jan 01 00:00:00 1970 +0000
- summary: initial
+ $ hg log -G -T '{rev}:{node|short} {branch} {desc}\n'
+ @ 5:530046499edf foo merge
+ |\
+ | o 4:adf1a74a7f7b foo modify a branch
+ | |
+ o | 3:1c28f494dae6 default clear branch name
+ | |
+ o | 2:c21617b13b22 bar change branch name
+ |/
+ o 1:6c0e42da283a foo add branch name
+ |
+ o 0:db01e8ea3388 default initial
$ hg branches
foo 5:530046499edf
--- a/tests/test-newcgi.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-newcgi.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-newercgi.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-no-symlinks.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-obsolete.t Sun Sep 07 11:46:11 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"
@@ -52,17 +54,13 @@
[255]
$ hg debugobsolete -d '0 0' `getid kill_me` -u babar
$ hg debugobsolete
- 97b7c2d76b1845ed3eb988cd612611e72406cef0 0 {'date': '0 0', 'user': 'babar'}
+ 97b7c2d76b1845ed3eb988cd612611e72406cef0 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'babar'}
(test that mercurial is not confused)
$ 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
Killing a single changeset with itself should fail
@@ -90,13 +88,13 @@
$ hg log -r 'hidden()' --template '{rev}:{node|short} {desc}\n' --hidden
2:245bde4270cd add original_c
$ hg debugrevlog -cd
- # rev p1rev p2rev start end deltastart base p1 p2 rawsize totalsize compression heads
- 0 -1 -1 0 59 0 0 0 0 58 58 0 1
- 1 0 -1 59 118 59 59 0 0 58 116 0 1
- 2 1 -1 118 204 59 59 59 0 76 192 0 1
- 3 1 -1 204 271 204 204 59 0 66 258 0 2
+ # rev p1rev p2rev start end deltastart base p1 p2 rawsize totalsize compression heads chainlen
+ 0 -1 -1 0 59 0 0 0 0 58 58 0 1 0
+ 1 0 -1 59 118 59 59 0 0 58 116 0 1 0
+ 2 1 -1 118 204 59 59 59 0 76 192 0 1 1
+ 3 1 -1 204 271 204 204 59 0 66 258 0 2 0
$ hg debugobsolete
- 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C {'date': '56 12', 'user': 'test'}
+ 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:44 1970 -0000) {'user': 'test'}
do it again (it read the obsstore before adding new changeset)
@@ -106,8 +104,8 @@
created new head
$ hg debugobsolete -d '1337 0' `getid new_c` `getid new_2_c`
$ hg debugobsolete
- 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C {'date': '56 12', 'user': 'test'}
- cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 {'date': '1337 0', 'user': 'test'}
+ 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:44 1970 -0000) {'user': 'test'}
+ cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
Register two markers with a missing node
@@ -118,10 +116,10 @@
$ hg debugobsolete -d '1338 0' `getid new_2_c` 1337133713371337133713371337133713371337
$ hg debugobsolete -d '1339 0' 1337133713371337133713371337133713371337 `getid new_3_c`
$ hg debugobsolete
- 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C {'date': '56 12', 'user': 'test'}
- cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 {'date': '1337 0', 'user': 'test'}
- ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 {'date': '1338 0', 'user': 'test'}
- 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 {'date': '1339 0', 'user': 'test'}
+ 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:44 1970 -0000) {'user': 'test'}
+ cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
+ ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
+ 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
Refuse pathological nullid successors
$ hg debugobsolete -d '9001 0' 1337133713371337133713371337133713371337 0000000000000000000000000000000000000000
@@ -133,59 +131,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
@@ -212,13 +173,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]
@@ -230,27 +185,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
@@ -261,13 +202,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
@@ -297,27 +232,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
@@ -336,28 +257,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)
@@ -371,32 +274,32 @@
added 4 changesets with 4 changes to 4 files (+1 heads)
(run 'hg heads' to see heads, 'hg merge' to merge)
$ hg debugobsolete
- 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C {'date': '56 12', 'user': 'test'}
- cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 {'date': '1337 0', 'user': 'test'}
- ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 {'date': '1338 0', 'user': 'test'}
- 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 {'date': '1339 0', 'user': 'test'}
- 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 {'date': '1338 0', 'user': 'test'}
+ 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:44 1970 -0000) {'user': 'test'}
+ cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
+ ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
+ 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
+ 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
Rollback//Transaction support
$ hg debugobsolete -d '1340 0' aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
$ hg debugobsolete
- 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C {'date': '56 12', 'user': 'test'}
- cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 {'date': '1337 0', 'user': 'test'}
- ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 {'date': '1338 0', 'user': 'test'}
- 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 {'date': '1339 0', 'user': 'test'}
- 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 {'date': '1338 0', 'user': 'test'}
- aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb 0 {'date': '1340 0', 'user': 'test'}
+ 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:44 1970 -0000) {'user': 'test'}
+ cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
+ ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
+ 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
+ 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
+ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb 0 (Thu Jan 01 00:22:20 1970 +0000) {'user': 'test'}
$ hg rollback -n
repository tip rolled back to revision 3 (undo debugobsolete)
$ hg rollback
repository tip rolled back to revision 3 (undo debugobsolete)
$ hg debugobsolete
- 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C {'date': '56 12', 'user': 'test'}
- cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 {'date': '1337 0', 'user': 'test'}
- ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 {'date': '1338 0', 'user': 'test'}
- 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 {'date': '1339 0', 'user': 'test'}
- 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 {'date': '1338 0', 'user': 'test'}
+ 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:44 1970 -0000) {'user': 'test'}
+ cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
+ ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
+ 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
+ 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
$ cd ..
@@ -410,21 +313,22 @@
adding manifests
adding file changes
added 4 changesets with 4 changes to 4 files (+1 heads)
- $ hg -R tmpd debugobsolete
- 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C {'date': '56 12', 'user': 'test'}
- cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 {'date': '1337 0', 'user': 'test'}
- ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 {'date': '1338 0', 'user': 'test'}
- 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 {'date': '1339 0', 'user': 'test'}
- 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 {'date': '1338 0', 'user': 'test'}
+ $ hg -R tmpd debugobsolete | sort
+ 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
+ 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:44 1970 -0000) {'user': 'test'}
+ 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
+ ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
+ cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
Check obsolete keys are exchanged only if source has an obsolete store
$ hg init empty
$ hg --config extensions.debugkeys=debugkeys.py -R empty push tmpd
pushing to tmpd
+ listkeys phases
+ listkeys bookmarks
no changes found
listkeys phases
- listkeys bookmarks
[1]
clone support
@@ -434,52 +338,26 @@
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'}
- cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 {'date': '1337 0', 'user': 'test'}
- ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 {'date': '1338 0', 'user': 'test'}
- 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 {'date': '1339 0', 'user': 'test'}
- 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 {'date': '1338 0', 'user': 'test'}
+ 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:44 1970 -0000) {'user': 'test'}
+ cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
+ ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
+ 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
+ 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
Destination repo have existing data
@@ -489,7 +367,7 @@
$ hg init tmpe
$ cd tmpe
- $ hg debugobsolete -d '1339 0' 2448244824482448244824482448244824482448 1339133913391339133913391339133913391339
+ $ hg debugobsolete -d '1339 0' 1339133913391339133913391339133913391339 ca819180edb99ed25ceafb3e9584ac287e240b00
$ hg pull ../tmpb
pulling from ../tmpb
requesting all changes
@@ -499,12 +377,12 @@
added 4 changesets with 4 changes to 4 files (+1 heads)
(run 'hg heads' to see heads, 'hg merge' to merge)
$ hg debugobsolete
- 2448244824482448244824482448244824482448 1339133913391339133913391339133913391339 0 {'date': '1339 0', 'user': 'test'}
- 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C {'date': '56 12', 'user': 'test'}
- cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 {'date': '1337 0', 'user': 'test'}
- ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 {'date': '1338 0', 'user': 'test'}
- 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 {'date': '1339 0', 'user': 'test'}
- 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 {'date': '1338 0', 'user': 'test'}
+ 1339133913391339133913391339133913391339 ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
+ 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:44 1970 -0000) {'user': 'test'}
+ cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
+ ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
+ 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
+ 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
On push
@@ -515,78 +393,45 @@
no changes found
[1]
$ hg -R ../tmpc debugobsolete
- 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C {'date': '56 12', 'user': 'test'}
- cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 {'date': '1337 0', 'user': 'test'}
- ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 {'date': '1338 0', 'user': 'test'}
- 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 {'date': '1339 0', 'user': 'test'}
- 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 {'date': '1338 0', 'user': 'test'}
- 2448244824482448244824482448244824482448 1339133913391339133913391339133913391339 0 {'date': '1339 0', 'user': 'test'}
+ 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:44 1970 -0000) {'user': 'test'}
+ cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
+ ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
+ 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
+ 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
+ 1339133913391339133913391339133913391339 ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
detect outgoing obsolete and unstable
---------------------------------------
$ 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
$ mkcommit original_d
$ mkcommit original_e
- $ hg debugobsolete `getid original_d` -d '0 0'
+ $ hg debugobsolete --record-parents `getid original_d` -d '0 0'
+ $ hg debugobsolete | grep `getid original_d`
+ 94b33453f93bdb8d457ef9b770851a618bf413e1 0 {6f96419950729f3671185b847352890f074f7557} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
$ 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 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 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
@@ -615,38 +460,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
@@ -666,37 +485,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
@@ -705,13 +504,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
@@ -720,6 +513,74 @@
adding file changes
added 1 changesets with 1 changes to 1 files (+1 heads)
+test relevance computation
+---------------------------------------
+
+Checking simple case of "marker relevance".
+
+
+Reminder of the repo situation
+
+ $ hg log --hidden --graph
+ @ 6:3de5eca88c00 (draft) [tip ] add obsolete_e
+ |
+ | x 5:cda648ca50f5 (draft) [ ] add original_e
+ | |
+ | x 4:94b33453f93b (draft) [ ] add original_d
+ |/
+ o 3:6f9641995072 (draft) [ ] add n3w_3_c
+ |
+ | o 2:245bde4270cd (public) [ ] add original_c
+ |/
+ o 1:7c3bad9141dc (public) [ ] add b
+ |
+ o 0:1f0dee641bb7 (public) [ ] add a
+
+
+List of all markers
+
+ $ hg debugobsolete
+ 1339133913391339133913391339133913391339 ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
+ 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:44 1970 -0000) {'user': 'test'}
+ cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
+ ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
+ 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
+ 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
+ 94b33453f93bdb8d457ef9b770851a618bf413e1 0 {6f96419950729f3671185b847352890f074f7557} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+ cda648ca50f50482b7055c0b0c4c117bba6733d9 3de5eca88c00aa039da7399a220f4a5221faa585 0 (*) {'user': 'test'} (glob)
+
+List of changesets with no chain
+
+ $ hg debugobsolete --hidden --rev ::2
+
+List of changesets that are included on marker chain
+
+ $ hg debugobsolete --hidden --rev 6
+ cda648ca50f50482b7055c0b0c4c117bba6733d9 3de5eca88c00aa039da7399a220f4a5221faa585 0 (*) {'user': 'test'} (glob)
+
+List of changesets with a longer chain, (including a pruned children)
+
+ $ hg debugobsolete --hidden --rev 3
+ 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
+ 1339133913391339133913391339133913391339 ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
+ 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:44 1970 -0000) {'user': 'test'}
+ 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
+ 94b33453f93bdb8d457ef9b770851a618bf413e1 0 {6f96419950729f3671185b847352890f074f7557} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+ ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
+ cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
+
+List of both
+
+ $ hg debugobsolete --hidden --rev 3::6
+ 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
+ 1339133913391339133913391339133913391339 ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
+ 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:44 1970 -0000) {'user': 'test'}
+ 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
+ 94b33453f93bdb8d457ef9b770851a618bf413e1 0 {6f96419950729f3671185b847352890f074f7557} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+ ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
+ cda648ca50f50482b7055c0b0c4c117bba6733d9 3de5eca88c00aa039da7399a220f4a5221faa585 0 (*) {'user': 'test'} (glob)
+ cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
+
#if serve
check hgweb does not explode
@@ -781,13 +642,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
@@ -813,40 +668,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
@@ -861,13 +695,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
@@ -902,18 +730,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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-oldcgi.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-patchbomb.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-permissions.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-phases-exchange.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-pull-http.t Sun Sep 07 11:46:11 2014 -0500
@@ -1,4 +1,4 @@
- $ "$TESTDIR/hghave" killdaemons || exit 80
+#require killdaemons
$ hg init test
$ cd test
--- a/tests/test-pull-permission.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-pull-permission.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-pull.t Sun Sep 07 11:46:11 2014 -0500
@@ -1,4 +1,4 @@
- $ "$TESTDIR/hghave" serve || exit 80
+#require serve
$ hg init test
$ cd test
--- a/tests/test-push-cgi.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-push-cgi.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-push-http.t Sun Sep 07 11:46:11 2014 -0500
@@ -1,4 +1,4 @@
- $ "$TESTDIR/hghave" killdaemons || exit 80
+#require killdaemons
$ hg init test
$ cd test
--- a/tests/test-push-warn.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-push-warn.t Sun Sep 07 11:46:11 2014 -0500
@@ -35,6 +35,9 @@
searching: 2 queries
query 2; still undecided: 1, sample size is: 1
2 total queries
+ listing keys for "phases"
+ checking for updated bookmarks
+ listing keys for "bookmarks"
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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-qrecord.t Sun Sep 07 11:46:11 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-rebase-cache.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-rebase-cache.t Sun Sep 07 11:46:11 2014 -0500
@@ -470,5 +470,11 @@
o 0 A public
- $ hg rebase --dest 7 --source 5
+ $ cat > $TESTTMP/checkeditform.sh <<EOF
+ > env | grep HGEDITFORM
+ > true
+ > EOF
+ $ HGEDITOR="sh $TESTTMP/checkeditform.sh" hg rebase --dest 7 --source 5 -e
+ HGEDITFORM=rebase.merge
+ HGEDITFORM=rebase.normal
saved backup bundle to $TESTTMP/a3/c4/.hg/strip-backup/*-backup.hg (glob)
--- a/tests/test-rebase-collapse.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-rebase-collapse.t Sun Sep 07 11:46:11 2014 -0500
@@ -148,7 +148,12 @@
abort: message can only be specified with collapse
[255]
- $ hg rebase --source 4 --collapse -m 'custom message'
+ $ cat > $TESTTMP/checkeditform.sh <<EOF
+ > env | grep HGEDITFORM
+ > true
+ > EOF
+ $ HGEDITOR="sh $TESTTMP/checkeditform.sh" hg rebase --source 4 --collapse -m 'custom message' -e
+ HGEDITFORM=rebase.collapse
saved backup bundle to $TESTTMP/a3/.hg/strip-backup/*-backup.hg (glob)
$ hg tglog
--- a/tests/test-rebase-obsolete.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-rebase-obsolete.t Sun Sep 07 11:46:11 2014 -0500
@@ -101,9 +101,9 @@
o 0:cd010b8cd998 A
$ hg debugobsolete
- 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 e4e5be0395b2cbd471ed22a26b1b6a1a0658a794 0 {'date': '*', 'user': 'test'} (glob)
- 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b 2327fea05063f39961b14cb69435a9898dc9a245 0 {'date': '*', 'user': 'test'} (glob)
- 32af7686d403cf45b5d95f2d70cebea587ac806a 8eeb3c33ad33d452c89e5dcf611c347f978fb42b 0 {'date': '*', 'user': 'test'} (glob)
+ 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 e4e5be0395b2cbd471ed22a26b1b6a1a0658a794 0 (*) {'user': 'test'} (glob)
+ 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b 2327fea05063f39961b14cb69435a9898dc9a245 0 (*) {'user': 'test'} (glob)
+ 32af7686d403cf45b5d95f2d70cebea587ac806a 8eeb3c33ad33d452c89e5dcf611c347f978fb42b 0 (*) {'user': 'test'} (glob)
$ cd ..
@@ -166,19 +166,19 @@
o 0:cd010b8cd998 A
$ hg debugobsolete
- 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 0 {'date': '*', 'user': 'test'} (glob)
- 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b 5ae4c968c6aca831df823664e706c9d4aa34473d 0 {'date': '*', 'user': 'test'} (glob)
- 32af7686d403cf45b5d95f2d70cebea587ac806a 0 {'date': '*', 'user': 'test'} (glob)
+ 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 0 {cd010b8cd998f3981a5a8115f94f8da4ab506089} (*) {'user': 'test'} (glob)
+ 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b 5ae4c968c6aca831df823664e706c9d4aa34473d 0 (*) {'user': 'test'} (glob)
+ 32af7686d403cf45b5d95f2d70cebea587ac806a 0 {5fddd98957c8a54a4d436dfe1da9d87f21a1b97b} (*) {'user': 'test'} (glob)
More complex case were part of the rebase set were already rebased
$ hg rebase --rev 'desc(D)' --dest 'desc(H)'
$ hg debugobsolete
- 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 0 {'date': '*', 'user': 'test'} (glob)
- 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b 5ae4c968c6aca831df823664e706c9d4aa34473d 0 {'date': '*', 'user': 'test'} (glob)
- 32af7686d403cf45b5d95f2d70cebea587ac806a 0 {'date': '*', 'user': 'test'} (glob)
- 08483444fef91d6224f6655ee586a65d263ad34c 4596109a6a4328c398bde3a4a3b6737cfade3003 0 {'date': '* *', 'user': 'test'} (glob)
+ 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 0 {cd010b8cd998f3981a5a8115f94f8da4ab506089} (*) {'user': 'test'} (glob)
+ 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b 5ae4c968c6aca831df823664e706c9d4aa34473d 0 (*) {'user': 'test'} (glob)
+ 32af7686d403cf45b5d95f2d70cebea587ac806a 0 {5fddd98957c8a54a4d436dfe1da9d87f21a1b97b} (*) {'user': 'test'} (glob)
+ 08483444fef91d6224f6655ee586a65d263ad34c 4596109a6a4328c398bde3a4a3b6737cfade3003 0 (*) {'user': 'test'} (glob)
$ hg log -G
@ 11:4596109a6a43 D
|
@@ -200,13 +200,13 @@
$ hg rebase --source 'desc(B)' --dest 'tip'
$ hg debugobsolete
- 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 0 {'date': '* *', 'user': 'test'} (glob)
- 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b 5ae4c968c6aca831df823664e706c9d4aa34473d 0 {'date': '* *', 'user': 'test'} (glob)
- 32af7686d403cf45b5d95f2d70cebea587ac806a 0 {'date': '* *', 'user': 'test'} (glob)
- 08483444fef91d6224f6655ee586a65d263ad34c 4596109a6a4328c398bde3a4a3b6737cfade3003 0 {'date': '* *', 'user': 'test'} (glob)
- 8877864f1edb05d0e07dc4ba77b67a80a7b86672 462a34d07e599b87ea08676a449373fe4e2e1347 0 {'date': '* *', 'user': 'test'} (glob)
- 08483444fef91d6224f6655ee586a65d263ad34c 0 {'date': '* *', 'user': 'test'} (glob)
- 5ae4c968c6aca831df823664e706c9d4aa34473d 98f6af4ee9539e14da4465128f894c274900b6e5 0 {'date': '* *', 'user': 'test'} (glob)
+ 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 0 {cd010b8cd998f3981a5a8115f94f8da4ab506089} (*) {'user': 'test'} (glob)
+ 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b 5ae4c968c6aca831df823664e706c9d4aa34473d 0 (*) {'user': 'test'} (glob)
+ 32af7686d403cf45b5d95f2d70cebea587ac806a 0 {5fddd98957c8a54a4d436dfe1da9d87f21a1b97b} (*) {'user': 'test'} (glob)
+ 08483444fef91d6224f6655ee586a65d263ad34c 4596109a6a4328c398bde3a4a3b6737cfade3003 0 (*) {'user': 'test'} (glob)
+ 8877864f1edb05d0e07dc4ba77b67a80a7b86672 462a34d07e599b87ea08676a449373fe4e2e1347 0 (*) {'user': 'test'} (glob)
+ 08483444fef91d6224f6655ee586a65d263ad34c 0 {8877864f1edb05d0e07dc4ba77b67a80a7b86672} (*) {'user': 'test'} (glob)
+ 5ae4c968c6aca831df823664e706c9d4aa34473d 98f6af4ee9539e14da4465128f894c274900b6e5 0 (*) {'user': 'test'} (glob)
$ hg log --rev 'divergent()'
$ hg log -G
o 13:98f6af4ee953 C
@@ -286,9 +286,9 @@
$ hg id --debug -r tip
4dc2197e807bae9817f09905b50ab288be2dbbcf tip
$ hg debugobsolete
- 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 4dc2197e807bae9817f09905b50ab288be2dbbcf 0 {'date': '*', 'user': 'test'} (glob)
- 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b 4dc2197e807bae9817f09905b50ab288be2dbbcf 0 {'date': '*', 'user': 'test'} (glob)
- 32af7686d403cf45b5d95f2d70cebea587ac806a 4dc2197e807bae9817f09905b50ab288be2dbbcf 0 {'date': '*', 'user': 'test'} (glob)
+ 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 4dc2197e807bae9817f09905b50ab288be2dbbcf 0 (*) {'user': 'test'} (glob)
+ 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b 4dc2197e807bae9817f09905b50ab288be2dbbcf 0 (*) {'user': 'test'} (glob)
+ 32af7686d403cf45b5d95f2d70cebea587ac806a 4dc2197e807bae9817f09905b50ab288be2dbbcf 0 (*) {'user': 'test'} (glob)
$ cd ..
@@ -345,9 +345,9 @@
o 0:cd010b8cd998 A
$ hg debugobsolete
- 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b e273c5e7d2d29df783dce9f9eaa3ac4adc69c15d 0 {'date': '*', 'user': 'test'} (glob)
- 32af7686d403cf45b5d95f2d70cebea587ac806a cf44d2f5a9f4297a62be94cbdd3dff7c7dc54258 0 {'date': '*', 'user': 'test'} (glob)
- 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 7c6027df6a99d93f461868e5433f63bde20b6dfb 0 {'date': '*', 'user': 'test'} (glob)
+ 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b e273c5e7d2d29df783dce9f9eaa3ac4adc69c15d 0 (*) {'user': 'test'} (glob)
+ 32af7686d403cf45b5d95f2d70cebea587ac806a cf44d2f5a9f4297a62be94cbdd3dff7c7dc54258 0 (*) {'user': 'test'} (glob)
+ 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 7c6027df6a99d93f461868e5433f63bde20b6dfb 0 (*) {'user': 'test'} (glob)
Test that rewriting leaving instability behind is allowed
---------------------------------------------------------------------
--- a/tests/test-rebase-scenario-global.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-rebase-scenario-global.t Sun Sep 07 11:46:11 2014 -0500
@@ -663,7 +663,7 @@
o 0: 'A'
-Test that rebase is not confused by $CWD disappearing during rebase (issue 4121)
+Test that rebase is not confused by $CWD disappearing during rebase (issue4121)
$ cd ..
$ hg init cwd-vanish
--- a/tests/test-relink.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-relink.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-repair-strip.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-revert-flags.t Sun Sep 07 11:46:11 2014 -0500
@@ -1,4 +1,4 @@
- $ "$TESTDIR/hghave" execbit || exit 80
+#require execbit
$ hg init repo
$ cd repo
--- a/tests/test-revert.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-revert.t Sun Sep 07 11:46:11 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,807 @@
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
+
+ $ 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
+ undeleting modified_untracked-clean
+ undeleting modified_untracked-revert
+ undeleting modified_untracked-wc
+ reverting modified_wc
+ adding removed_clean
+ reverting removed_deleted
+ adding removed_removed
+ 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)
+
+ $ 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
+ 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
+
+ ### revert for: modified_deleted
+
+ ### revert for: modified_removed
+
+ ### revert for: modified_revert
+ no changes needed to 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
+ no changes needed to 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-rollback.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-rollback.t Sun Sep 07 11:46:11 2014 -0500
@@ -96,7 +96,7 @@
bar
$ hg bookmark --delete foo
-rollback by pretxncommit saves commit message (issue 1635)
+rollback by pretxncommit saves commit message (issue1635)
$ echo a >> a
$ hg --config hooks.pretxncommit=false commit -m"precious commit message"
--- a/tests/test-run-tests.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-run-tests.t Sun Sep 07 11:46:11 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,32 @@
$ cat test-failure.t
$ echo babar
rataxes
+ This is a noop statement so that
+ this test is still more bytes than success.
+
+Interactive with custom view
+
+ $ echo 'n' | $TESTDIR/run-tests.py --with-hg=`which hg` -i --view echo
+ $TESTTMP/test-failure.t $TESTTMP/test-failure.t.err
+ Accept this change? [n]* (glob)
+ 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]
+
+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 +281,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 +308,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: skipped
+ 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: skipped
+ # 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: skipped
+ # 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-schemes.t Sun Sep 07 11:46:11 2014 -0500
@@ -1,4 +1,4 @@
- $ "$TESTDIR/hghave" serve || exit 80
+#require serve
$ cat <<EOF >> $HGRCPATH
> [extensions]
--- a/tests/test-serve.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-serve.t Sun Sep 07 11:46:11 2014 -0500
@@ -1,4 +1,4 @@
- $ "$TESTDIR/hghave" serve || exit 80
+#require serve
$ hgserve()
> {
--- a/tests/test-share.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-share.t Sun Sep 07 11:46:11 2014 -0500
@@ -1,4 +1,4 @@
- $ "$TESTDIR/hghave" killdaemons || exit 80
+#require killdaemons
$ echo "[extensions]" >> $HGRCPATH
$ echo "share = " >> $HGRCPATH
--- a/tests/test-shelve.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-shelve.t Sun Sep 07 11:46:11 2014 -0500
@@ -446,7 +446,7 @@
$ hg --config extensions.mq=! unshelve
unshelving change 'test'
-shelve should leave dirstate clean (issue 4055)
+shelve should leave dirstate clean (issue4055)
$ cd ..
$ hg init shelverebase
@@ -475,7 +475,7 @@
$ cd ..
-shelve should only unshelve pending changes (issue 4068)
+shelve should only unshelve pending changes (issue4068)
$ hg init onlypendingchanges
$ cd onlypendingchanges
@@ -680,9 +680,6 @@
g
$ hg unshelve --abort
rebase aborted
- no changes needed to a
- no changes needed to d
- no changes needed to e
unshelve of 'default' aborted
$ hg st
? f.orig
--- a/tests/test-simplemerge.py Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-simplemerge.py Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-simplemerge.py.out Sun Sep 07 11:46:11 2014 -0500
@@ -1,5 +1,5 @@
-....................
+................
----------------------------------------------------------------------
-Ran 20 tests in 0.000s
+Ran 16 tests in 0.000s
OK
--- a/tests/test-ssh.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-ssh.t Sun Sep 07 11:46:11 2014 -0500
@@ -360,6 +360,47 @@
$ cd ..
+stderr from remote commands should be printed before stdout from local code (issue4336)
+
+ $ hg clone remote stderr-ordering
+ updating to branch default
+ 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ $ cd stderr-ordering
+ $ cat >> localwrite.py << EOF
+ > from mercurial import exchange, extensions
+ >
+ > def wrappedpush(orig, repo, *args, **kwargs):
+ > res = orig(repo, *args, **kwargs)
+ > repo.ui.write('local stdout\n')
+ > return res
+ >
+ > def extsetup(ui):
+ > extensions.wrapfunction(exchange, 'push', wrappedpush)
+ > EOF
+
+ $ cat >> .hg/hgrc << EOF
+ > [paths]
+ > default-push = ssh://user@dummy/remote
+ > [ui]
+ > ssh = python "$TESTDIR/dummyssh"
+ > [extensions]
+ > localwrite = localwrite.py
+ > EOF
+
+ $ echo localwrite > foo
+ $ hg commit -m 'testing localwrite'
+ $ hg push
+ pushing to ssh://user@dummy/remote
+ searching for changes
+ remote: adding changesets
+ remote: adding manifests
+ remote: adding file changes
+ remote: added 1 changesets with 1 changes to 1 files
+ remote: KABOOM
+ local stdout
+
+ $ cd ..
+
$ cat dummylog
Got arguments 1:user@dummy 2:hg -R nonexistent serve --stdio
Got arguments 1:user@dummy 2:hg -R /$TESTTMP/nonexistent serve --stdio
@@ -387,3 +428,5 @@
Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
+ Got arguments 1:user@dummy 2:hg -R remote serve --stdio
+ changegroup-in-remote hook: HG_NODE=65c38f4125f9602c8db4af56530cc221d93b8ef8 HG_SOURCE=serve HG_URL=remote:ssh:127.0.0.1
--- a/tests/test-static-http.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-static-http.t Sun Sep 07 11:46:11 2014 -0500
@@ -1,4 +1,4 @@
- $ "$TESTDIR/hghave" killdaemons || exit 80
+#require killdaemons
#if windows
$ hg clone http://localhost:$HGPORT/ copy
@@ -125,7 +125,7 @@
updating to branch default
2 files updated, 0 files merged, 0 files removed, 0 files unresolved
-test with "/" URI (issue 747) and subrepo
+test with "/" URI (issue747) and subrepo
$ hg init
$ hg init sub
--- a/tests/test-strict.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-strict.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-strip.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-subrepo-git.t Sun Sep 07 11:46:11 2014 -0500
@@ -1,4 +1,4 @@
- $ "$TESTDIR/hghave" git || exit 80
+#require git
make git commits repeatable
--- a/tests/test-subrepo-relative-path.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-subrepo-relative-path.t Sun Sep 07 11:46:11 2014 -0500
@@ -1,4 +1,4 @@
- $ "$TESTDIR/hghave" killdaemons || exit 80
+#require killdaemons
Preparing the subrepository 'sub'
--- a/tests/test-subrepo-svn.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-subrepo-svn.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-symlink-placeholder.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-symlinks.t Sun Sep 07 11:46:11 2014 -0500
@@ -1,4 +1,4 @@
- $ "$TESTDIR/hghave" symlink || exit 80
+#require symlink
== tests added in 0.7 ==
--- a/tests/test-transplant.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-transplant.t Sun Sep 07 11:46:11 2014 -0500
@@ -1,4 +1,4 @@
- $ "$TESTDIR/hghave" killdaemons || exit 80
+#require killdaemons
$ cat <<EOF >> $HGRCPATH
> [extensions]
@@ -95,8 +95,13 @@
$ hg ci -qm "b4"
$ hg status --rev "7^1" --rev 7
A b3
- $ HGEDITOR=cat hg transplant --edit 7
+ $ cat > $TESTTMP/checkeditform.sh <<EOF
+ > env | grep HGEDITFORM
+ > true
+ > EOF
+ $ HGEDITOR="sh $TESTTMP/checkeditform.sh; cat" hg transplant --edit 7
applying ffd6818a3975
+ HGEDITFORM=transplant.normal
b3
@@ -373,7 +378,8 @@
patch failed to apply
abort: fix up the merge and run hg transplant --continue
[255]
- $ hg transplant --continue
+ $ HGEDITOR="sh $TESTTMP/checkeditform.sh" hg transplant --continue -e
+ HGEDITFORM=transplant.normal
46ae92138f3c transplanted as 9159dada197d
$ hg transplant 1:3
skipping already applied revision 1:46ae92138f3c
@@ -430,9 +436,30 @@
transplant
- $ hg transplant -m 1
+ $ HGEDITOR="sh $TESTTMP/checkeditform.sh" hg transplant -m 1 -e
applying 42dc4432fd35
+ HGEDITFORM=transplant.merge
1:42dc4432fd35 merged at a9f4acbac129
+ $ hg update -q -C 2
+ $ cat > a <<EOF
+ > x
+ > y
+ > z
+ > EOF
+ $ hg commit -m replace
+ $ hg update -q -C 4
+ $ hg transplant -m 5
+ applying 600a3cdcb41d
+ patching file a
+ Hunk #1 FAILED at 0
+ 1 out of 1 hunks FAILED -- saving rejects to file a.rej
+ patch failed to apply
+ abort: fix up the merge and run hg transplant --continue
+ [255]
+ $ HGEDITOR="sh $TESTTMP/checkeditform.sh" hg transplant --continue -e
+ HGEDITFORM=transplant.merge
+ 600a3cdcb41d transplanted as a3f88be652e0
+
$ cd ..
test transplant into empty repository
--- a/tests/test-treediscovery-legacy.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-treediscovery-legacy.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-treediscovery.t Sun Sep 07 11:46:11 2014 -0500
@@ -1,4 +1,4 @@
- $ "$TESTDIR/hghave" killdaemons || exit 80
+#require killdaemons
Tests discovery against servers without getbundle support:
@@ -522,12 +522,13 @@
"GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases
"GET /?cmd=capabilities HTTP/1.1" 200 -
"GET /?cmd=heads HTTP/1.1" 200 -
+ "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases
+ "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks
"GET /?cmd=branchmap HTTP/1.1" 200 -
"GET /?cmd=branchmap HTTP/1.1" 200 -
"GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks
"POST /?cmd=unbundle HTTP/1.1" 200 - x-hgarg-1:heads=686173686564+1827a5bb63e602382eb89dd58f2ac9f3b007ad91
"GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases
- "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks
"GET /?cmd=capabilities HTTP/1.1" 200 -
"GET /?cmd=heads HTTP/1.1" 200 -
"GET /?cmd=capabilities HTTP/1.1" 200 -
--- a/tests/test-unbundlehash.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-unbundlehash.t Sun Sep 07 11:46:11 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 Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-update-issue1456.t Sun Sep 07 11:46:11 2014 -0500
@@ -1,4 +1,4 @@
- $ "$TESTDIR/hghave" execbit || exit 80
+#require execbit
$ rm -rf a
$ hg init a
--- a/tests/test-websub.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-websub.t Sun Sep 07 11:46:11 2014 -0500
@@ -1,4 +1,4 @@
- $ "$TESTDIR/hghave" serve || exit 80
+#require serve
$ hg init test
$ cd test
--- a/tests/test-wireproto.t Wed Sep 03 20:42:51 2014 +0200
+++ b/tests/test-wireproto.t Sun Sep 07 11:46:11 2014 -0500
@@ -1,4 +1,4 @@
- $ "$TESTDIR/hghave" killdaemons || exit 80
+#require killdaemons
Test wire protocol argument passing