--- a/contrib/check-code.py Wed Dec 01 04:21:47 2010 +0100
+++ b/contrib/check-code.py Wed Dec 01 11:04:50 2010 +0100
@@ -64,6 +64,7 @@
('^([^"\']|("[^"]*")|(\'[^\']*\'))*\\^', "^ must be quoted"),
(r'^source\b', "don't use 'source', use '.'"),
(r'touch -d', "don't use 'touch -d', use 'touch -t' instead"),
+ (r'ls\s+[^-]+\s+-', "options to 'ls' must come before filenames"),
]
testfilters = [
@@ -118,6 +119,9 @@
"linebreak after :"),
(r'class\s[^(]:', "old-style class, use class foo(object)"),
(r'^\s+del\(', "del isn't a function"),
+ (r'\band\(', "and isn't a function"),
+ (r'\bor\(', "or isn't a function"),
+ (r'\bnot\(', "not isn't a function"),
(r'^\s+except\(', "except isn't a function"),
(r',]', "unneeded trailing ',' in list"),
# (r'class\s[A-Z][^\(]*\((?!Exception)',
@@ -145,6 +149,9 @@
(r'raise Exception', "don't raise generic exceptions"),
(r'ui\.(status|progress|write|note|warn)\([\'\"]x',
"warning: unwrapped ui message"),
+ (r' is\s+(not\s+)?["\'0-9-]', "object comparison with literal"),
+ (r' [=!]=\s+(True|False|None)',
+ "comparison with singleton, use 'is' or 'is not' instead"),
]
pyfilters = [
--- a/doc/Makefile Wed Dec 01 04:21:47 2010 +0100
+++ b/doc/Makefile Wed Dec 01 11:04:50 2010 +0100
@@ -1,11 +1,13 @@
SOURCES=$(wildcard *.[0-9].txt)
MAN=$(SOURCES:%.txt=%)
HTML=$(SOURCES:%.txt=%.html)
-GENDOC=gendoc.py ../mercurial/commands.py ../mercurial/help.py ../mercurial/help/*.txt
+GENDOC=gendoc.py ../mercurial/commands.py ../mercurial/help.py \
+ ../mercurial/help/*.txt ../hgext/*.py ../hgext/*/__init__.py
PREFIX=/usr/local
MANDIR=$(PREFIX)/share/man
INSTALL=install -c -m 644
PYTHON=python
+RSTARGS=
export LANGUAGE=C
export LC_ALL=C
@@ -24,11 +26,11 @@
mv $@.tmp $@
%: %.txt common.txt
- $(PYTHON) runrst hgmanpage --halt warning \
+ $(PYTHON) runrst hgmanpage $(RSTARGS) --halt warning \
--strip-elements-with-class htmlonly $*.txt $*
%.html: %.txt common.txt
- $(PYTHON) runrst html --halt warning \
+ $(PYTHON) runrst html $(RSTARGS) --halt warning \
--link-stylesheet --stylesheet-path style.css $*.txt $*.html
MANIFEST: man html
--- a/hgext/bookmarks.py Wed Dec 01 04:21:47 2010 +0100
+++ b/hgext/bookmarks.py Wed Dec 01 11:04:50 2010 +0100
@@ -31,7 +31,7 @@
from mercurial.i18n import _
from mercurial.node import nullid, nullrev, bin, hex, short
from mercurial import util, commands, repair, extensions, pushkey, hg, url
-from mercurial import revset
+from mercurial import revset, encoding
import os
def write(repo):
@@ -52,7 +52,7 @@
try:
file = repo.opener('bookmarks', 'w', atomictemp=True)
for refspec, node in refs.iteritems():
- file.write("%s %s\n" % (hex(node), refspec))
+ file.write("%s %s\n" % (hex(node), encoding.fromlocal(refspec)))
file.rename()
# touch 00changelog.i so hgweb reloads bookmarks (no lock needed)
@@ -137,7 +137,7 @@
write(repo)
return
- if mark != None:
+ if mark is not None:
if "\n" in mark:
raise util.Abort(_("bookmark name cannot contain newlines"))
mark = mark.strip()
@@ -233,6 +233,7 @@
bookmarks = {}
for line in self.opener('bookmarks'):
sha, refspec = line.strip().split(' ', 1)
+ refspec = encoding.tolocal(refspec)
bookmarks[refspec] = self.changelog.lookup(sha)
except:
pass
@@ -333,7 +334,7 @@
rb = remote.listkeys('bookmarks')
for k in rb.keys():
if k in self._bookmarks:
- nr, nl = rb[k], self._bookmarks[k]
+ nr, nl = rb[k], hex(self._bookmarks[k])
if nr in self:
cr = self[nr]
cl = self[nl]
@@ -348,14 +349,12 @@
return result
def addchangegroup(self, *args, **kwargs):
- parents = self.dirstate.parents()
-
result = super(bookmark_repo, self).addchangegroup(*args, **kwargs)
if result > 1:
# We have more heads than before
return result
node = self.changelog.tip()
-
+ parents = self.dirstate.parents()
self._bookmarksupdate(parents, node)
return result
--- a/hgext/convert/__init__.py Wed Dec 01 04:21:47 2010 +0100
+++ b/hgext/convert/__init__.py Wed Dec 01 11:04:50 2010 +0100
@@ -59,10 +59,10 @@
--sourcesort try to preserve source revisions order, only
supported by Mercurial sources.
- If <REVMAP> isn't given, it will be put in a default location
- (<dest>/.hg/shamap by default). The <REVMAP> is a simple text file
- that maps each source commit ID to the destination ID for that
- revision, like so::
+ If ``REVMAP`` isn't given, it will be put in a default location
+ (``<dest>/.hg/shamap`` by default). The ``REVMAP`` is a simple
+ text file that maps each source commit ID to the destination ID
+ for that revision, like so::
<source ID> <destination ID>
@@ -138,15 +138,19 @@
Mercurial Source
''''''''''''''''
- --config convert.hg.ignoreerrors=False (boolean)
- ignore integrity errors when reading. Use it to fix Mercurial
- repositories with missing revlogs, by converting from and to
- Mercurial.
- --config convert.hg.saverev=False (boolean)
- store original revision ID in changeset (forces target IDs to
- change)
- --config convert.hg.startrev=0 (hg revision identifier)
- convert start revision and its descendants
+ The Mercurial source recognizes the following configuration
+ options, which you can set on the command line with ``--config``:
+
+ :convert.hg.ignoreerrors: ignore integrity errors when reading.
+ Use it to fix Mercurial repositories with missing revlogs, by
+ converting from and to Mercurial. Default is False.
+
+ :convert.hg.saverev: store original. revision ID in changeset
+ (forces target IDs to change). It takes and boolean argument
+ and defaults to False.
+
+ :convert.hg.startrev: convert start revision and its descendants.
+ It takes a hg revision identifier and defaults to 0.
CVS Source
''''''''''
@@ -154,42 +158,46 @@
CVS source will use a sandbox (i.e. a checked-out copy) from CVS
to indicate the starting point of what will be converted. Direct
access to the repository files is not needed, unless of course the
- repository is :local:. The conversion uses the top level directory
- in the sandbox to find the CVS repository, and then uses CVS rlog
- commands to find files to convert. This means that unless a
- filemap is given, all files under the starting directory will be
+ repository is ``:local:``. The conversion uses the top level
+ directory in the sandbox to find the CVS repository, and then uses
+ CVS rlog commands to find files to convert. This means that unless
+ a filemap is given, all files under the starting directory will be
converted, and that any directory reorganization in the CVS
sandbox is ignored.
- The options shown are the defaults.
+ The following options can be used with ``--config``:
+
+ :convert.cvsps.cache: Set to False to disable remote log caching,
+ for testing and debugging purposes. Default is True.
+
+ :convert.cvsps.fuzz: Specify the maximum time (in seconds) that is
+ allowed between commits with identical user and log message in
+ a single changeset. When very large files were checked in as
+ part of a changeset then the default may not be long enough.
+ The default is 60.
- --config convert.cvsps.cache=True (boolean)
- Set to False to disable remote log caching, for testing and
- debugging purposes.
- --config convert.cvsps.fuzz=60 (integer)
- Specify the maximum time (in seconds) that is allowed between
- commits with identical user and log message in a single
- changeset. When very large files were checked in as part of a
- changeset then the default may not be long enough.
- --config convert.cvsps.mergeto='{{mergetobranch ([-\\w]+)}}'
- Specify a regular expression to which commit log messages are
- matched. If a match occurs, then the conversion process will
- insert a dummy revision merging the branch on which this log
- message occurs to the branch indicated in the regex.
- --config convert.cvsps.mergefrom='{{mergefrombranch ([-\\w]+)}}'
- Specify a regular expression to which commit log messages are
- matched. If a match occurs, then the conversion process will
- add the most recent revision on the branch indicated in the
- regex as the second parent of the changeset.
- --config hook.cvslog
- Specify a Python function to be called at the end of gathering
- the CVS log. The function is passed a list with the log entries,
- and can modify the entries in-place, or add or delete them.
- --config hook.cvschangesets
- Specify a Python function to be called after the changesets
- are calculated from the the CVS log. The function is passed
- a list with the changeset entries, and can modify the changesets
- in-place, or add or delete them.
+ :convert.cvsps.mergeto: Specify a regular expression to which
+ commit log messages are matched. If a match occurs, then the
+ conversion process will insert a dummy revision merging the
+ branch on which this log message occurs to the branch
+ indicated in the regex. Default is ``{{mergetobranch
+ ([-\\w]+)}}``
+
+ :convert.cvsps.mergefrom: Specify a regular expression to which
+ commit log messages are matched. If a match occurs, then the
+ conversion process will add the most recent revision on the
+ branch indicated in the regex as the second parent of the
+ changeset. Default is ``{{mergefrombranch ([-\\w]+)}}``
+
+ :hook.cvslog: Specify a Python function to be called at the end of
+ gathering the CVS log. The function is passed a list with the
+ log entries, and can modify the entries in-place, or add or
+ delete them.
+
+ :hook.cvschangesets: Specify a Python function to be called after
+ the changesets are calculated from the the CVS log. The
+ function is passed a list with the changeset entries, and can
+ modify the changesets in-place, or add or delete them.
An additional "debugcvsps" Mercurial command allows the builtin
changeset merging code to be run without doing a conversion. Its
@@ -200,29 +208,33 @@
'''''''''''''''''
Subversion source detects classical trunk/branches/tags layouts.
- By default, the supplied "svn://repo/path/" source URL is
- converted as a single branch. If "svn://repo/path/trunk" exists it
- replaces the default branch. If "svn://repo/path/branches" exists,
- its subdirectories are listed as possible branches. If
- "svn://repo/path/tags" exists, it is looked for tags referencing
- converted branches. Default "trunk", "branches" and "tags" values
- can be overridden with following options. Set them to paths
+ By default, the supplied ``svn://repo/path/`` source URL is
+ converted as a single branch. If ``svn://repo/path/trunk`` exists
+ it replaces the default branch. If ``svn://repo/path/branches``
+ exists, its subdirectories are listed as possible branches. If
+ ``svn://repo/path/tags`` exists, it is looked for tags referencing
+ converted branches. Default ``trunk``, ``branches`` and ``tags``
+ values can be overridden with following options. Set them to paths
relative to the source URL, or leave them blank to disable auto
detection.
- --config convert.svn.branches=branches (directory name)
- specify the directory containing branches
- --config convert.svn.tags=tags (directory name)
- specify the directory containing tags
- --config convert.svn.trunk=trunk (directory name)
- specify the name of the trunk branch
+ The following options can be set with ``--config``:
+
+ :convert.svn.branches: specify the directory containing branches.
+ The defaults is ``branches``.
+
+ :convert.svn.tags: specify the directory containing tags. The
+ default is ``tags``.
+
+ :convert.svn.trunk: specify the name of the trunk branch The
+ defauls is ``trunk``.
Source history can be retrieved starting at a specific revision,
instead of being integrally converted. Only single branch
conversions are supported.
- --config convert.svn.startrev=0 (svn revision number)
- specify start Subversion revision.
+ :convert.svn.startrev: specify start Subversion revision number.
+ The default is 0.
Perforce Source
'''''''''''''''
@@ -232,24 +244,27 @@
source to a flat Mercurial repository, ignoring labels, branches
and integrations. Note that when a depot path is given you then
usually should specify a target directory, because otherwise the
- target may be named ...-hg.
+ target may be named ``...-hg``.
It is possible to limit the amount of source history to be
- converted by specifying an initial Perforce revision.
+ converted by specifying an initial Perforce revision:
- --config convert.p4.startrev=0 (perforce changelist number)
- specify initial Perforce revision.
+ :convert.p4.startrev: specify initial Perforce revision, a
+ Perforce changelist number).
Mercurial Destination
'''''''''''''''''''''
- --config convert.hg.clonebranches=False (boolean)
- dispatch source branches in separate clones.
- --config convert.hg.tagsbranch=default (branch name)
- tag revisions branch name
- --config convert.hg.usebranchnames=True (boolean)
- preserve branch names
+ The following options are supported:
+
+ :convert.hg.clonebranches: dispatch source branches in separate
+ clones. The default is False.
+ :convert.hg.tagsbranch: branch name for tag revisions, defaults to
+ ``default``.
+
+ :convert.hg.usebranchnames: preserve branch names. The default is
+ True
"""
return convcmd.convert(ui, src, dest, revmapfile, **opts)
--- a/hgext/eol.py Wed Dec 01 04:21:47 2010 +0100
+++ b/hgext/eol.py Wed Dec 01 11:04:50 2010 +0100
@@ -61,6 +61,11 @@
Such files are normally not touched under the assumption that they
have mixed EOLs on purpose.
+The extension provides ``cleverencode:`` and ``cleverdecode:`` filters
+like the deprecated win32text extension does. This means that you can
+disable win32text and enable eol and your filters will still work. You
+only need to these filters until you have prepared a ``.hgeol`` file.
+
The ``win32text.forbid*`` hooks provided by the win32text extension
have been unified into a single hook named ``eol.hook``. The hook will
lookup the expected line endings from the ``.hgeol`` file, which means
@@ -109,6 +114,9 @@
'to-lf': tolf,
'to-crlf': tocrlf,
'is-binary': isbinary,
+ # The following provide backwards compatibility with win32text
+ 'cleverencode:': tolf,
+ 'cleverdecode:': tocrlf
}
--- a/hgext/hgk.py Wed Dec 01 04:21:47 2010 +0100
+++ b/hgext/hgk.py Wed Dec 01 11:04:50 2010 +0100
@@ -181,14 +181,14 @@
if i + x >= count:
l[chunk - x:] = [0] * (chunk - x)
break
- if full != None:
+ if full is not None:
l[x] = repo[i + x]
l[x].changeset() # force reading
else:
l[x] = 1
for x in xrange(chunk - 1, -1, -1):
if l[x] != 0:
- yield (i + x, full != None and l[x] or None)
+ yield (i + x, full is not None and l[x] or None)
if i == 0:
break
--- a/hgext/keyword.py Wed Dec 01 04:21:47 2010 +0100
+++ b/hgext/keyword.py Wed Dec 01 11:04:50 2010 +0100
@@ -170,14 +170,25 @@
for k, v in kwmaps)
else:
self.templates = _defaultkwmaps(self.ui)
- escaped = '|'.join(map(re.escape, self.templates.keys()))
- self.re_kw = re.compile(r'\$(%s)\$' % escaped)
- self.re_kwexp = re.compile(r'\$(%s): [^$\n\r]*? \$' % escaped)
-
templatefilters.filters.update({'utcdate': utcdate,
'svnisodate': svnisodate,
'svnutcdate': svnutcdate})
+ @util.propertycache
+ def escape(self):
+ '''Returns bar-separated and escaped keywords.'''
+ return '|'.join(map(re.escape, self.templates.keys()))
+
+ @util.propertycache
+ def rekw(self):
+ '''Returns regex for unexpanded keywords.'''
+ return re.compile(r'\$(%s)\$' % self.escape)
+
+ @util.propertycache
+ def rekwexp(self):
+ '''Returns regex for expanded keywords.'''
+ return re.compile(r'\$(%s): [^$\n\r]*? \$' % self.escape)
+
def substitute(self, data, path, ctx, subfunc):
'''Replaces keywords in data with expanded template.'''
def kwsub(mobj):
@@ -191,11 +202,15 @@
return '$%s: %s $' % (kw, ekw)
return subfunc(kwsub, data)
+ def linkctx(self, path, fileid):
+ '''Similar to filelog.linkrev, but returns a changectx.'''
+ return self.repo.filectx(path, fileid=fileid).changectx()
+
def expand(self, path, node, data):
'''Returns data with keywords expanded.'''
if not self.restrict and self.match(path) and not util.binary(data):
- ctx = self.repo.filectx(path, fileid=node).changectx()
- return self.substitute(data, path, ctx, self.re_kw.sub)
+ ctx = self.linkctx(path, node)
+ return self.substitute(data, path, ctx, self.rekw.sub)
return data
def iskwfile(self, cand, ctx):
@@ -212,8 +227,8 @@
kwcmd = self.restrict and lookup # kwexpand/kwshrink
if self.restrict or expand and lookup:
mf = ctx.manifest()
- fctx = ctx
- subn = (self.restrict or rekw) and self.re_kw.subn or self.re_kwexp.subn
+ lctx = ctx
+ re_kw = (self.restrict or rekw) and self.rekw or self.rekwexp
msg = (expand and _('overwriting %s expanding keywords\n')
or _('overwriting %s shrinking keywords\n'))
for f in candidates:
@@ -225,12 +240,12 @@
continue
if expand:
if lookup:
- fctx = self.repo.filectx(f, fileid=mf[f]).changectx()
- data, found = self.substitute(data, f, fctx, subn)
+ lctx = self.linkctx(f, mf[f])
+ data, found = self.substitute(data, f, lctx, re_kw.subn)
elif self.restrict:
- found = self.re_kw.search(data)
+ found = re_kw.search(data)
else:
- data, found = _shrinktext(data, subn)
+ data, found = _shrinktext(data, re_kw.subn)
if found:
self.ui.note(msg % f)
self.repo.wwrite(f, data, ctx.flags(f))
@@ -242,7 +257,7 @@
def shrink(self, fname, text):
'''Returns text with all keyword substitutions removed.'''
if self.match(fname) and not util.binary(text):
- return _shrinktext(text, self.re_kwexp.sub)
+ return _shrinktext(text, self.rekwexp.sub)
return text
def shrinklines(self, fname, lines):
@@ -250,7 +265,7 @@
if self.match(fname):
text = ''.join(lines)
if not util.binary(text):
- return _shrinktext(text, self.re_kwexp.sub).splitlines(True)
+ return _shrinktext(text, self.rekwexp.sub).splitlines(True)
return lines
def wread(self, fname, data):
--- a/hgext/mq.py Wed Dec 01 04:21:47 2010 +0100
+++ b/hgext/mq.py Wed Dec 01 11:04:50 2010 +0100
@@ -1006,7 +1006,7 @@
raise util.Abort(_("patch %s not in series") % patch)
def push(self, repo, patch=None, force=False, list=False,
- mergeq=None, all=False, move=False):
+ mergeq=None, all=False, move=False, exact=False):
diffopts = self.diffopts()
wlock = repo.wlock()
try:
@@ -1015,7 +1015,7 @@
heads += ls
if not heads:
heads = [nullid]
- if repo.dirstate.parents()[0] not in heads:
+ if repo.dirstate.parents()[0] not in heads and not exact:
self.ui.status(_("(working directory not at a head)\n"))
if not self.series:
@@ -1062,6 +1062,18 @@
if not force:
self.check_localchanges(repo)
+ if exact:
+ if move:
+ raise util.Abort(_("cannot use --exact and --move together"))
+ if self.applied:
+ raise util.Abort(_("cannot push --exact with applied patches"))
+ root = self.series[start]
+ target = patchheader(self.join(root), self.plainmode).parent
+ if not target:
+ raise util.Abort(_("%s does not have a parent recorded" % root))
+ if not repo[target] == repo['.']:
+ hg.update(repo, target)
+
if move:
if not patch:
raise util.Abort(_("please specify the patch to move"))
@@ -1270,10 +1282,10 @@
# and then commit.
#
# this should really read:
- # mm, dd, aa, aa2 = repo.status(tip, patchparent)[:4]
+ # mm, dd, aa = repo.status(top, patchparent)[:3]
# but we do it backwards to take advantage of manifest/chlog
# caching against the next repo.status call
- mm, aa, dd, aa2 = repo.status(patchparent, top)[:4]
+ mm, aa, dd = repo.status(patchparent, top)[:3]
changes = repo.changelog.read(top)
man = repo.manifest.read(changes[0])
aaa = aa[:]
@@ -1289,6 +1301,9 @@
else:
match = cmdutil.matchall(repo)
m, a, r, d = repo.status(match=match)[:4]
+ mm = set(mm)
+ aa = set(aa)
+ dd = set(dd)
# we might end up with files that were added between
# qtip and the dirstate parent, but then changed in the
@@ -1299,7 +1314,7 @@
self.ui.warn(_('warning: not refreshing %s\n') % x)
continue
if x not in aa:
- mm.append(x)
+ mm.add(x)
# we might end up with files added by the local dirstate that
# were deleted by the patch. In this case, they should only
# show up in the changed section.
@@ -1308,10 +1323,10 @@
self.ui.warn(_('warning: not adding %s\n') % x)
continue
if x in dd:
- del dd[dd.index(x)]
- mm.append(x)
+ dd.remove(x)
+ mm.add(x)
else:
- aa.append(x)
+ aa.add(x)
# make sure any files deleted in the local dirstate
# are not in the add or change column of the patch
forget = []
@@ -1320,16 +1335,16 @@
self.ui.warn(_('warning: not removing %s\n') % x)
continue
if x in aa:
- del aa[aa.index(x)]
+ aa.remove(x)
forget.append(x)
continue
- elif x in mm:
- del mm[mm.index(x)]
- dd.append(x)
-
- m = list(set(mm))
- r = list(set(dd))
- a = list(set(aa))
+ else:
+ mm.discard(x)
+ dd.add(x)
+
+ m = list(mm)
+ r = list(dd)
+ a = list(aa)
c = [filter(matchfn, l) for l in (m, a, r)]
match = cmdutil.matchfiles(repo, set(c[0] + c[1] + c[2]))
chunks = patch.diff(repo, patchparent, match=match,
@@ -1529,7 +1544,7 @@
l = line.rstrip()
l = l[10:].split(' ')
qpp = [bin(x) for x in l]
- elif datastart != None:
+ elif datastart is not None:
l = line.rstrip()
n, name = l.split(':', 1)
if n:
@@ -2344,7 +2359,8 @@
mergeq = queue(ui, repo.join(""), newpath)
ui.warn(_("merging with queue at: %s\n") % mergeq.path)
ret = q.push(repo, patch, force=opts.get('force'), list=opts.get('list'),
- mergeq=mergeq, all=opts.get('all'), move=opts.get('move'))
+ mergeq=mergeq, all=opts.get('all'), move=opts.get('move'),
+ exact=opts.get('exact'))
return ret
def pop(ui, repo, patch=None, **opts):
@@ -3120,6 +3136,7 @@
"^qpush":
(push,
[('f', 'force', None, _('apply on top of local changes')),
+ ('e', 'exact', None, _('apply the target patch to its recorded parent')),
('l', 'list', None, _('list patch name in commit text')),
('a', 'all', None, _('apply all patches')),
('m', 'merge', None, _('merge from another queue (DEPRECATED)')),
--- a/hgext/record.py Wed Dec 01 04:21:47 2010 +0100
+++ b/hgext/record.py Wed Dec 01 11:04:50 2010 +0100
@@ -429,7 +429,7 @@
merge = len(repo[None].parents()) > 1
if merge:
raise util.Abort(_('cannot partially commit a merge '
- '(use hg commit instead)'))
+ '(use "hg commit" instead)'))
changes = repo.status(match=match)[:3]
diffopts = mdiff.diffopts(git=True, nodates=True)
--- a/hgext/transplant.py Wed Dec 01 04:21:47 2010 +0100
+++ b/hgext/transplant.py Wed Dec 01 11:04:50 2010 +0100
@@ -401,7 +401,7 @@
def hasnode(repo, node):
try:
- return repo.changelog.rev(node) != None
+ return repo.changelog.rev(node) is not None
except error.RevlogError:
return False
--- a/i18n/da.po Wed Dec 01 04:21:47 2010 +0100
+++ b/i18n/da.po Wed Dec 01 11:04:50 2010 +0100
@@ -17,8 +17,8 @@
msgstr ""
"Project-Id-Version: Mercurial\n"
"Report-Msgid-Bugs-To: <mercurial-devel@selenic.com>\n"
-"POT-Creation-Date: 2010-10-28 09:50+0200\n"
-"PO-Revision-Date: 2010-10-28 10:01+0200\n"
+"POT-Creation-Date: 2010-11-01 11:03+0100\n"
+"PO-Revision-Date: 2010-11-01 11:11+0100\n"
"Last-Translator: <mg@lazybytes.net>\n"
"Language-Team: Danish\n"
"MIME-Version: 1.0\n"
@@ -3396,6 +3396,10 @@
msgstr "\"%s\" kan ikke bruges som navnet på en rettelse"
#, python-format
+msgid "\"%s\" already exists as a directory"
+msgstr "\"%s\" eksisterer allerede som et katalog"
+
+#, python-format
msgid "patch \"%s\" already exists"
msgstr "rettelsen \"%s\" findes allerede"
@@ -3403,6 +3407,10 @@
msgstr "kan ikke håndtere sammenføjninger"
#, python-format
+msgid "cannot write patch \"%s\": %s"
+msgstr "kan ikke skrive patch \"%s\": %s"
+
+#, python-format
msgid "error unlinking %s\n"
msgstr "fejl ved sletning af %s\n"
@@ -4723,10 +4731,10 @@
msgid ""
" [pager]\n"
-" pager = LESS='FSRX' less"
+" pager = less -FRSX"
msgstr ""
" [pager]\n"
-" pager = LESS='FSRX' less"
+" pager = less -FRSX"
msgid ""
"If no pager is set, the pager extensions uses the environment variable\n"
@@ -4734,18 +4742,6 @@
msgstr ""
msgid ""
-"By default, the pager is only executed if a command has output. To\n"
-"force the pager to run even if a command prints nothing, set::"
-msgstr ""
-
-msgid ""
-" [pager]\n"
-" force = True"
-msgstr ""
-" [pager]\n"
-" force = True"
-
-msgid ""
"If you notice \"BROKEN PIPE\" error messages, you can disable them by\n"
"setting::"
msgstr ""
@@ -6225,6 +6221,12 @@
msgstr "noterer fjernelse af %s som en omdøbning til %s (%d%% lighed)\n"
#, python-format
+msgid "%s has not been committed yet, so no copy data will be stored for %s.\n"
+msgstr ""
+"%s er endnu ikke comitted, så der vil ikke blive gemt kopieringsdata for %"
+"s.\n"
+
+#, python-format
msgid "%s: not copying - file is not managed\n"
msgstr "%s: kopierer ikke - filen er ikke versionsstyret\n"
@@ -6264,12 +6266,6 @@
msgid "copying %s to %s\n"
msgstr "kopierer %s til %s\n"
-#, python-format
-msgid "%s has not been committed yet, so no copy data will be stored for %s.\n"
-msgstr ""
-"%s er endnu ikke comitted, så der vil ikke blive gemt kopieringsdata for %"
-"s.\n"
-
msgid "no source or destination specified"
msgstr "ingen kilde eller destination angivet"
@@ -9355,6 +9351,9 @@
msgid "[PATH]"
msgstr "[STI]"
+msgid "revlog format"
+msgstr ""
+
msgid "REPO NAMESPACE [KEY OLD NEW]"
msgstr ""
@@ -12984,10 +12983,10 @@
#, python-format
msgid "can't use %s here"
-msgstr ""
+msgstr "kan ikke bruge %s her"
msgid "can't use a list in this context"
-msgstr ""
+msgstr "en liste kan ikke bruges i denne konteks"
#, python-format
msgid "not a function: %s"
@@ -13004,7 +13003,7 @@
#. i18n: "id" is a keyword
msgid "id requires a string"
-msgstr ""
+msgstr "id kræver en streng"
msgid ""
"``rev(number)``\n"
@@ -13013,11 +13012,11 @@
#. i18n: "rev" is a keyword
msgid "rev requires one argument"
-msgstr ""
+msgstr "rev kræver et argument"
#. i18n: "rev" is a keyword
msgid "rev requires a number"
-msgstr ""
+msgstr "rev kræver et tal"
#. i18n: "rev" is a keyword
msgid "rev expects a number"
@@ -13298,20 +13297,23 @@
"``tag(name)``\n"
" The specified tag by name, or all tagged revisions if no name is given."
msgstr ""
+"``tag(navn)``\n"
+" Den navngivne mærkat eller alle revisioner med en mærkat hvis der\n"
+" ikke angives noget navn."
#. i18n: "tag" is a keyword
msgid "tag takes one or no arguments"
-msgstr ""
+msgstr "tag tager et eller to argumenter"
#. i18n: "tag" is a keyword
msgid "the argument to tag must be a string"
-msgstr ""
+msgstr "argumentet til tag skal være en streng"
msgid "can't negate that"
msgstr ""
msgid "not a symbol"
-msgstr ""
+msgstr "ikke et symbol"
msgid "empty query"
msgstr "tomt forespørgsel"
@@ -13560,11 +13562,11 @@
msgstr "certifikatet er for %s"
msgid "no commonName found in certificate"
-msgstr ""
+msgstr "fandt ikke noget commonName i certifikatet"
#, python-format
msgid "%s certificate error: %s"
-msgstr ""
+msgstr "%s certifikatfejl: %s"
#, python-format
msgid "command '%s' failed: %s"
@@ -13647,7 +13649,7 @@
#, python-format
msgid "no port number associated with service '%s'"
-msgstr ""
+msgstr "der er ikke knyttet noget portnummer til servicen '%s'"
msgid "cannot verify bundle or remote repos"
msgstr "kan ikke verificere bundt eller fjerndepoter"
@@ -13704,7 +13706,7 @@
msgstr "duplikeret revision %d (%d)"
msgid "abandoned transaction found - run hg recover\n"
-msgstr ""
+msgstr "fandt efterladt transaktion - kør hg recover\n"
#, python-format
msgid "repository uses revlog format %d\n"
@@ -13738,7 +13740,7 @@
msgstr "krydstjekker filer i ændringer og manifester\n"
msgid "crosschecking"
-msgstr ""
+msgstr "krydstjekker"
#, python-format
msgid "changeset refers to unknown manifest %s"
@@ -13766,7 +13768,7 @@
#, python-format
msgid "%s not in manifests"
-msgstr ""
+msgstr "%s findes ikke i manifestet"
#, python-format
msgid "unpacked size is %s, %s expected"
--- a/i18n/polib.py Wed Dec 01 04:21:47 2010 +0100
+++ b/i18n/polib.py Wed Dec 01 11:04:50 2010 +0100
@@ -105,7 +105,7 @@
... finally:
... os.unlink(tmpf)
"""
- if kwargs.get('autodetect_encoding', True) == True:
+ if kwargs.get('autodetect_encoding', True):
enc = detect_encoding(fpath)
else:
enc = kwargs.get('encoding', default_encoding)
@@ -159,7 +159,7 @@
... finally:
... os.unlink(tmpf)
"""
- if kwargs.get('autodetect_encoding', True) == True:
+ if kwargs.get('autodetect_encoding', True):
enc = detect_encoding(fpath, True)
else:
enc = kwargs.get('encoding', default_encoding)
--- a/mercurial/archival.py Wed Dec 01 04:21:47 2010 +0100
+++ b/mercurial/archival.py Wed Dec 01 11:04:50 2010 +0100
@@ -8,7 +8,7 @@
from i18n import _
from node import hex
import cmdutil
-import util
+import util, encoding
import cStringIO, os, stat, tarfile, time, zipfile
import zlib, gzip
@@ -243,7 +243,7 @@
if repo.ui.configbool("ui", "archivemeta", True):
def metadata():
base = 'repo: %s\nnode: %s\nbranch: %s\n' % (
- repo[0].hex(), hex(node), ctx.branch())
+ repo[0].hex(), hex(node), encoding.fromlocal(ctx.branch()))
tags = ''.join('tag: %s\n' % t for t in ctx.tags()
if repo.tagtype(t) == 'global')
--- a/mercurial/cmdutil.py Wed Dec 01 04:21:47 2010 +0100
+++ b/mercurial/cmdutil.py Wed Dec 01 11:04:50 2010 +0100
@@ -147,6 +147,11 @@
# attempt to parse old-style ranges first to deal with
# things like old-tag which contain query metacharacters
try:
+ if isinstance(spec, int):
+ seen.add(spec)
+ l.append(spec)
+ continue
+
if revrangesep in spec:
start, end = spec.split(revrangesep, 1)
start = revfix(repo, start, 0)
@@ -796,7 +801,6 @@
branch = ctx.branch()
# don't show the default branch name
if branch != 'default':
- branch = encoding.tolocal(branch)
self.ui.write(_("branch: %s\n") % branch,
label='log.branch')
for tag in self.repo.nodetags(changenode):
@@ -1352,8 +1356,7 @@
if ctx.p2():
edittext.append(_("HG: branch merge"))
if ctx.branch():
- edittext.append(_("HG: branch '%s'")
- % encoding.tolocal(ctx.branch()))
+ edittext.append(_("HG: branch '%s'") % ctx.branch())
edittext.extend([_("HG: subrepo %s") % s for s in subs])
edittext.extend([_("HG: added %s") % f for f in added])
edittext.extend([_("HG: changed %s") % f for f in modified])
--- a/mercurial/commands.py Wed Dec 01 04:21:47 2010 +0100
+++ b/mercurial/commands.py Wed Dec 01 11:04:50 2010 +0100
@@ -126,7 +126,7 @@
lastfunc = funcmap[-1]
funcmap[-1] = lambda x: "%s:%s" % (lastfunc(x), x[1])
- ctx = repo[opts.get('rev')]
+ ctx = cmdutil.revsingle(repo, opts.get('rev'))
m = cmdutil.match(repo, pats, opts)
follow = not opts.get('no_follow')
for abs in ctx.walk(m):
@@ -178,7 +178,7 @@
Returns 0 on success.
'''
- ctx = repo[opts.get('rev')]
+ ctx = cmdutil.revsingle(repo, opts.get('rev'))
if not ctx:
raise util.Abort(_('no working directory: please specify a revision'))
node = ctx.node()
@@ -243,7 +243,7 @@
opts['date'] = util.parsedate(date)
cmdutil.bail_if_changed(repo)
- node = repo.lookup(rev)
+ node = cmdutil.revsingle(repo, rev).node()
op1, op2 = repo.dirstate.parents()
a = repo.changelog.ancestor(op1, node)
@@ -408,7 +408,8 @@
raise util.Abort(_("%s killed") % command)
else:
transition = "bad"
- ctx = repo[rev or '.']
+ ctx = cmdutil.revsingle(repo, rev)
+ rev = None # clear for future iterations
state[transition].append(ctx.node())
ui.status(_('Changeset %d:%s: %s\n') % (ctx, ctx, transition))
check_state(state, interactive=False)
@@ -487,15 +488,14 @@
repo.dirstate.setbranch(label)
ui.status(_('reset working directory to branch %s\n') % label)
elif label:
- utflabel = encoding.fromlocal(label)
- if not opts.get('force') and utflabel in repo.branchtags():
+ if not opts.get('force') and label in repo.branchtags():
if label not in [p.branch() for p in repo.parents()]:
raise util.Abort(_('a branch of the same name already exists'
" (use 'hg update' to switch to it)"))
- repo.dirstate.setbranch(utflabel)
+ repo.dirstate.setbranch(label)
ui.status(_('marked working directory as branch %s\n') % label)
else:
- ui.write("%s\n" % encoding.tolocal(repo.dirstate.branch()))
+ ui.write("%s\n" % repo.dirstate.branch())
def branches(ui, repo, active=False, closed=False):
"""list repository named branches
@@ -524,9 +524,8 @@
for isactive, node, tag in branches:
if (not active) or isactive:
- encodedtag = encoding.tolocal(tag)
if ui.quiet:
- ui.write("%s\n" % encodedtag)
+ ui.write("%s\n" % tag)
else:
hn = repo.lookup(node)
if isactive:
@@ -542,10 +541,10 @@
notice = _(' (inactive)')
if tag == repo.dirstate.branch():
label = 'branches.current'
- rev = str(node).rjust(31 - encoding.colwidth(encodedtag))
+ rev = str(node).rjust(31 - encoding.colwidth(tag))
rev = ui.label('%s:%s' % (rev, hexfunc(hn)), 'log.changeset')
- encodedtag = ui.label(encodedtag, label)
- ui.write("%s %s%s\n" % (encodedtag, rev, notice))
+ tag = ui.label(tag, label)
+ ui.write("%s %s%s\n" % (tag, rev, notice))
def bundle(ui, repo, fname, dest=None, **opts):
"""create a changegroup file
@@ -572,11 +571,14 @@
Returns 0 on success, 1 if no changes found.
"""
- revs = opts.get('rev') or None
+ revs = None
+ if 'rev' in opts:
+ revs = cmdutil.revrange(repo, opts['rev'])
+
if opts.get('all'):
base = ['null']
else:
- base = opts.get('base')
+ base = cmdutil.revrange(repo, opts.get('base'))
if base:
if dest:
raise util.Abort(_("--base is incompatible with specifying "
@@ -1026,7 +1028,7 @@
def debugrebuildstate(ui, repo, rev="tip"):
"""rebuild the dirstate as it would look like for the given revision"""
- ctx = repo[rev]
+ ctx = cmdutil.revsingle(repo, rev)
wlock = repo.wlock()
try:
repo.dirstate.rebuild(ctx.node(), ctx.manifest())
@@ -1116,7 +1118,7 @@
key, old, new = keyinfo
r = target.pushkey(namespace, key, old, new)
ui.status(str(r) + '\n')
- return not(r)
+ return not r
else:
for k, v in target.listkeys(namespace).iteritems():
ui.write("%s\t%s\n" % (k.encode('string-escape'),
@@ -1140,12 +1142,12 @@
Returns 0 on success.
"""
- if not rev2:
- rev2 = hex(nullid)
+ r1 = cmdutil.revsingle(repo, rev1).node()
+ r2 = cmdutil.revsingle(repo, rev2, 'null').node()
wlock = repo.wlock()
try:
- repo.dirstate.setparents(repo.lookup(rev1), repo.lookup(rev2))
+ repo.dirstate.setparents(r1, r2)
finally:
wlock.release()
@@ -1174,9 +1176,8 @@
ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
def debugsub(ui, repo, rev=None):
- if rev == '':
- rev = None
- for k, v in sorted(repo[rev].substate.items()):
+ ctx = cmdutil.revsingle(repo, rev, None)
+ for k, v in sorted(ctx.substate.items()):
ui.write('path %s\n' % k)
ui.write(' source %s\n' % v[0])
ui.write(' revision %s\n' % v[1])
@@ -1435,7 +1436,7 @@
def debugrename(ui, repo, file1, *pats, **opts):
"""dump rename information"""
- ctx = repo[opts.get('rev')]
+ ctx = cmdutil.revsingle(repo, opts.get('rev'))
m = cmdutil.match(repo, (file1,) + pats, opts)
for abs in ctx.walk(m):
fctx = ctx[abs]
@@ -1808,10 +1809,9 @@
Returns 0 if matching heads are found, 1 if not.
"""
- if opts.get('rev'):
- start = repo.lookup(opts['rev'])
- else:
- start = None
+ start = None
+ if 'rev' in opts:
+ start = cmdutil.revsingle(repo, opts['rev'], None).node()
if opts.get('topo'):
heads = [repo[h] for h in repo.heads(start)]
@@ -1828,8 +1828,7 @@
heads += [repo[h] for h in ls if rev(h) in descendants]
if branchrevs:
- decode, encode = encoding.fromlocal, encoding.tolocal
- branches = set(repo[decode(br)].branch() for br in branchrevs)
+ branches = set(repo[br].branch() for br in branchrevs)
heads = [h for h in heads if h.branch() in branches]
if not opts.get('closed'):
@@ -1842,7 +1841,7 @@
if branchrevs:
haveheads = set(h.branch() for h in heads)
if branches - haveheads:
- headless = ', '.join(encode(b) for b in branches - haveheads)
+ headless = ', '.join(b for b in branches - haveheads)
msg = _('no open branch heads found on branches %s')
if opts.get('rev'):
msg += _(' (started at %s)' % opts['rev'])
@@ -2200,14 +2199,14 @@
output.append("%s%s" % ('+'.join([str(p.rev()) for p in parents]),
(changed) and "+" or ""))
else:
- ctx = repo[rev]
+ ctx = cmdutil.revsingle(repo, rev)
if default or id:
output = [hexfunc(ctx.node())]
if num:
output.append(str(ctx.rev()))
if repo.local() and default and not ui.quiet:
- b = encoding.tolocal(ctx.branch())
+ b = ctx.branch()
if b != 'default':
output.append("(%s)" % b)
@@ -2217,7 +2216,7 @@
output.append(t)
if branch:
- output.append(encoding.tolocal(ctx.branch()))
+ output.append(ctx.branch())
if tags:
output.extend(ctx.tags())
@@ -2279,6 +2278,7 @@
d = opts["base"]
strip = opts["strip"]
wlock = lock = None
+ msgs = []
def tryone(ui, hunk):
tmpname, message, user, date, branch, nodeid, p1, p2 = \
@@ -2329,7 +2329,10 @@
finally:
files = cmdutil.updatedir(ui, repo, files,
similarity=sim / 100.0)
- if not opts.get('no_commit'):
+ if opts.get('no_commit'):
+ if message:
+ msgs.append(message)
+ else:
if opts.get('exact'):
m = None
else:
@@ -2378,6 +2381,8 @@
if not haspatch:
raise util.Abort(_('no diffs found'))
+ if msgs:
+ repo.opener('last-message.txt', 'wb').write('\n* * *\n'.join(msgs))
finally:
release(lock, wlock)
@@ -2437,7 +2442,7 @@
Returns 0 if a match is found, 1 otherwise.
"""
end = opts.get('print0') and '\0' or '\n'
- rev = opts.get('rev') or None
+ rev = cmdutil.revsingle(repo, opts.get('rev'), None).node()
ret = 1
m = cmdutil.match(repo, pats, opts, default='relglob')
@@ -2572,7 +2577,7 @@
node = rev
decor = {'l':'644 @ ', 'x':'755 * ', '':'644 '}
- ctx = repo[node]
+ ctx = cmdutil.revsingle(repo, node)
for f in ctx:
if ui.debugflag:
ui.write("%40s " % hex(ctx.manifest()[f]))
@@ -2615,7 +2620,7 @@
node = opts.get('rev')
if not node:
- branch = repo.changectx(None).branch()
+ branch = repo[None].branch()
bheads = repo.branchheads(branch)
if len(bheads) > 2:
raise util.Abort(_(
@@ -2641,6 +2646,8 @@
raise util.Abort(_('working dir not at a head rev - '
'use "hg update" or merge with an explicit rev'))
node = parent == bheads[0] and bheads[-1] or bheads[0]
+ else:
+ node = cmdutil.revsingle(repo, node).node()
if opts.get('preview'):
# find nodes that are ancestors of p2 but not of p1
@@ -2686,11 +2693,8 @@
Returns 0 on success.
"""
- rev = opts.get('rev')
- if rev:
- ctx = repo[rev]
- else:
- ctx = repo[None]
+
+ ctx = cmdutil.revsingle(repo, opts.get('rev'), None)
if file_:
m = cmdutil.match(repo, (file_,), opts)
@@ -3098,15 +3102,16 @@
raise util.Abort(_("you can't specify a revision and a date"))
opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
+ parent, p2 = repo.dirstate.parents()
+ if not opts.get('rev') and p2 != nullid:
+ raise util.Abort(_('uncommitted merge - '
+ 'use "hg update", see "hg help revert"'))
+
if not pats and not opts.get('all'):
raise util.Abort(_('no files or directories specified; '
'use --all to revert the whole repo'))
- parent, p2 = repo.dirstate.parents()
- if not opts.get('rev') and p2 != nullid:
- raise util.Abort(_('uncommitted merge - please provide a '
- 'specific revision'))
- ctx = repo[opts.get('rev')]
+ ctx = cmdutil.revsingle(repo, opts.get('rev'))
node = ctx.node()
mf = ctx.manifest()
if node == parent:
@@ -3715,7 +3720,7 @@
if not rev_ and repo.dirstate.parents()[1] != nullid:
raise util.Abort(_('uncommitted merge - please provide a '
'specific revision'))
- r = repo[rev_].node()
+ r = cmdutil.revsingle(repo, rev_).node()
if not message:
# we don't translate commit messages
--- a/mercurial/config.py Wed Dec 01 04:21:47 2010 +0100
+++ b/mercurial/config.py Wed Dec 01 11:04:50 2010 +0100
@@ -130,7 +130,7 @@
name = m.group(1)
if sections and section not in sections:
continue
- if self.get(section, name) != None:
+ if self.get(section, name) is not None:
del self._data[section][name]
continue
--- a/mercurial/context.py Wed Dec 01 04:21:47 2010 +0100
+++ b/mercurial/context.py Wed Dec 01 11:04:50 2010 +0100
@@ -7,7 +7,7 @@
from node import nullid, nullrev, short, hex
from i18n import _
-import ancestor, bdiff, error, util, subrepo, patch
+import ancestor, bdiff, error, util, subrepo, patch, encoding
import os, errno, stat
propertycache = util.propertycache
@@ -109,7 +109,7 @@
def description(self):
return self._changeset[4]
def branch(self):
- return self._changeset[5].get("branch")
+ return encoding.tolocal(self._changeset[5].get("branch"))
def extra(self):
return self._changeset[5]
def tags(self):
@@ -179,7 +179,7 @@
"""
# deal with workingctxs
n2 = c2._node
- if n2 == None:
+ if n2 is None:
n2 = c2._parents[0]._node
n = self._repo.changelog.ancestor(self._node, n2)
return changectx(self._repo, n)
@@ -591,9 +591,8 @@
if extra:
self._extra = extra.copy()
if 'branch' not in self._extra:
- branch = self._repo.dirstate.branch()
try:
- branch = branch.decode('UTF-8').encode('UTF-8')
+ branch = encoding.fromlocal(self._repo.dirstate.branch())
except UnicodeDecodeError:
raise util.Abort(_('branch name not in UTF-8!'))
self._extra['branch'] = branch
@@ -603,6 +602,9 @@
def __str__(self):
return str(self._parents[0]) + "+"
+ def __repr__(self):
+ return "<workingctx %s>" % str(self)
+
def __nonzero__(self):
return True
@@ -712,7 +714,7 @@
assert self._clean is not None # must call status first
return self._clean
def branch(self):
- return self._extra['branch']
+ return encoding.tolocal(self._extra['branch'])
def extra(self):
return self._extra
@@ -902,6 +904,9 @@
def __str__(self):
return "%s@%s" % (self.path(), self._changectx)
+ def __repr__(self):
+ return "<workingfilectx %s>" % str(self)
+
def data(self):
return self._repo.wread(self._path)
def renamed(self):
@@ -1042,7 +1047,7 @@
def clean(self):
return self._status[6]
def branch(self):
- return self._extra['branch']
+ return encoding.tolocal(self._extra['branch'])
def extra(self):
return self._extra
def flags(self, f):
--- a/mercurial/demandimport.py Wed Dec 01 04:21:47 2010 +0100
+++ b/mercurial/demandimport.py Wed Dec 01 11:04:50 2010 +0100
@@ -111,7 +111,7 @@
mod = getattr(mod, comp)
for x in fromlist:
# set requested submodules for demand load
- if not(hasattr(mod, x)):
+ if not hasattr(mod, x):
setattr(mod, x, _demandmod(x, mod.__dict__, locals))
return mod
--- a/mercurial/dirstate.py Wed Dec 01 04:21:47 2010 +0100
+++ b/mercurial/dirstate.py Wed Dec 01 11:04:50 2010 +0100
@@ -7,7 +7,7 @@
from node import nullid
from i18n import _
-import util, ignore, osutil, parsers
+import util, ignore, osutil, parsers, encoding
import struct, os, stat, errno
import cStringIO
@@ -36,7 +36,7 @@
class dirstate(object):
- def __init__(self, opener, ui, root):
+ def __init__(self, opener, ui, root, validate):
'''Create a new dirstate object.
opener is an open()-like callable that can be used to open the
@@ -44,6 +44,7 @@
the dirstate.
'''
self._opener = opener
+ self._validate = validate
self._root = root
self._rootdir = os.path.join(root, '')
self._dirty = False
@@ -197,10 +198,10 @@
yield x
def parents(self):
- return self._pl
+ return [self._validate(p) for p in self._pl]
def branch(self):
- return self._branch
+ return encoding.tolocal(self._branch)
def setparents(self, p1, p2=nullid):
self._dirty = self._dirtypl = True
@@ -209,8 +210,8 @@
def setbranch(self, branch):
if branch in ['tip', '.', 'null']:
raise util.Abort(_('the name \'%s\' is reserved') % branch)
- self._branch = branch
- self._opener("branch", "w").write(branch + '\n')
+ self._branch = encoding.fromlocal(branch)
+ self._opener("branch", "w").write(self._branch + '\n')
def _read(self):
self._map = {}
--- a/mercurial/discovery.py Wed Dec 01 04:21:47 2010 +0100
+++ b/mercurial/discovery.py Wed Dec 01 11:04:50 2010 +0100
@@ -220,8 +220,6 @@
# - a local outgoing head descended from update
# - a remote head that's known locally and not
# ancestral to an outgoing head
- #
- # New named branches cannot be created without --force.
# 1. Create set of branches involved in the push.
branches = set(repo[n].branch() for n in outg)
@@ -280,20 +278,30 @@
# 5. Check for new heads.
# If there are more heads after the push than before, a suitable
- # warning, depending on unsynced status, is displayed.
+ # error message, depending on unsynced status, is displayed.
+ error = None
for branch in branches:
- if len(newmap[branch]) > len(oldmap[branch]):
+ newhs = set(newmap[branch])
+ oldhs = set(oldmap[branch])
+ if len(newhs) > len(oldhs):
+ if error is None:
+ if branch:
+ error = _("push creates new remote heads "
+ "on branch '%s'!") % branch
+ else:
+ error = _("push creates new remote heads!")
+ if branch in unsynced:
+ hint = _("you should pull and merge or "
+ "use push -f to force")
+ else:
+ hint = _("did you forget to merge? "
+ "use push -f to force")
if branch:
- msg = _("push creates new remote heads "
- "on branch '%s'!") % branch
- else:
- msg = _("push creates new remote heads!")
-
- if branch in unsynced:
- hint = _("you should pull and merge or use push -f to force")
- else:
- hint = _("did you forget to merge? use push -f to force")
- raise util.Abort(msg, hint=hint)
+ repo.ui.debug("new remote heads on branch '%s'\n" % branch)
+ for h in (newhs - oldhs):
+ repo.ui.debug("new remote head %s\n" % short(h))
+ if error:
+ raise util.Abort(error, hint=hint)
# 6. Check for unsynced changes on involved branches.
if unsynced:
--- a/mercurial/encoding.py Wed Dec 01 04:21:47 2010 +0100
+++ b/mercurial/encoding.py Wed Dec 01 11:04:50 2010 +0100
@@ -48,6 +48,16 @@
encodingmode = os.environ.get("HGENCODINGMODE", "strict")
fallbackencoding = 'ISO-8859-1'
+class localstr(str):
+ '''This class allows strings that are unmodified to be
+ round-tripped to the local encoding and back'''
+ def __new__(cls, u, l):
+ s = str.__new__(cls, l)
+ s._utf8 = u
+ return s
+ def __hash__(self):
+ return hash(self._utf8) # avoid collisions in local string space
+
def tolocal(s):
"""
Convert a string from internal UTF-8 to local encoding
@@ -57,17 +67,45 @@
other character sets. We attempt to decode everything strictly
using UTF-8, then Latin-1, and failing that, we use UTF-8 and
replace unknown characters.
+
+ The localstr class is used to cache the known UTF-8 encoding of
+ strings next to their local representation to allow lossless
+ round-trip conversion back to UTF-8.
+
+ >>> u = 'foo: \\xc3\\xa4' # utf-8
+ >>> l = tolocal(u)
+ >>> l
+ 'foo: ?'
+ >>> fromlocal(l)
+ 'foo: \\xc3\\xa4'
+ >>> u2 = 'foo: \\xc3\\xa1'
+ >>> d = { l: 1, tolocal(u2): 2 }
+ >>> d # no collision
+ {'foo: ?': 1, 'foo: ?': 2}
+ >>> 'foo: ?' in d
+ False
+ >>> l1 = 'foo: \\xe4' # historical latin1 fallback
+ >>> l = tolocal(l1)
+ >>> l
+ 'foo: ?'
+ >>> fromlocal(l) # magically in utf-8
+ 'foo: \\xc3\\xa4'
"""
+
for e in ('UTF-8', fallbackencoding):
try:
u = s.decode(e) # attempt strict decoding
- return u.encode(encoding, "replace")
+ if e == 'UTF-8':
+ return localstr(s, u.encode(encoding, "replace"))
+ else:
+ return localstr(u.encode('UTF-8'),
+ u.encode(encoding, "replace"))
except LookupError, k:
raise error.Abort("%s, please check your locale settings" % k)
except UnicodeDecodeError:
pass
u = s.decode("utf-8", "replace") # last ditch
- return u.encode(encoding, "replace")
+ return u.encode(encoding, "replace") # can't round-trip
def fromlocal(s):
"""
@@ -79,6 +117,11 @@
'replace', which replaces unknown characters with a special
Unicode character, and 'ignore', which drops the character.
"""
+
+ # can we do a lossless round-trip?
+ if isinstance(s, localstr):
+ return s._utf8
+
try:
return s.decode(encoding, encodingmode).encode("utf-8")
except UnicodeDecodeError, inst:
--- a/mercurial/hg.py Wed Dec 01 04:21:47 2010 +0100
+++ b/mercurial/hg.py Wed Dec 01 11:04:50 2010 +0100
@@ -32,24 +32,22 @@
return revs, revs[0]
branchmap = repo.branchmap()
- def primary(butf8):
- if butf8 == '.':
+ def primary(branch):
+ if branch == '.':
if not lrepo or not lrepo.local():
raise util.Abort(_("dirstate branch not accessible"))
- butf8 = lrepo.dirstate.branch()
- if butf8 in branchmap:
- revs.extend(node.hex(r) for r in reversed(branchmap[butf8]))
+ branch = lrepo.dirstate.branch()
+ if branch in branchmap:
+ revs.extend(node.hex(r) for r in reversed(branchmap[branch]))
return True
else:
return False
for branch in branches:
- butf8 = encoding.fromlocal(branch)
- if not primary(butf8):
+ if not primary(branch):
raise error.RepoLookupError(_("unknown branch '%s'") % branch)
if hashbranch:
- butf8 = encoding.fromlocal(hashbranch)
- if not primary(butf8):
+ if not primary(hashbranch):
revs.append(hashbranch)
return revs, revs[0]
@@ -365,8 +363,7 @@
except error.RepoLookupError:
continue
bn = dest_repo[uprev].branch()
- dest_repo.ui.status(_("updating to branch %s\n")
- % encoding.tolocal(bn))
+ dest_repo.ui.status(_("updating to branch %s\n") % bn)
_update(dest_repo, uprev)
return src_repo, dest_repo
--- a/mercurial/localrepo.py Wed Dec 01 04:21:47 2010 +0100
+++ b/mercurial/localrepo.py Wed Dec 01 11:04:50 2010 +0100
@@ -105,7 +105,7 @@
self._tags = None
self._tagtypes = None
- self._branchcache = None # in UTF-8
+ self._branchcache = None
self._branchcachetip = None
self.nodetagscache = None
self.filterpats = {}
@@ -178,7 +178,19 @@
@propertycache
def dirstate(self):
- return dirstate.dirstate(self.opener, self.ui, self.root)
+ warned = [0]
+ def validate(node):
+ try:
+ r = self.changelog.rev(node)
+ return node
+ except error.LookupError:
+ if not warned[0]:
+ warned[0] = True
+ self.ui.warn(_("warning: ignoring unknown"
+ " working parent %s!\n") % short(node))
+ return nullid
+
+ return dirstate.dirstate(self.opener, self.ui, self.root, validate)
def __getitem__(self, changeid):
if changeid is None:
@@ -423,7 +435,6 @@
bt[bn] = tip
return bt
-
def _readbranchcache(self):
partial = {}
try:
@@ -443,7 +454,8 @@
if not l:
continue
node, label = l.split(" ", 1)
- partial.setdefault(label.strip(), []).append(bin(node))
+ label = encoding.tolocal(label.strip())
+ partial.setdefault(label, []).append(bin(node))
except KeyboardInterrupt:
raise
except Exception, inst:
@@ -458,7 +470,7 @@
f.write("%s %s\n" % (hex(tip), tiprev))
for label, nodes in branches.iteritems():
for node in nodes:
- f.write("%s %s\n" % (hex(node), label))
+ f.write("%s %s\n" % (hex(node), encoding.fromlocal(label)))
f.rename()
except (IOError, OSError):
pass
@@ -647,7 +659,8 @@
except IOError:
ds = ""
self.opener("journal.dirstate", "w").write(ds)
- self.opener("journal.branch", "w").write(self.dirstate.branch())
+ self.opener("journal.branch", "w").write(
+ encoding.fromlocal(self.dirstate.branch()))
self.opener("journal.desc", "w").write("%d\n%s\n" % (len(self), desc))
renames = [(self.sjoin("journal"), self.sjoin("undo")),
@@ -705,7 +718,7 @@
except IOError:
self.ui.warn(_("Named branch could not be reset, "
"current branch still is: %s\n")
- % encoding.tolocal(self.dirstate.branch()))
+ % self.dirstate.branch())
self.invalidate()
self.dirstate.invalidate()
self.destroyed()
@@ -1207,8 +1220,7 @@
def heads(self, start=None):
heads = self.changelog.heads(start)
# sort the output in rev descending order
- heads = [(-self.changelog.rev(h), h) for h in heads]
- return [n for (r, n) in sorted(heads)]
+ return sorted(heads, key=self.changelog.rev, reverse=True)
def branchheads(self, branch=None, start=None, closed=False):
'''return a (possibly filtered) list of heads for the given branch
--- a/mercurial/manifest.py Wed Dec 01 04:21:47 2010 +0100
+++ b/mercurial/manifest.py Wed Dec 01 11:04:50 2010 +0100
@@ -171,19 +171,19 @@
raise AssertionError(
_("failed to remove %s from manifest") % f)
l = ""
- if dstart != None and dstart <= start and dend >= start:
+ if dstart is not None and dstart <= start and dend >= start:
if dend < end:
dend = end
if l:
dline.append(l)
else:
- if dstart != None:
+ if dstart is not None:
delta.append([dstart, dend, "".join(dline)])
dstart = start
dend = end
dline = [l]
- if dstart != None:
+ if dstart is not None:
delta.append([dstart, dend, "".join(dline)])
# apply the delta to the addlist, and get a delta for addrevision
cachedelta = (self.rev(p1), addlistdelta(addlist, delta))
--- a/mercurial/minirst.py Wed Dec 01 04:21:47 2010 +0100
+++ b/mercurial/minirst.py Wed Dec 01 11:04:50 2010 +0100
@@ -14,27 +14,8 @@
are just indented blocks that look like they are nested. This relies
on the user to keep the right indentation for the blocks.
-It only supports a small subset of reStructuredText:
-
-- sections
-
-- paragraphs
-
-- literal blocks
-
-- definition lists
-
-- specific admonitions
-
-- bullet lists (items must start with '-')
-
-- enumerated lists (no autonumbering)
-
-- field lists (colons cannot be escaped)
-
-- option lists (supports only long options without arguments)
-
-- inline literals (no other inline markup is not recognized)
+Remember to update http://mercurial.selenic.com/wiki/HelpStyleGuide
+when adding support for new constructs.
"""
import re, sys
@@ -118,7 +99,8 @@
return blocks
_bulletre = re.compile(r'(-|[0-9A-Za-z]+\.|\(?[0-9A-Za-z]+\)|\|) ')
-_optionre = re.compile(r'^(--[a-z-]+)((?:[ =][a-zA-Z][\w-]*)? +)(.*)$')
+_optionre = re.compile(r'^(-([a-zA-Z0-9]), )?(--[a-z0-9-]+)'
+ r'((.*) +)(.*)$')
_fieldre = re.compile(r':(?![: ])([^:]*)(?<! ):[ ]+(.*)')
_definitionre = re.compile(r'[^ ]')
@@ -192,6 +174,42 @@
return blocks
+def updateoptionlists(blocks):
+ i = 0
+ while i < len(blocks):
+ if blocks[i]['type'] != 'option':
+ i += 1
+ continue
+
+ optstrwidth = 0
+ j = i
+ while j < len(blocks) and blocks[j]['type'] == 'option':
+ m = _optionre.match(blocks[j]['lines'][0])
+
+ shortoption = m.group(2)
+ group3 = m.group(3)
+ longoption = group3[2:].strip()
+ desc = m.group(6).strip()
+ longoptionarg = m.group(5).strip()
+ blocks[j]['lines'][0] = desc
+
+ noshortop = ''
+ if not shortoption:
+ noshortop = ' '
+
+ opt = "%s%s" % (shortoption and "-%s " % shortoption or '',
+ ("%s--%s %s") % (noshortop, longoption,
+ longoptionarg))
+ opt = opt.rstrip()
+ blocks[j]['optstr'] = opt
+ optstrwidth = max(optstrwidth, encoding.colwidth(opt))
+ j += 1
+
+ for block in blocks[i:j]:
+ block['optstrwidth'] = optstrwidth
+ i = j + 1
+ return blocks
+
def prunecontainers(blocks, keep):
"""Prune unwanted containers.
@@ -297,8 +315,11 @@
i = 0
while i < len(blocks):
b = blocks[i]
- if b['type'] == 'paragraph' and b['lines'][0].startswith('.. '):
+ if b['type'] == 'paragraph' and (b['lines'][0].startswith('.. ') or
+ b['lines'] == ['..']):
del blocks[i]
+ if i < len(blocks) and blocks[i]['type'] == 'margin':
+ del blocks[i]
else:
i += 1
return blocks
@@ -338,6 +359,17 @@
'tip': _('Tip:'),
'warning': _('Warning!')}
+def formatoption(block, width):
+ desc = ' '.join(map(str.strip, block['lines']))
+ colwidth = encoding.colwidth(block['optstr'])
+ usablewidth = width - 1
+ hanging = block['optstrwidth']
+ initindent = '%s%s ' % (block['optstr'], ' ' * ((hanging - colwidth)))
+ hangindent = ' ' * (encoding.colwidth(initindent) + 1)
+ return ' %s' % (util.wrap(desc, usablewidth,
+ initindent=initindent,
+ hangindent=hangindent))
+
def formatblock(block, width):
"""Format a block according to width."""
if width <= 0:
@@ -394,9 +426,7 @@
key = key.ljust(_fieldwidth)
block['lines'][0] = key + block['lines'][0]
elif block['type'] == 'option':
- m = _optionre.match(block['lines'][0])
- option, arg, rest = m.groups()
- subindent = indent + (len(option) + len(arg)) * ' '
+ return formatoption(block, width)
text = ' '.join(map(str.strip, block['lines']))
return util.wrap(text, width=width,
@@ -416,8 +446,9 @@
blocks = hgrole(blocks)
blocks = splitparagraphs(blocks)
blocks = updatefieldlists(blocks)
+ blocks = updateoptionlists(blocks)
+ blocks = addmargins(blocks)
blocks = prunecomments(blocks)
- blocks = addmargins(blocks)
blocks = findadmonitions(blocks)
text = '\n'.join(formatblock(b, width) for b in blocks)
if keep is None:
@@ -443,8 +474,9 @@
blocks = debug(inlineliterals, blocks)
blocks = debug(splitparagraphs, blocks)
blocks = debug(updatefieldlists, blocks)
+ blocks = debug(updateoptionlists, blocks)
blocks = debug(findsections, blocks)
+ blocks = debug(addmargins, blocks)
blocks = debug(prunecomments, blocks)
- blocks = debug(addmargins, blocks)
blocks = debug(findadmonitions, blocks)
print '\n'.join(formatblock(b, 30) for b in blocks)
--- a/mercurial/patch.py Wed Dec 01 04:21:47 2010 +0100
+++ b/mercurial/patch.py Wed Dec 01 11:04:50 2010 +0100
@@ -974,7 +974,7 @@
fp.seek(pos)
return gitpatches
-def iterhunks(ui, fp, sourcefile=None):
+def iterhunks(ui, fp):
"""Read a patch and yield the following events:
- ("file", afile, bfile, firsthunk): select a new target file.
- ("hunk", hunk): a new hunk is ready to be applied, follows a
@@ -995,10 +995,6 @@
BFILE = 1
context = None
lr = linereader(fp)
- # gitworkdone is True if a git operation (copy, rename, ...) was
- # performed already for the current file. Useful when the file
- # section may have no hunk.
- gitworkdone = False
while True:
newfile = newgitfile = False
@@ -1010,7 +1006,7 @@
current_hunk.fix_newline()
yield 'hunk', current_hunk
current_hunk = None
- if ((sourcefile or state == BFILE) and ((not context and x[0] == '@') or
+ if (state == BFILE and ((not context and x[0] == '@') or
((context is not False) and x.startswith('***************')))):
if context is None and x.startswith('***************'):
context = True
@@ -1032,7 +1028,6 @@
elif x.startswith('diff --git'):
# check for git diff, scanning the whole patch file if needed
m = gitre.match(x)
- gitworkdone = False
if m:
afile, bfile = m.group(1, 2)
if not git:
@@ -1047,7 +1042,6 @@
if gp and (gp.op in ('COPY', 'DELETE', 'RENAME', 'ADD')
or gp.mode):
afile = bfile
- gitworkdone = True
newgitfile = True
elif x.startswith('---'):
# check for a unified diff
@@ -1075,9 +1069,6 @@
afile = parsefilename(x)
bfile = parsefilename(l2)
- if newfile:
- gitworkdone = False
-
if newgitfile or newfile:
emitfile = True
state = BFILE
@@ -1089,7 +1080,7 @@
raise PatchError(_("malformed patch %s %s") % (afile,
current_hunk.desc))
-def applydiff(ui, fp, changed, strip=1, sourcefile=None, eolmode='strict'):
+def applydiff(ui, fp, changed, strip=1, eolmode='strict'):
"""Reads a patch from fp and tries to apply it.
The dict 'changed' is filled in with all of the filenames changed
@@ -1103,13 +1094,10 @@
Callers probably want to call 'cmdutil.updatedir' after this to
apply certain categories of changes not done by this function.
"""
- return _applydiff(
- ui, fp, patchfile, copyfile,
- changed, strip=strip, sourcefile=sourcefile, eolmode=eolmode)
+ return _applydiff(ui, fp, patchfile, copyfile, changed, strip=strip,
+ eolmode=eolmode)
-
-def _applydiff(ui, fp, patcher, copyfn, changed, strip=1,
- sourcefile=None, eolmode='strict'):
+def _applydiff(ui, fp, patcher, copyfn, changed, strip=1, eolmode='strict'):
rejects = 0
err = 0
current_file = None
@@ -1124,7 +1112,7 @@
current_file.write_rej()
return len(current_file.rej)
- for state, values in iterhunks(ui, fp, sourcefile):
+ for state, values in iterhunks(ui, fp):
if state == 'hunk':
if not current_file:
continue
@@ -1137,14 +1125,10 @@
rejects += closefile()
afile, bfile, first_hunk = values
try:
- if sourcefile:
- current_file = patcher(ui, sourcefile, opener,
- eolmode=eolmode)
- else:
- current_file, missing = selectfile(afile, bfile,
- first_hunk, strip)
- current_file = patcher(ui, current_file, opener,
- missing=missing, eolmode=eolmode)
+ current_file, missing = selectfile(afile, bfile,
+ first_hunk, strip)
+ current_file = patcher(ui, current_file, opener,
+ missing=missing, eolmode=eolmode)
except PatchError, err:
ui.warn(str(err) + '\n')
current_file = None
--- a/mercurial/revlog.py Wed Dec 01 04:21:47 2010 +0100
+++ b/mercurial/revlog.py Wed Dec 01 11:04:50 2010 +0100
@@ -212,7 +212,7 @@
return None
self.mapfind_count += 1
last = self.l - 1
- while self.index[last] != None:
+ while self.index[last] is not None:
if last == 0:
self.all = 1
self.allmap = 1
--- a/mercurial/revset.py Wed Dec 01 04:21:47 2010 +0100
+++ b/mercurial/revset.py Wed Dec 01 11:04:50 2010 +0100
@@ -202,9 +202,13 @@
return [r for r in subset if r == l]
def p1(repo, subset, x):
- """``p1(set)``
- First parent of changesets in set.
+ """``p1([set])``
+ First parent of changesets in set, or the working directory.
"""
+ if x is None:
+ p = repo[x].parents()[0].rev()
+ return [r for r in subset if r == p]
+
ps = set()
cl = repo.changelog
for r in getset(repo, range(len(repo)), x):
@@ -212,9 +216,17 @@
return [r for r in subset if r in ps]
def p2(repo, subset, x):
- """``p2(set)``
- Second parent of changesets in set.
+ """``p2([set])``
+ Second parent of changesets in set, or the working directory.
"""
+ if x is None:
+ ps = repo[x].parents()
+ try:
+ p = ps[1].rev()
+ return [r for r in subset if r == p]
+ except IndexError:
+ return []
+
ps = set()
cl = repo.changelog
for r in getset(repo, range(len(repo)), x):
@@ -222,9 +234,13 @@
return [r for r in subset if r in ps]
def parents(repo, subset, x):
- """``parents(set)``
- The set of all parents for all changesets in set.
+ """``parents([set])``
+ The set of all parents for all changesets in set, or the working directory.
"""
+ if x is None:
+ ps = tuple(p.rev() for p in repo[x].parents())
+ return [r for r in subset if r in ps]
+
ps = set()
cl = repo.changelog
for r in getset(repo, range(len(repo)), x):
@@ -699,7 +715,7 @@
}
def optimize(x, small):
- if x == None:
+ if x is None:
return 0, x
smallbonus = 1
--- a/mercurial/subrepo.py Wed Dec 01 04:21:47 2010 +0100
+++ b/mercurial/subrepo.py Wed Dec 01 11:04:50 2010 +0100
@@ -6,7 +6,7 @@
# GNU General Public License version 2 or any later version.
import errno, os, re, xml.dom.minidom, shutil, urlparse, posixpath
-import stat, subprocess
+import stat, subprocess, tarfile
from i18n import _
import config, util, node, error, cmdutil
hg = None
@@ -604,7 +604,234 @@
return self._svncommand(['cat'], name)
+class gitsubrepo(object):
+ def __init__(self, ctx, path, state):
+ # TODO add git version check.
+ self._state = state
+ self._ctx = ctx
+ self._relpath = path
+ self._path = ctx._repo.wjoin(path)
+ self._ui = ctx._repo.ui
+
+ def _gitcommand(self, commands, stream=False):
+ return self._gitdir(commands, stream=stream)[0]
+
+ def _gitdir(self, commands, stream=False):
+ commands = ['--no-pager', '--git-dir=%s/.git' % self._path,
+ '--work-tree=%s' % self._path] + commands
+ return self._gitnodir(commands, stream=stream)
+
+ def _gitnodir(self, commands, stream=False):
+ """Calls the git command
+
+ The methods tries to call the git command. versions previor to 1.6.0
+ are not supported and very probably fail.
+ """
+ cmd = ['git'] + commands
+ cmd = [util.shellquote(arg) for arg in cmd]
+ cmd = util.quotecommand(' '.join(cmd))
+
+ # print git's stderr, which is mostly progress and useful info
+ p = subprocess.Popen(cmd, shell=True, bufsize=-1,
+ close_fds=util.closefds,
+ stdout=subprocess.PIPE)
+ if stream:
+ return p.stdout, None
+
+ retdata = p.stdout.read()
+ # wait for the child to exit to avoid race condition.
+ p.wait()
+
+ if p.returncode != 0:
+ # there are certain error codes that are ok
+ command = None
+ for arg in commands:
+ if not arg.startswith('-'):
+ command = arg
+ break
+ if command == 'cat-file':
+ return retdata, p.returncode
+ if command in ('commit', 'status') and p.returncode == 1:
+ return retdata, p.returncode
+ # for all others, abort
+ raise util.Abort('git %s error %d' % (command, p.returncode))
+
+ return retdata, p.returncode
+
+ def _gitstate(self):
+ return self._gitcommand(['rev-parse', 'HEAD']).strip()
+
+ def _githavelocally(self, revision):
+ out, code = self._gitdir(['cat-file', '-e', revision])
+ return code == 0
+
+ def _gitisancestor(self, r1, r2):
+ base = self._gitcommand(['merge-base', r1, r2]).strip()
+ return base == r1
+
+ def _gitbranchmap(self):
+ 'returns the current branch and a map from git revision to branch[es]'
+ bm = {}
+ redirects = {}
+ current = None
+ out = self._gitcommand(['branch', '-a', '--no-color',
+ '--verbose', '--abbrev=40'])
+ for line in out.split('\n'):
+ if not line:
+ continue
+ if line[2:].startswith('(no branch)'):
+ continue
+ branch, revision = line[2:].split()[:2]
+ if revision == '->':
+ continue # ignore remote/HEAD redirects
+ if line[0] == '*':
+ current = branch
+ bm.setdefault(revision, []).append(branch)
+ return current, bm
+
+ def _fetch(self, source, revision):
+ if not os.path.exists('%s/.git' % self._path):
+ self._ui.status(_('cloning subrepo %s\n') % self._relpath)
+ self._gitnodir(['clone', source, self._path])
+ if self._githavelocally(revision):
+ return
+ self._ui.status(_('pulling subrepo %s\n') % self._relpath)
+ self._gitcommand(['fetch', '--all', '-q'])
+ if not self._githavelocally(revision):
+ raise util.Abort(_("revision %s does not exist in subrepo %s\n") %
+ (revision, self._path))
+
+ def dirty(self):
+ if self._state[1] != self._gitstate(): # version checked out changed?
+ return True
+ # check for staged changes or modified files; ignore untracked files
+ # docs say --porcelain flag is future-proof format
+ changed = self._gitcommand(['status', '--porcelain',
+ '--untracked-files=no'])
+ return bool(changed.strip())
+
+ def get(self, state):
+ source, revision, kind = state
+ self._fetch(source, revision)
+ # if the repo was set to be bare, unbare it
+ if self._gitcommand(['config', '--get', 'core.bare']
+ ).strip() == 'true':
+ self._gitcommand(['config', 'core.bare', 'false'])
+ if self._gitstate() == revision:
+ self._gitcommand(['reset', '--hard', 'HEAD'])
+ return
+ elif self._gitstate() == revision:
+ return
+ current, bm = self._gitbranchmap()
+ if revision not in bm:
+ # no branch to checkout, check it out with no branch
+ self._ui.warn(_('checking out detached HEAD in subrepo %s\n') %
+ self._relpath)
+ self._ui.warn(_('check out a git branch if you intend '
+ 'to make changes\n'))
+ self._gitcommand(['checkout', '-q', revision])
+ return
+ branches = bm[revision]
+ firstlocalbranch = None
+ for b in branches:
+ if b == 'master':
+ # master trumps all other branches
+ self._gitcommand(['checkout', 'master'])
+ return
+ if not firstlocalbranch and not b.startswith('remotes/'):
+ firstlocalbranch = b
+ if firstlocalbranch:
+ self._gitcommand(['checkout', firstlocalbranch])
+ else:
+ remote = branches[0]
+ local = remote.split('/')[-1]
+ self._gitcommand(['checkout', '-b', local, remote])
+
+ def commit(self, text, user, date):
+ cmd = ['commit', '-a', '-m', text]
+ if user:
+ cmd += ['--author', user]
+ if date:
+ # git's date parser silently ignores when seconds < 1e9
+ # convert to ISO8601
+ cmd += ['--date', util.datestr(date, '%Y-%m-%dT%H:%M:%S %1%2')]
+ self._gitcommand(cmd)
+ # make sure commit works otherwise HEAD might not exist under certain
+ # circumstances
+ return self._gitstate()
+
+ def merge(self, state):
+ source, revision, kind = state
+ self._fetch(source, revision)
+ base = self._gitcommand(['merge-base', revision,
+ self._state[1]]).strip()
+ if base == revision:
+ self.get(state) # fast forward merge
+ elif base != self._state[1]:
+ self._gitcommand(['merge', '--no-commit', revision])
+
+ def push(self, force):
+ # if a branch in origin contains the revision, nothing to do
+ current, bm = self._gitbranchmap()
+ for revision, branches in bm.iteritems():
+ for b in branches:
+ if b.startswith('remotes/origin'):
+ if self._gitisancestor(self._state[1], revision):
+ return True
+ # otherwise, try to push the currently checked out branch
+ cmd = ['push']
+ if force:
+ cmd.append('--force')
+ if current:
+ # determine if the current branch is even useful
+ if not self._gitisancestor(self._state[1], current):
+ self._ui.warn(_('unrelated git branch checked out '
+ 'in subrepo %s\n') % self._relpath)
+ return False
+ self._ui.status(_('pushing branch %s of subrepo %s\n') %
+ (current, self._relpath))
+ self._gitcommand(cmd + ['origin', current, '-q'])
+ return True
+ else:
+ self._ui.warn(_('no branch checked out in subrepo %s\n'
+ 'cannot push revision %s') %
+ (self._relpath, self._state[1]))
+ return False
+
+ def remove(self):
+ if self.dirty():
+ self._ui.warn(_('not removing repo %s because '
+ 'it has changes.\n') % self._path)
+ return
+ # we can't fully delete the repository as it may contain
+ # local-only history
+ self._ui.note(_('removing subrepo %s\n') % self._path)
+ self._gitcommand(['config', 'core.bare', 'true'])
+ for f in os.listdir(self._path):
+ if f == '.git':
+ continue
+ path = os.path.join(self._path, f)
+ if os.path.isdir(path) and not os.path.islink(path):
+ shutil.rmtree(path)
+ else:
+ os.remove(path)
+
+ def archive(self, archiver, prefix):
+ source, revision = self._state
+ self._fetch(source, revision)
+
+ # Parse git's native archive command.
+ # This should be much faster than manually traversing the trees
+ # and objects with many subprocess calls.
+ tarstream = self._gitcommand(['archive', revision], stream=True)
+ tar = tarfile.open(fileobj=tarstream, mode='r|')
+ for info in tar:
+ archiver.addfile(os.path.join(prefix, self._relpath, info.name),
+ info.mode, info.issym(),
+ tar.extractfile(info).read())
+
types = {
'hg': hgsubrepo,
'svn': svnsubrepo,
+ 'git': gitsubrepo,
}
--- a/mercurial/templatekw.py Wed Dec 01 04:21:47 2010 +0100
+++ b/mercurial/templatekw.py Wed Dec 01 11:04:50 2010 +0100
@@ -148,7 +148,6 @@
def showbranches(**args):
branch = args['ctx'].branch()
if branch != 'default':
- branch = encoding.tolocal(branch)
return showlist('branch', [branch], plural='branches', **args)
def showchildren(**args):
--- a/mercurial/ui.py Wed Dec 01 04:21:47 2010 +0100
+++ b/mercurial/ui.py Wed Dec 01 11:04:50 2010 +0100
@@ -589,7 +589,7 @@
termination.
'''
- if pos == None or not self.debugflag:
+ if pos is None or not self.debugflag:
return
if unit:
--- a/mercurial/util.py Wed Dec 01 04:21:47 2010 +0100
+++ b/mercurial/util.py Wed Dec 01 11:04:50 2010 +0100
@@ -1054,7 +1054,7 @@
# NOTE: unixtime = localunixtime + offset
offset, date = timezone(string), string
- if offset != None:
+ if offset is not None:
date = " ".join(string.split()[:-1])
# add missing elements from defaults
@@ -1328,15 +1328,26 @@
#### naming convention of below implementation follows 'textwrap' module
class MBTextWrapper(textwrap.TextWrapper):
+ """
+ Extend TextWrapper for double-width characters.
+
+ Some Asian characters use two terminal columns instead of one.
+ A good example of this behavior can be seen with u'\u65e5\u672c',
+ the two Japanese characters for "Japan":
+ len() returns 2, but when printed to a terminal, they eat 4 columns.
+
+ (Note that this has nothing to do whatsoever with unicode
+ representation, or encoding of the underlying string)
+ """
def __init__(self, **kwargs):
textwrap.TextWrapper.__init__(self, **kwargs)
def _cutdown(self, str, space_left):
l = 0
ucstr = unicode(str, encoding.encoding)
- w = unicodedata.east_asian_width
+ colwidth = unicodedata.east_asian_width
for i in xrange(len(ucstr)):
- l += w(ucstr[i]) in 'WFA' and 2 or 1
+ l += colwidth(ucstr[i]) in 'WFA' and 2 or 1
if space_left < l:
return (ucstr[:i].encode(encoding.encoding),
ucstr[i:].encode(encoding.encoding))
--- a/mercurial/verify.py Wed Dec 01 04:21:47 2010 +0100
+++ b/mercurial/verify.py Wed Dec 01 11:04:50 2010 +0100
@@ -34,7 +34,7 @@
raise util.Abort(_("cannot verify bundle or remote repos"))
def err(linkrev, msg, filename=None):
- if linkrev != None:
+ if linkrev is not None:
badrevs.add(linkrev)
else:
linkrev = '?'
--- a/mercurial/wireproto.py Wed Dec 01 04:21:47 2010 +0100
+++ b/mercurial/wireproto.py Wed Dec 01 11:04:50 2010 +0100
@@ -25,7 +25,7 @@
class wirerepository(repo.repository):
def lookup(self, key):
self.requirecap('lookup', _('look up remote revision'))
- d = self._call("lookup", key=key)
+ d = self._call("lookup", key=encoding.fromlocal(key))
success, data = d[:-1].split(" ", 1)
if int(success):
return bin(data)
@@ -44,14 +44,7 @@
branchmap = {}
for branchpart in d.splitlines():
branchname, branchheads = branchpart.split(' ', 1)
- branchname = urllib.unquote(branchname)
- # Earlier servers (1.3.x) send branch names in (their) local
- # charset. The best we can do is assume it's identical to our
- # own local charset, in case it's not utf-8.
- try:
- branchname.decode('utf-8')
- except UnicodeDecodeError:
- branchname = encoding.fromlocal(branchname)
+ branchname = encoding.tolocal(urllib.unquote(branchname))
branchheads = decodelist(branchheads)
branchmap[branchname] = branchheads
return branchmap
@@ -83,17 +76,20 @@
if not self.capable('pushkey'):
return False
d = self._call("pushkey",
- namespace=namespace, key=key, old=old, new=new)
+ namespace=encoding.fromlocal(namespace),
+ key=encoding.fromlocal(key),
+ old=encoding.fromlocal(old),
+ new=encoding.fromlocal(new))
return bool(int(d))
def listkeys(self, namespace):
if not self.capable('pushkey'):
return {}
- d = self._call("listkeys", namespace=namespace)
+ d = self._call("listkeys", namespace=encoding.fromlocal(namespace))
r = {}
for l in d.splitlines():
k, v = l.split('\t')
- r[k.decode('string-escape')] = v.decode('string-escape')
+ r[encoding.tolocal(k)] = encoding.tolocal(v)
return r
def stream_out(self):
@@ -162,7 +158,7 @@
branchmap = repo.branchmap()
heads = []
for branch, nodes in branchmap.iteritems():
- branchname = urllib.quote(branch)
+ branchname = urllib.quote(encoding.fromlocal(branch))
branchnodes = encodelist(nodes)
heads.append('%s %s' % (branchname, branchnodes))
return '\n'.join(heads)
@@ -213,14 +209,14 @@
return "capabilities: %s\n" % (capabilities(repo, proto))
def listkeys(repo, proto, namespace):
- d = pushkeymod.list(repo, namespace).items()
- t = '\n'.join(['%s\t%s' % (k.encode('string-escape'),
- v.encode('string-escape')) for k, v in d])
+ d = pushkeymod.list(repo, encoding.tolocal(namespace)).items()
+ t = '\n'.join(['%s\t%s' % (encoding.fromlocal(k), encoding.fromlocal(v))
+ for k, v in d])
return t
def lookup(repo, proto, key):
try:
- r = hex(repo.lookup(key))
+ r = hex(repo.lookup(encoding.tolocal(key)))
success = 1
except Exception, inst:
r = str(inst)
@@ -228,7 +224,21 @@
return "%s %s\n" % (success, r)
def pushkey(repo, proto, namespace, key, old, new):
- r = pushkeymod.push(repo, namespace, key, old, new)
+ # compatibility with pre-1.8 clients which were accidentally
+ # sending raw binary nodes rather than utf-8-encoded hex
+ if len(new) == 20 and new.encode('string-escape') != new:
+ # looks like it could be a binary node
+ try:
+ u = new.decode('utf-8')
+ new = encoding.tolocal(new) # but cleanly decodes as UTF-8
+ except UnicodeDecodeError:
+ pass # binary, leave unmodified
+ else:
+ new = encoding.tolocal(new) # normal path
+
+ r = pushkeymod.push(repo,
+ encoding.tolocal(namespace), encoding.tolocal(key),
+ encoding.tolocal(old), new)
return '%s\n' % int(r)
def _allowstream(ui):
--- a/tests/run-tests.py Wed Dec 01 04:21:47 2010 +0100
+++ b/tests/run-tests.py Wed Dec 01 11:04:50 2010 +0100
@@ -504,7 +504,8 @@
vlog("# Running", cmd)
exitcode, output = run(cmd, options, replacements)
# do not merge output if skipped, return hghave message instead
- if exitcode == SKIPPED_STATUS:
+ # similarly, with --debug, output is None
+ if exitcode == SKIPPED_STATUS or output is None:
return exitcode, output
finally:
os.remove(name)
@@ -593,7 +594,7 @@
tochild.close()
output = fromchild.read()
ret = fromchild.close()
- if ret == None:
+ if ret is None:
ret = 0
else:
proc = Popen4(cmd)
@@ -713,7 +714,7 @@
# If we're not in --debug mode and reference output file exists,
# check test output against it.
if options.debug:
- refout = None # to match out == None
+ refout = None # to match "out is None"
elif os.path.exists(ref):
f = open(ref, "r")
refout = splitnewlines(f.read())
--- a/tests/test-check-code.t Wed Dec 01 04:21:47 2010 +0100
+++ b/tests/test-check-code.t Wed Dec 01 11:04:50 2010 +0100
@@ -52,3 +52,44 @@
> y = format(x)
any/all/format not available in Python 2.4
[1]
+
+ $ cat > is-op.py <<EOF
+ > # is-operator comparing number or string literal
+ > x = None
+ > y = x is 'foo'
+ > y = x is "foo"
+ > y = x is 5346
+ > y = x is -6
+ > y = x is not 'foo'
+ > y = x is not "foo"
+ > y = x is not 5346
+ > y = x is not -6
+ > EOF
+
+ $ "$check_code" ./is-op.py
+ ./is-op.py:3:
+ > y = x is 'foo'
+ object comparison with literal
+ ./is-op.py:4:
+ > y = x is "foo"
+ object comparison with literal
+ ./is-op.py:5:
+ > y = x is 5346
+ object comparison with literal
+ ./is-op.py:6:
+ > y = x is -6
+ object comparison with literal
+ ./is-op.py:7:
+ > y = x is not 'foo'
+ object comparison with literal
+ ./is-op.py:8:
+ > y = x is not "foo"
+ object comparison with literal
+ ./is-op.py:9:
+ > y = x is not 5346
+ object comparison with literal
+ ./is-op.py:10:
+ > y = x is not -6
+ object comparison with literal
+ [1]
+
--- a/tests/test-confused-revert.t Wed Dec 01 04:21:47 2010 +0100
+++ b/tests/test-confused-revert.t Wed Dec 01 11:04:50 2010 +0100
@@ -58,8 +58,8 @@
Revert should fail:
- $ hg revert --all
- abort: uncommitted merge - please provide a specific revision
+ $ hg revert
+ abort: uncommitted merge - use "hg update", see "hg help revert"
[255]
Revert should be ok now:
--- a/tests/test-convert.t Wed Dec 01 04:21:47 2010 +0100
+++ b/tests/test-convert.t Wed Dec 01 11:04:50 2010 +0100
@@ -40,16 +40,16 @@
have the following effects:
--branchsort convert from parent to child revision when possible, which
- means branches are usually converted one after the other. It
- generates more compact repositories.
+ means branches are usually converted one after the other.
+ It generates more compact repositories.
--datesort sort revisions by date. Converted repositories have good-
looking changelogs but are often an order of magnitude
larger than the same ones generated by --branchsort.
--sourcesort try to preserve source revisions order, only supported by
Mercurial sources.
- If <REVMAP> isn't given, it will be put in a default location
- (<dest>/.hg/shamap by default). The <REVMAP> is a simple text file that
+ If "REVMAP" isn't given, it will be put in a default location
+ ("<dest>/.hg/shamap" by default). The "REVMAP" is a simple text file that
maps each source commit ID to the destination ID for that revision, like
so:
@@ -123,16 +123,19 @@
Mercurial Source
''''''''''''''''
- --config convert.hg.ignoreerrors=False (boolean)
- ignore integrity errors when reading. Use it to fix Mercurial
- repositories with missing revlogs, by converting from and to
- Mercurial.
+ The Mercurial source recognizes the following configuration options, which
+ you can set on the command line with "--config":
- --config convert.hg.saverev=False (boolean)
- store original revision ID in changeset (forces target IDs to change)
-
- --config convert.hg.startrev=0 (hg revision identifier)
- convert start revision and its descendants
+ convert.hg.ignoreerrors
+ ignore integrity errors when reading. Use it to fix Mercurial
+ repositories with missing revlogs, by converting from and to
+ Mercurial. Default is False.
+ convert.hg.saverev
+ store original. revision ID in changeset (forces target IDs to
+ change). It takes and boolean argument and defaults to False.
+ convert.hg.startrev
+ convert start revision and its descendants. It takes a hg
+ revision identifier and defaults to 0.
CVS Source
''''''''''
@@ -140,46 +143,45 @@
CVS source will use a sandbox (i.e. a checked-out copy) from CVS to
indicate the starting point of what will be converted. Direct access to
the repository files is not needed, unless of course the repository is
- :local:. The conversion uses the top level directory in the sandbox to
+ ":local:". The conversion uses the top level directory in the sandbox to
find the CVS repository, and then uses CVS rlog commands to find files to
convert. This means that unless a filemap is given, all files under the
starting directory will be converted, and that any directory
reorganization in the CVS sandbox is ignored.
- The options shown are the defaults.
-
- --config convert.cvsps.cache=True (boolean)
- Set to False to disable remote log caching, for testing and debugging
- purposes.
-
- --config convert.cvsps.fuzz=60 (integer)
- Specify the maximum time (in seconds) that is allowed between commits
- with identical user and log message in a single changeset. When very
- large files were checked in as part of a changeset then the default
- may not be long enough.
+ The following options can be used with "--config":
- --config convert.cvsps.mergeto='{{mergetobranch ([-\w]+)}}'
- Specify a regular expression to which commit log messages are matched.
- If a match occurs, then the conversion process will insert a dummy
- revision merging the branch on which this log message occurs to the
- branch indicated in the regex.
-
- --config convert.cvsps.mergefrom='{{mergefrombranch ([-\w]+)}}'
- Specify a regular expression to which commit log messages are matched.
- If a match occurs, then the conversion process will add the most
- recent revision on the branch indicated in the regex as the second
- parent of the changeset.
-
- --config hook.cvslog
- Specify a Python function to be called at the end of gathering the CVS
- log. The function is passed a list with the log entries, and can
- modify the entries in-place, or add or delete them.
-
- --config hook.cvschangesets
- Specify a Python function to be called after the changesets are
- calculated from the the CVS log. The function is passed a list with
- the changeset entries, and can modify the changesets in-place, or add
- or delete them.
+ convert.cvsps.cache
+ Set to False to disable remote log caching, for testing and
+ debugging purposes. Default is True.
+ convert.cvsps.fuzz
+ Specify the maximum time (in seconds) that is allowed between
+ commits with identical user and log message in a single
+ changeset. When very large files were checked in as part of a
+ changeset then the default may not be long enough. The default
+ is 60.
+ convert.cvsps.mergeto
+ Specify a regular expression to which commit log messages are
+ matched. If a match occurs, then the conversion process will
+ insert a dummy revision merging the branch on which this log
+ message occurs to the branch indicated in the regex. Default
+ is "{{mergetobranch ([-\w]+)}}"
+ convert.cvsps.mergefrom
+ Specify a regular expression to which commit log messages are
+ matched. If a match occurs, then the conversion process will
+ add the most recent revision on the branch indicated in the
+ regex as the second parent of the changeset. Default is
+ "{{mergefrombranch ([-\w]+)}}"
+ hook.cvslog
+ Specify a Python function to be called at the end of gathering
+ the CVS log. The function is passed a list with the log
+ entries, and can modify the entries in-place, or add or delete
+ them.
+ hook.cvschangesets
+ Specify a Python function to be called after the changesets
+ are calculated from the the CVS log. The function is passed a
+ list with the changeset entries, and can modify the changesets
+ in-place, or add or delete them.
An additional "debugcvsps" Mercurial command allows the builtin changeset
merging code to be run without doing a conversion. Its parameters and
@@ -199,21 +201,22 @@
them to paths relative to the source URL, or leave them blank to disable
auto detection.
- --config convert.svn.branches=branches (directory name)
- specify the directory containing branches
+ The following options can be set with "--config":
- --config convert.svn.tags=tags (directory name)
- specify the directory containing tags
-
- --config convert.svn.trunk=trunk (directory name)
- specify the name of the trunk branch
+ convert.svn.branches
+ specify the directory containing branches. The defaults is
+ "branches".
+ convert.svn.tags
+ specify the directory containing tags. The default is "tags".
+ convert.svn.trunk
+ specify the name of the trunk branch The defauls is "trunk".
Source history can be retrieved starting at a specific revision, instead
of being integrally converted. Only single branch conversions are
supported.
- --config convert.svn.startrev=0 (svn revision number)
- specify start Subversion revision.
+ convert.svn.startrev
+ specify start Subversion revision number. The default is 0.
Perforce Source
'''''''''''''''
@@ -222,25 +225,27 @@
specification as source. It will convert all files in the source to a flat
Mercurial repository, ignoring labels, branches and integrations. Note
that when a depot path is given you then usually should specify a target
- directory, because otherwise the target may be named ...-hg.
+ directory, because otherwise the target may be named "...-hg".
It is possible to limit the amount of source history to be converted by
- specifying an initial Perforce revision.
+ specifying an initial Perforce revision:
- --config convert.p4.startrev=0 (perforce changelist number)
- specify initial Perforce revision.
+ convert.p4.startrev
+ specify initial Perforce revision, a Perforce changelist
+ number).
Mercurial Destination
'''''''''''''''''''''
- --config convert.hg.clonebranches=False (boolean)
- dispatch source branches in separate clones.
+ The following options are supported:
- --config convert.hg.tagsbranch=default (branch name)
- tag revisions branch name
-
- --config convert.hg.usebranchnames=True (boolean)
- preserve branch names
+ convert.hg.clonebranches
+ dispatch source branches in separate clones. The default is
+ False.
+ convert.hg.tagsbranch
+ branch name for tag revisions, defaults to "default".
+ convert.hg.usebranchnames
+ preserve branch names. The default is True
options:
--- a/tests/test-doctest.py Wed Dec 01 04:21:47 2010 +0100
+++ b/tests/test-doctest.py Wed Dec 01 11:04:50 2010 +0100
@@ -13,8 +13,8 @@
import mercurial.match
doctest.testmod(mercurial.match)
-import mercurial.url
-doctest.testmod(mercurial.url)
+import mercurial.encoding
+doctest.testmod(mercurial.encoding)
import hgext.convert.cvsps
doctest.testmod(hgext.convert.cvsps)
--- a/tests/test-encoding.t Wed Dec 01 04:21:47 2010 +0100
+++ b/tests/test-encoding.t Wed Dec 01 11:04:50 2010 +0100
@@ -240,6 +240,4 @@
abort: decoding near '\xe9': 'ascii' codec can't decode byte 0xe9 in position 0: ordinal not in range(128)! (esc)
[255]
$ cp latin-1-tag .hg/branch
- $ HGENCODING=latin-1 hg ci -m 'should fail'
- abort: branch name not in UTF-8!
- [255]
+ $ HGENCODING=latin-1 hg ci -m 'auto-promote legacy name'
--- a/tests/test-hardlinks-safety.t Wed Dec 01 04:21:47 2010 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,106 +0,0 @@
-some implementations of cp can't create hardlinks
-
- $ cat > cp.py <<EOF
- > from mercurial import util
- > import sys
- > util.copyfiles(sys.argv[1], sys.argv[2], hardlink=True)
- > EOF
-
-Test hardlinking outside hg:
-
- $ mkdir x
- $ echo foo > x/a
-
- $ python cp.py x y
- $ echo bar >> y/a
-
-No diff if hardlink:
-
- $ diff x/a y/a
-
-Test mq hardlinking:
-
- $ echo "[extensions]" >> $HGRCPATH
- $ echo "mq=" >> $HGRCPATH
-
- $ hg init a
- $ cd a
-
- $ hg qimport -n foo - << EOF
- > # HG changeset patch
- > # Date 1 0
- > diff -r 2588a8b53d66 a
- > --- /dev/null Thu Jan 01 00:00:00 1970 +0000
- > +++ b/a Wed Jul 23 15:54:29 2008 +0200
- > @@ -0,0 +1,1 @@
- > +a
- > EOF
- adding foo to series file
-
- $ hg qpush
- applying foo
- now at: foo
-
- $ cd ..
- $ python cp.py a b
- $ cd b
-
- $ hg qimport -n bar - << EOF
- > # HG changeset patch
- > # Date 2 0
- > diff -r 2588a8b53d66 a
- > --- /dev/null Thu Jan 01 00:00:00 1970 +0000
- > +++ b/b Wed Jul 23 15:54:29 2008 +0200
- > @@ -0,0 +1,1 @@
- > +b
- > EOF
- adding bar to series file
-
- $ hg qpush
- applying bar
- now at: bar
-
- $ cat .hg/patches/status
- 430ed4828a74fa4047bc816a25500f7472ab4bfe:foo
- 4e7abb4840c46a910f6d7b4d3c3fc7e5209e684c:bar
-
- $ cat .hg/patches/series
- foo
- bar
-
- $ cat ../a/.hg/patches/status
- 430ed4828a74fa4047bc816a25500f7472ab4bfe:foo
-
- $ cat ../a/.hg/patches/series
- foo
-
-Test tags hardlinking:
-
- $ hg qdel -r qbase:qtip
- patch foo finalized without changeset message
- patch bar finalized without changeset message
-
- $ hg tag -l lfoo
- $ hg tag foo
-
- $ cd ..
- $ python cp.py b c
- $ cd c
-
- $ hg tag -l -r 0 lbar
- $ hg tag -r 0 bar
-
- $ cat .hgtags
- 4e7abb4840c46a910f6d7b4d3c3fc7e5209e684c foo
- 430ed4828a74fa4047bc816a25500f7472ab4bfe bar
-
- $ cat .hg/localtags
- 4e7abb4840c46a910f6d7b4d3c3fc7e5209e684c lfoo
- 430ed4828a74fa4047bc816a25500f7472ab4bfe lbar
-
- $ cat ../b/.hgtags
- 4e7abb4840c46a910f6d7b4d3c3fc7e5209e684c foo
-
- $ cat ../b/.hg/localtags
- 4e7abb4840c46a910f6d7b4d3c3fc7e5209e684c lfoo
-
--- a/tests/test-hardlinks.t Wed Dec 01 04:21:47 2010 +0100
+++ b/tests/test-hardlinks.t Wed Dec 01 11:04:50 2010 +0100
@@ -10,6 +10,19 @@
> find $1 -type f | python $TESTTMP/nlinks.py
> }
+Some implementations of cp can't create hardlinks (replaces 'cp -al' on Linux):
+
+ $ cat > linkcp.py <<EOF
+ > from mercurial import util
+ > import sys
+ > util.copyfiles(sys.argv[1], sys.argv[2], hardlink=True)
+ > EOF
+
+ $ linkcp()
+ > {
+ > python $TESTTMP/linkcp.py $1 $2
+ > }
+
Prepare repo r1:
$ mkdir r1
@@ -152,3 +165,167 @@
1 r2/.hg/store/data/f1.i
1 r2/.hg/store/fncache
+
+ $ cd r3
+ $ hg tip --template '{rev}:{node|short}\n'
+ 11:a6451b6bc41f
+ $ echo bla > f1
+ $ hg ci -m1
+ $ cd ..
+
+Create hardlinked copy r4 of r3 (on Linux, we would call 'cp -al'):
+
+ $ linkcp r3 r4
+
+r4 has hardlinks in the working dir (not just inside .hg):
+
+ $ nlinksdir r4
+ 2 r4/.hg/00changelog.i
+ 2 r4/.hg/branch
+ 2 r4/.hg/branchheads.cache
+ 2 r4/.hg/dirstate
+ 2 r4/.hg/hgrc
+ 2 r4/.hg/last-message.txt
+ 2 r4/.hg/requires
+ 2 r4/.hg/store/00changelog.i
+ 2 r4/.hg/store/00manifest.i
+ 2 r4/.hg/store/data/d1/f2.d
+ 2 r4/.hg/store/data/d1/f2.i
+ 2 r4/.hg/store/data/f1.i
+ 2 r4/.hg/store/fncache
+ 2 r4/.hg/store/undo
+ 2 r4/.hg/tags.cache
+ 2 r4/.hg/undo.branch
+ 2 r4/.hg/undo.desc
+ 2 r4/.hg/undo.dirstate
+ 2 r4/d1/data1
+ 2 r4/d1/f2
+ 2 r4/f1
+
+Update back to revision 11 in r4 should break hardlink of file f1:
+
+ $ hg -R r4 up 11
+ 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+ $ nlinksdir r4
+ 2 r4/.hg/00changelog.i
+ 1 r4/.hg/branch
+ 2 r4/.hg/branchheads.cache
+ 1 r4/.hg/dirstate
+ 2 r4/.hg/hgrc
+ 2 r4/.hg/last-message.txt
+ 2 r4/.hg/requires
+ 2 r4/.hg/store/00changelog.i
+ 2 r4/.hg/store/00manifest.i
+ 2 r4/.hg/store/data/d1/f2.d
+ 2 r4/.hg/store/data/d1/f2.i
+ 2 r4/.hg/store/data/f1.i
+ 2 r4/.hg/store/fncache
+ 2 r4/.hg/store/undo
+ 2 r4/.hg/tags.cache
+ 2 r4/.hg/undo.branch
+ 2 r4/.hg/undo.desc
+ 2 r4/.hg/undo.dirstate
+ 2 r4/d1/data1
+ 2 r4/d1/f2
+ 1 r4/f1
+
+
+Test hardlinking outside hg:
+
+ $ mkdir x
+ $ echo foo > x/a
+
+ $ linkcp x y
+ $ echo bar >> y/a
+
+No diff if hardlink:
+
+ $ diff x/a y/a
+
+Test mq hardlinking:
+
+ $ echo "[extensions]" >> $HGRCPATH
+ $ echo "mq=" >> $HGRCPATH
+
+ $ hg init a
+ $ cd a
+
+ $ hg qimport -n foo - << EOF
+ > # HG changeset patch
+ > # Date 1 0
+ > diff -r 2588a8b53d66 a
+ > --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+ > +++ b/a Wed Jul 23 15:54:29 2008 +0200
+ > @@ -0,0 +1,1 @@
+ > +a
+ > EOF
+ adding foo to series file
+
+ $ hg qpush
+ applying foo
+ now at: foo
+
+ $ cd ..
+ $ linkcp a b
+ $ cd b
+
+ $ hg qimport -n bar - << EOF
+ > # HG changeset patch
+ > # Date 2 0
+ > diff -r 2588a8b53d66 a
+ > --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+ > +++ b/b Wed Jul 23 15:54:29 2008 +0200
+ > @@ -0,0 +1,1 @@
+ > +b
+ > EOF
+ adding bar to series file
+
+ $ hg qpush
+ applying bar
+ now at: bar
+
+ $ cat .hg/patches/status
+ 430ed4828a74fa4047bc816a25500f7472ab4bfe:foo
+ 4e7abb4840c46a910f6d7b4d3c3fc7e5209e684c:bar
+
+ $ cat .hg/patches/series
+ foo
+ bar
+
+ $ cat ../a/.hg/patches/status
+ 430ed4828a74fa4047bc816a25500f7472ab4bfe:foo
+
+ $ cat ../a/.hg/patches/series
+ foo
+
+Test tags hardlinking:
+
+ $ hg qdel -r qbase:qtip
+ patch foo finalized without changeset message
+ patch bar finalized without changeset message
+
+ $ hg tag -l lfoo
+ $ hg tag foo
+
+ $ cd ..
+ $ linkcp b c
+ $ cd c
+
+ $ hg tag -l -r 0 lbar
+ $ hg tag -r 0 bar
+
+ $ cat .hgtags
+ 4e7abb4840c46a910f6d7b4d3c3fc7e5209e684c foo
+ 430ed4828a74fa4047bc816a25500f7472ab4bfe bar
+
+ $ cat .hg/localtags
+ 4e7abb4840c46a910f6d7b4d3c3fc7e5209e684c lfoo
+ 430ed4828a74fa4047bc816a25500f7472ab4bfe lbar
+
+ $ cat ../b/.hgtags
+ 4e7abb4840c46a910f6d7b4d3c3fc7e5209e684c foo
+
+ $ cat ../b/.hg/localtags
+ 4e7abb4840c46a910f6d7b4d3c3fc7e5209e684c lfoo
+
--- a/tests/test-import.t Wed Dec 01 04:21:47 2010 +0100
+++ b/tests/test-import.t Wed Dec 01 11:04:50 2010 +0100
@@ -437,6 +437,13 @@
$ hg revert -a
reverting a
+
+import with --no-commit should have written .hg/last-message.txt
+
+ $ cat .hg/last-message.txt
+ change (no-eol)
+
+
test fuzziness with eol=auto
$ hg --config patch.eol=auto import --no-commit -v tip.patch
--- a/tests/test-minirst.py Wed Dec 01 04:21:47 2010 +0100
+++ b/tests/test-minirst.py Wed Dec 01 11:04:50 2010 +0100
@@ -120,16 +120,19 @@
There is support for simple option lists,
but only with long options:
---all Output all.
---both Output both (this description is
- quite long).
---long Output all day long.
+-X, --exclude filter an option with a short and long option with an argument
+-I, --include an option with both a short option and a long option
+--all Output all.
+--both Output both (this description is
+ quite long).
+--long Output all day long.
---par This option has two paragraphs in its description.
- This is the first.
+--par This option has two paragraphs in its description.
+ This is the first.
- This is the second. Blank lines may be omitted between
- options (as above) or left in (as here).
+ This is the second. Blank lines may be omitted between
+ options (as above) or left in (as here).
+
The next paragraph looks like an option list, but lacks the two-space
marker after the option. It is treated as a normal paragraph:
@@ -221,6 +224,10 @@
.. An indented comment
Some indented text.
+
+..
+
+Empty comment above
"""
debugformat('comments', comments, 30)
--- a/tests/test-minirst.py.out Wed Dec 01 04:21:47 2010 +0100
+++ b/tests/test-minirst.py.out Wed Dec 01 11:04:50 2010 +0100
@@ -180,14 +180,20 @@
There is support for simple option lists, but only with long
options:
---all Output all.
---both Output both (this description is quite long).
---long Output all day long.
---par This option has two paragraphs in its
- description. This is the first.
+ -X --exclude filter an option with a short and long option
+ with an argument
+ -I --include an option with both a short option and
+ a long option
+ --all Output all.
+ --both Output both (this description is quite
+ long).
+ --long Output all day long.
+ --par This option has two paragraphs in its
+ description. This is the first.
- This is the second. Blank lines may be omitted
- between options (as above) or left in (as here).
+ This is the second. Blank lines may
+ be omitted between options (as above)
+ or left in (as here).
The next paragraph looks like an option list, but lacks the
two-space marker after the option. It is treated as a normal
@@ -202,23 +208,62 @@
option lists, but only with
long options:
---all Output all.
---both Output both (this
- description is
- quite long).
---long Output all day
- long.
---par This option has two
- paragraphs in its
- description. This
- is the first.
+ -X --exclude filter an
+ option
+ with a
+ short
+ and
+ long
+ option
+ with an
+ argumen
+ t
+ -I --include an
+ option
+ with
+ both a
+ short
+ option
+ and a
+ long
+ option
+ --all Output
+ all.
+ --both Output
+ both
+ (this d
+ escript
+ ion is
+ quite
+ long).
+ --long Output
+ all day
+ long.
+ --par This
+ option
+ has two
+ paragra
+ phs in
+ its des
+ criptio
+ n. This
+ is the
+ first.
- This is the second.
- Blank lines may be
- omitted between
- options (as above)
- or left in (as
- here).
+ This is
+ the
+ second.
+ Blank
+ lines
+ may be
+ omitted
+ between
+ options
+ (as
+ above)
+ or left
+ in (as
+ here).
The next paragraph looks like
an option list, but lacks the
@@ -339,5 +384,7 @@
Some text.
Some indented text.
+
+Empty comment above
----------------------------------------------------------------------
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-mq-qpush-exact.t Wed Dec 01 11:04:50 2010 +0100
@@ -0,0 +1,290 @@
+ $ echo "[extensions]" >> $HGRCPATH
+ $ echo "mq=" >> $HGRCPATH
+ $ echo "graphlog=" >> $HGRCPATH
+
+make a test repository that looks like this:
+
+o 2:28bc7b1afd6a
+|
+| @ 1:d7fe2034f71b
+|/
+o 0/62ecad8b70e5
+
+ $ hg init r0
+ $ cd r0
+ $ touch f0
+ $ hg ci -m0 -Aq
+ $ touch f1
+ $ hg ci -m1 -Aq
+
+ $ hg update 0 -q
+ $ touch f2
+ $ hg ci -m2 -Aq
+ $ hg update 1 -q
+
+make some patches with a parent: 1:d7fe2034f71b -> p0 -> p1
+
+ $ echo cp0 >> fp0
+ $ hg add fp0
+ $ hg qnew p0 -d "0 0"
+
+ $ echo cp1 >> fp1
+ $ hg add fp1
+ $ hg qnew p1 -d "0 0"
+
+ $ hg qpop -aq
+ patch queue now empty
+
+qpush --exact when at the parent
+
+ $ hg update 1 -q
+ $ hg qpush -e
+ applying p0
+ now at: p0
+ $ hg parents -qr qbase
+ 1:d7fe2034f71b
+ $ hg qpop -aq
+ patch queue now empty
+
+ $ hg qpush -e p0
+ applying p0
+ now at: p0
+ $ hg parents -qr qbase
+ 1:d7fe2034f71b
+ $ hg qpop -aq
+ patch queue now empty
+
+ $ hg qpush -e p1
+ applying p0
+ applying p1
+ now at: p1
+ $ hg parents -qr qbase
+ 1:d7fe2034f71b
+ $ hg qpop -aq
+ patch queue now empty
+
+ $ hg qpush -ea
+ applying p0
+ applying p1
+ now at: p1
+ $ hg parents -qr qbase
+ 1:d7fe2034f71b
+ $ hg qpop -aq
+ patch queue now empty
+
+qpush --exact when at another rev
+
+ $ hg update 0 -q
+ $ hg qpush -e
+ 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ applying p0
+ now at: p0
+ $ hg parents -qr qbase
+ 1:d7fe2034f71b
+ $ hg qpop -aq
+ patch queue now empty
+
+ $ hg update 0 -q
+ $ hg qpush -e p0
+ 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ applying p0
+ now at: p0
+ $ hg parents -qr qbase
+ 1:d7fe2034f71b
+ $ hg qpop -aq
+ patch queue now empty
+
+ $ hg update 0 -q
+ $ hg qpush -e p1
+ 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ applying p0
+ applying p1
+ now at: p1
+ $ hg parents -qr qbase
+ 1:d7fe2034f71b
+ $ hg qpop -aq
+ patch queue now empty
+
+ $ hg update 0 -q
+ $ hg qpush -ea
+ 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ applying p0
+ applying p1
+ now at: p1
+ $ hg parents -qr qbase
+ 1:d7fe2034f71b
+ $ hg qpop -aq
+ patch queue now empty
+
+qpush --exact while crossing branches
+
+ $ hg update 2 -q
+ $ hg qpush -e
+ 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+ applying p0
+ now at: p0
+ $ hg parents -qr qbase
+ 1:d7fe2034f71b
+ $ hg qpop -aq
+ patch queue now empty
+
+ $ hg update 2 -q
+ $ hg qpush -e p0
+ 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+ applying p0
+ now at: p0
+ $ hg parents -qr qbase
+ 1:d7fe2034f71b
+ $ hg qpop -aq
+ patch queue now empty
+
+ $ hg update 2 -q
+ $ hg qpush -e p1
+ 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+ applying p0
+ applying p1
+ now at: p1
+ $ hg parents -qr qbase
+ 1:d7fe2034f71b
+ $ hg qpop -aq
+ patch queue now empty
+
+ $ hg update 2 -q
+ $ hg qpush -ea
+ 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+ applying p0
+ applying p1
+ now at: p1
+ $ hg parents -qr qbase
+ 1:d7fe2034f71b
+ $ hg qpop -aq
+ patch queue now empty
+
+qpush --exact --force with changes to an unpatched file
+
+ $ hg update 1 -q
+ $ echo c0 >> f0
+ $ hg qpush -e
+ abort: local changes found, refresh first
+ [255]
+ $ hg qpush -ef
+ applying p0
+ now at: p0
+ $ cat f0
+ c0
+ $ rm f0
+ $ touch f0
+ $ hg qpop -aq
+ patch queue now empty
+
+ $ hg update 1 -q
+ $ echo c0 >> f0
+ $ hg qpush -e p1
+ abort: local changes found, refresh first
+ [255]
+ $ hg qpush -e p1 -f
+ applying p0
+ applying p1
+ now at: p1
+ $ cat f0
+ c0
+ $ rm f0
+ $ touch f0
+ $ hg qpop -aq
+ patch queue now empty
+
+qpush --exact --force with changes to a patched file
+
+ $ hg update 1 -q
+ $ echo cp0-bad >> fp0
+ $ hg add fp0
+ $ hg qpush -e
+ abort: local changes found, refresh first
+ [255]
+ $ hg qpush -ef
+ applying p0
+ file fp0 already exists
+ 1 out of 1 hunks FAILED -- saving rejects to file fp0.rej
+ patch failed, unable to continue (try -v)
+ patch failed, rejects left in working dir
+ errors during apply, please fix and refresh p0
+ [2]
+ $ cat fp0
+ cp0-bad
+ $ cat fp0.rej
+ --- fp0
+ +++ fp0
+ @@ -0,0 +1,1 @@
+ +cp0
+ $ hg qpop -aqf
+ patch queue now empty
+ $ rm fp0
+ $ rm fp0.rej
+
+ $ hg update 1 -q
+ $ echo cp1-bad >> fp1
+ $ hg add fp1
+ $ hg qpush -e p1
+ abort: local changes found, refresh first
+ [255]
+ $ hg qpush -e p1 -f
+ applying p0
+ applying p1
+ file fp1 already exists
+ 1 out of 1 hunks FAILED -- saving rejects to file fp1.rej
+ patch failed, unable to continue (try -v)
+ patch failed, rejects left in working dir
+ errors during apply, please fix and refresh p1
+ [2]
+ $ cat fp1
+ cp1-bad
+ $ cat fp1.rej
+ --- fp1
+ +++ fp1
+ @@ -0,0 +1,1 @@
+ +cp1
+ $ hg qpop -aqf
+ patch queue now empty
+ $ rm fp1
+ $ rm fp1.rej
+
+qpush --exact when already at a patch
+
+ $ hg update 1
+ 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ $ hg qpush -e p0
+ applying p0
+ now at: p0
+ $ hg qpush -e p1
+ abort: cannot push --exact with applied patches
+ [255]
+ $ hg qpop -aq
+ patch queue now empty
+
+qpush --exact --move should fail
+
+ $ hg qpush -e --move p1
+ abort: cannot use --exact and --move together
+ [255]
+
+qpush --exact a patch without a parent recorded
+
+ $ hg qpush -q
+ now at: p0
+ $ grep -v '# Parent' .hg/patches/p0 > p0.new
+ $ mv p0.new .hg/patches/p0
+ $ hg qpop -aq
+ patch queue now empty
+ $ hg qpush -e
+ abort: p0 does not have a parent recorded
+ [255]
+ $ hg qpush -e p0
+ abort: p0 does not have a parent recorded
+ [255]
+ $ hg qpush -e p1
+ abort: p0 does not have a parent recorded
+ [255]
+ $ hg qpush -ea
+ abort: p0 does not have a parent recorded
+ [255]
+
--- a/tests/test-no-symlinks Wed Dec 01 04:21:47 2010 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,47 +0,0 @@
-#!/bin/sh
-
-"$TESTDIR/hghave" no-symlink || exit 80
-
-# The following script was used to create the bundle:
-#
-# hg init symlinks
-# cd symlinks
-# echo a > a
-# mkdir d
-# echo b > d/b
-# ln -s a a.lnk
-# ln -s d/b d/b.lnk
-# hg ci -Am t
-# hg bundle --base null ../test-no-symlinks.hg
-
-# Extract a symlink on a platform not supporting them
-echo % unbundle
-hg init t
-cd t
-hg pull -q "$TESTDIR/test-no-symlinks.hg"
-hg update
-
-cat a.lnk && echo
-cat d/b.lnk && echo
-
-# Copy a symlink and move another
-echo % move and copy
-hg copy a.lnk d/a2.lnk
-hg mv d/b.lnk b2.lnk
-hg ci -Am copy
-cat d/a2.lnk && echo
-cat b2.lnk && echo
-
-# Bundle and extract again
-echo % bundle
-hg bundle --base null ../symlinks.hg
-cd ..
-
-hg init t2
-cd t2
-hg pull ../symlinks.hg
-hg update
-
-cat a.lnk && echo
-cat d/a2.lnk && echo
-cat b2.lnk && echo
--- a/tests/test-no-symlinks.out Wed Dec 01 04:21:47 2010 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,20 +0,0 @@
-% unbundle
-4 files updated, 0 files merged, 0 files removed, 0 files unresolved
-a
-d/b
-% move and copy
-a
-d/b
-% bundle
-2 changesets found
-pulling from ../symlinks.hg
-requesting all changes
-adding changesets
-adding manifests
-adding file changes
-added 2 changesets with 6 changes to 6 files
-(run 'hg update' to get a working copy)
-5 files updated, 0 files merged, 0 files removed, 0 files unresolved
-a
-a
-d/b
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-no-symlinks.t Wed Dec 01 11:04:50 2010 +0100
@@ -0,0 +1,59 @@
+ $ "$TESTDIR/hghave" no-symlink || exit 80
+
+# The following script was used to create the bundle:
+#
+# hg init symlinks
+# cd symlinks
+# echo a > a
+# mkdir d
+# echo b > d/b
+# ln -s a a.lnk
+# ln -s d/b d/b.lnk
+# hg ci -Am t
+# hg bundle --base null ../test-no-symlinks.hg
+
+Extract a symlink on a platform not supporting them
+
+ $ hg init t
+ $ cd t
+ $ hg pull -q "$TESTDIR/test-no-symlinks.hg"
+ $ hg update
+ 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ $ cat a.lnk && echo
+ a
+ $ cat d/b.lnk && echo
+ d/b
+
+Copy a symlink and move another
+
+ $ hg copy a.lnk d/a2.lnk
+ $ hg mv d/b.lnk b2.lnk
+ $ hg ci -Am copy
+ $ cat d/a2.lnk && echo
+ a
+ $ cat b2.lnk && echo
+ d/b
+
+Bundle and extract again
+
+ $ hg bundle --base null ../symlinks.hg
+ 2 changesets found
+ $ cd ..
+ $ hg init t2
+ $ cd t2
+ $ hg pull ../symlinks.hg
+ pulling from ../symlinks.hg
+ requesting all changes
+ adding changesets
+ adding manifests
+ adding file changes
+ added 2 changesets with 6 changes to 6 files
+ (run 'hg update' to get a working copy)
+ $ hg update
+ 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ $ cat a.lnk && echo
+ a
+ $ cat d/a2.lnk && echo
+ a
+ $ cat b2.lnk && echo
+ d/b
--- a/tests/test-parentrevspec.t Wed Dec 01 04:21:47 2010 +0100
+++ b/tests/test-parentrevspec.t Wed Dec 01 11:04:50 2010 +0100
@@ -69,12 +69,12 @@
6^^^^^: 0
6^^^^^^: -1
6^1: 5
- 6^2: abort: unknown revision '6^2'!
+ 6^2: hg: parse error at 1: syntax error
6^^2: 4
6^1^2: 4
- 6^^3: abort: unknown revision '6^^3'!
+ 6^^3: hg: parse error at 1: syntax error
$ lookup "6~" "6~1" "6~2" "6~3" "6~4" "6~5" "6~42" "6~1^2" "6~1^2~2"
- 6~: abort: unknown revision '6~'!
+ 6~: hg: parse error at 1: syntax error
6~1: 5
6~2: 3
6~3: 2
@@ -102,4 +102,4 @@
$ hg tag -l -r 2 "foo^bar"
$ lookup "foo^bar" "foo^bar^"
foo^bar: 2
- foo^bar^: abort: unknown revision 'foo^bar^'!
+ foo^bar^: hg: parse error at 3: syntax error
--- a/tests/test-push-warn.t Wed Dec 01 04:21:47 2010 +0100
+++ b/tests/test-push-warn.t Wed Dec 01 11:04:50 2010 +0100
@@ -30,6 +30,23 @@
(you should pull and merge or use push -f to force)
[255]
+ $ hg push --debug ../a
+ pushing to ../a
+ searching for changes
+ examining 1c9246a22a0a:d8d565842d04
+ found incomplete branch 1c9246a22a0a:d8d565842d04
+ searching: 1 queries
+ narrowing 1:1 d8d565842d04
+ found new branch changeset 1c9246a22a0a
+ found new changesets starting at 1c9246a22a0a
+ 1 total queries
+ common changesets up to d8d565842d04
+ new remote heads on branch 'default'
+ new remote head 1e108cc5548c
+ abort: push creates new remote heads on branch 'default'!
+ (you should pull and merge or use push -f to force)
+ [255]
+
$ hg pull ../a
pulling from ../a
searching for changes
--- a/tests/test-record.t Wed Dec 01 04:21:47 2010 +0100
+++ b/tests/test-record.t Wed Dec 01 11:04:50 2010 +0100
@@ -883,7 +883,7 @@
(branch merge, don't forget to commit)
$ hg record -m'will abort'
- abort: cannot partially commit a merge (use hg commit instead)
+ abort: cannot partially commit a merge (use "hg commit" instead)
[255]
$ hg up -C
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-revset-dirstate-parents.t Wed Dec 01 11:04:50 2010 +0100
@@ -0,0 +1,52 @@
+ $ HGENCODING=utf-8
+ $ export HGENCODING
+
+ $ try() {
+ > hg debugrevspec --debug $@
+ > }
+
+ $ log() {
+ > hg log --template '{rev}\n' -r "$1"
+ > }
+
+ $ hg init repo
+ $ cd repo
+
+ $ try 'p1()'
+ ('func', ('symbol', 'p1'), None)
+ $ try 'p2()'
+ ('func', ('symbol', 'p2'), None)
+ $ try 'parents()'
+ ('func', ('symbol', 'parents'), None)
+
+null revision
+ $ log 'p1()'
+ $ log 'p2()'
+ $ log 'parents()'
+
+working dir with a single parent
+ $ echo a > a
+ $ hg ci -Aqm0
+ $ log 'p1()'
+ 0
+ $ log 'tag() and p1()'
+ $ log 'p2()'
+ $ log 'parents()'
+ 0
+ $ log 'tag() and parents()'
+
+merge in progress
+ $ echo b > b
+ $ hg ci -Aqm1
+ $ hg up -q 0
+ $ echo c > c
+ $ hg ci -Aqm2
+ $ hg merge -q
+ $ log 'p1()'
+ 2
+ $ log 'p2()'
+ 1
+ $ log 'tag() and p2()'
+ $ log 'parents()'
+ 1
+ 2
--- a/tests/test-ssh.t Wed Dec 01 04:21:47 2010 +0100
+++ b/tests/test-ssh.t Wed Dec 01 11:04:50 2010 +0100
@@ -214,7 +214,7 @@
$ hg debugpushkey --config ui.ssh="python ../dummyssh" ssh://user@dummy/remote bookmarks
foo 1160648e36cec0054048a7edc4110c6f84fde594
$ hg book -f foo
- $ hg push
+ $ hg push --traceback
pushing to ssh://user@dummy/remote
searching for changes
no changes found
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-subrepo-git.t Wed Dec 01 11:04:50 2010 +0100
@@ -0,0 +1,242 @@
+ $ "$TESTDIR/hghave" git || exit 80
+
+make git commits repeatable
+
+ $ GIT_AUTHOR_NAME='test'; export GIT_AUTHOR_NAME
+ $ GIT_AUTHOR_EMAIL='test@example.org'; export GIT_AUTHOR_EMAIL
+ $ GIT_AUTHOR_DATE='1234567891 +0000'; export GIT_AUTHOR_DATE
+ $ GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"; export GIT_COMMITTER_NAME
+ $ GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"; export GIT_COMMITTER_EMAIL
+ $ GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"; export GIT_COMMITTER_DATE
+
+root hg repo
+
+ $ hg init t
+ $ cd t
+ $ echo a > a
+ $ hg add a
+ $ hg commit -m a
+ $ cd ..
+
+new external git repo
+
+ $ mkdir gitroot
+ $ cd gitroot
+ $ git init -q
+ $ echo g > g
+ $ git add g
+ $ git commit -q -m g
+
+add subrepo clone
+
+ $ cd ../t
+ $ echo 's = [git]../gitroot' > .hgsub
+ $ git clone -q ../gitroot s
+ $ hg add .hgsub
+ $ hg commit -m 'new git subrepo'
+ committing subrepository $TESTTMP/t/s
+ $ hg debugsub
+ path s
+ source ../gitroot
+ revision da5f5b1d8ffcf62fb8327bcd3c89a4367a6018e7
+
+record a new commit from upstream from a different branch
+
+ $ cd ../gitroot
+ $ git checkout -b testing
+ Switched to a new branch 'testing'
+ $ echo gg >> g
+ $ git commit -q -a -m gg
+
+ $ cd ../t/s
+ $ git pull -q
+ $ git checkout -b testing origin/testing
+ Switched to a new branch 'testing'
+ Branch testing set up to track remote branch testing from origin.
+
+ $ cd ..
+ $ hg commit -m 'update git subrepo'
+ committing subrepository $TESTTMP/t/s
+ $ hg debugsub
+ path s
+ source ../gitroot
+ revision 126f2a14290cd5ce061fdedc430170e8d39e1c5a
+
+clone root
+
+ $ hg clone . ../tc
+ updating to branch default
+ cloning subrepo s
+ 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ $ cd ../tc
+ $ hg debugsub
+ path s
+ source ../gitroot
+ revision 126f2a14290cd5ce061fdedc430170e8d39e1c5a
+
+update to previous substate
+
+ $ hg update 1
+ Switched to a new branch 'master'
+ 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ $ cat s/g
+ g
+ $ hg debugsub
+ path s
+ source ../gitroot
+ revision da5f5b1d8ffcf62fb8327bcd3c89a4367a6018e7
+
+make $GITROOT pushable, by replacing it with a clone with nothing checked out
+
+ $ cd ..
+ $ git clone gitroot gitrootbare --bare -q
+ $ rm -rf gitroot
+ $ mv gitrootbare gitroot
+
+clone root, make local change
+
+ $ cd t
+ $ hg clone . ../ta
+ updating to branch default
+ cloning subrepo s
+ 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+ $ cd ../ta
+ $ echo ggg >> s/g
+ $ hg commit -m ggg
+ committing subrepository $TESTTMP/ta/s
+ $ hg debugsub
+ path s
+ source ../gitroot
+ revision 79695940086840c99328513acbe35f90fcd55e57
+
+clone root separately, make different local change
+
+ $ cd ../t
+ $ hg clone . ../tb
+ updating to branch default
+ cloning subrepo s
+ 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+ $ cd ../tb/s
+ $ echo f > f
+ $ git add f
+ $ cd ..
+
+ $ hg commit -m f
+ committing subrepository $TESTTMP/tb/s
+ $ hg debugsub
+ path s
+ source ../gitroot
+ revision aa84837ccfbdfedcdcdeeedc309d73e6eb069edc
+
+user b push changes
+
+ $ hg push
+ pushing to $TESTTMP/t
+ pushing branch testing of subrepo s
+ searching for changes
+ adding changesets
+ adding manifests
+ adding file changes
+ added 1 changesets with 1 changes to 1 files
+
+user a pulls, merges, commits
+
+ $ cd ../ta
+ $ hg pull
+ pulling from $TESTTMP/t
+ searching for changes
+ adding changesets
+ adding manifests
+ adding file changes
+ added 1 changesets with 1 changes to 1 files (+1 heads)
+ (run 'hg heads' to see heads, 'hg merge' to merge)
+ $ hg merge
+ Automatic merge went well; stopped before committing as requested
+ pulling subrepo s
+ 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ (branch merge, don't forget to commit)
+ $ cat s/f
+ f
+ $ cat s/g
+ g
+ gg
+ ggg
+ $ hg commit -m 'merge'
+ committing subrepository $TESTTMP/ta/s
+ $ hg debugsub
+ path s
+ source ../gitroot
+ revision f47b465e1bce645dbf37232a00574aa1546ca8d3
+ $ hg push
+ pushing to $TESTTMP/t
+ pushing branch testing of subrepo s
+ searching for changes
+ adding changesets
+ adding manifests
+ adding file changes
+ added 2 changesets with 2 changes to 1 files
+
+make upstream git changes
+
+ $ cd ..
+ $ git clone -q gitroot gitclone
+ $ cd gitclone
+ $ echo ff >> f
+ $ git commit -q -a -m ff
+ $ echo fff >> f
+ $ git commit -q -a -m fff
+ $ git push -q origin testing
+
+make and push changes to hg without updating the subrepo
+
+ $ cd ../t
+ $ hg clone . ../td
+ updating to branch default
+ cloning subrepo s
+ checking out detached HEAD in subrepo s
+ check out a git branch if you intend to make changes
+ 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ $ cd ../td
+ $ echo aa >> a
+ $ hg commit -m aa
+ $ hg push
+ pushing to $TESTTMP/t
+ searching for changes
+ adding changesets
+ adding manifests
+ adding file changes
+ added 1 changesets with 1 changes to 1 files
+
+update to a revision without the subrepo, keeping the local git repository
+
+ $ cd ../t
+ $ hg up 0
+ 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
+ $ ls -a s
+ .
+ ..
+ .git
+
+ $ hg up 2
+ 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ $ ls -a s
+ .
+ ..
+ .git
+ g
+
+archive subrepos
+
+ $ cd ../t
+ $ hg archive --subrepos -r tip ../archive
+ pulling subrepo s
+ $ cd ../archive
+ $ cat s/f
+ f
+ $ cat s/g
+ g
+ gg
+ ggg
+
--- a/tests/test-win32text.t Wed Dec 01 04:21:47 2010 +0100
+++ b/tests/test-win32text.t Wed Dec 01 11:04:50 2010 +0100
@@ -9,10 +9,6 @@
> data = data.replace('\n', '\r\n')
> file(path, 'wb').write(data)
> EOF
- $ cat > print.py <<EOF
- > import sys
- > print(sys.stdin.read().replace('\n', '<LF>').replace('\r', '<CR>').replace('\0', '<NUL>'))
- > EOF
$ echo '[hooks]' >> .hg/hgrc
$ echo 'pretxncommit.crlf = python:hgext.win32text.forbidcrlf' >> .hg/hgrc
$ echo 'pretxnchangegroup.crlf = python:hgext.win32text.forbidcrlf' >> .hg/hgrc
@@ -369,12 +365,13 @@
$ python -c 'file("f4.bat", "wb").write("rem empty\x0D\x0A")'
$ hg add f3 f4.bat
$ hg ci -m 6
- $ python print.py < bin
- hello<NUL><CR><LF>
- $ python print.py < f3
- some<LF>text<LF>
- $ python print.py < f4.bat
- rem empty<CR><LF>
+ $ cat bin
+ hello\x00\r (esc)
+ $ cat f3
+ some
+ text
+ $ cat f4.bat
+ rem empty\r (esc)
$ echo
$ echo '[extensions]' >> .hg/hgrc
@@ -405,38 +402,39 @@
tip
$ rm f3 f4.bat bin
- $ hg co -C 2>&1 | python -c 'import sys, os; sys.stdout.write(sys.stdin.read().replace(os.getcwd(), "...."))'
+ $ hg co -C
WARNING: f4.bat already has CRLF line endings
and does not need EOL conversion by the win32text plugin.
Before your next commit, please reconsider your encode/decode settings in
- Mercurial.ini or ..../.hg/hgrc.
+ Mercurial.ini or $TESTTMP/t/.hg/hgrc.
3 files updated, 0 files merged, 0 files removed, 0 files unresolved
- $ python print.py < bin
- hello<NUL><CR><LF>
- $ python print.py < f3
- some<CR><LF>text<CR><LF>
- $ python print.py < f4.bat
- rem empty<CR><LF>
+ $ cat bin
+ hello\x00\r (esc)
+ $ cat f3
+ some\r (esc)
+ text\r (esc)
+ $ cat f4.bat
+ rem empty\r (esc)
$ echo
$ python -c 'file("f5.sh", "wb").write("# empty\x0D\x0A")'
$ hg add f5.sh
$ hg ci -m 7
- $ python print.py < f5.sh
- # empty<CR><LF>
- $ hg cat f5.sh | python print.py
- # empty<LF>
+ $ cat f5.sh
+ # empty\r (esc)
+ $ hg cat f5.sh
+ # empty
$ echo '% just linefeed' > linefeed
$ hg ci -qAm 8 linefeed
- $ python print.py < linefeed
- % just linefeed<LF>
- $ hg cat linefeed | python print.py
- % just linefeed<LF>
+ $ cat linefeed
+ % just linefeed
+ $ hg cat linefeed
+ % just linefeed
$ hg st -q
$ hg revert -a linefeed
no changes needed to linefeed
- $ python print.py < linefeed
- % just linefeed<LF>
+ $ cat linefeed
+ % just linefeed
$ hg st -q
$ echo modified >> linefeed
$ hg st -q
@@ -444,5 +442,5 @@
$ hg revert -a
reverting linefeed
$ hg st -q
- $ python print.py < linefeed
- % just linefeed<CR><LF>
+ $ cat linefeed
+ % just linefeed\r (esc)