Mercurial > hg
changeset 15376:b26315ae7f18 stable
merge in another fix on the wrong branch
author | Matt Mackall <mpm@selenic.com> |
---|---|
date | Thu, 27 Oct 2011 18:35:07 -0500 |
parents | fe9d36a6853e (diff) 872f06c342ff (current diff) |
children | 107ff02b134d |
files | |
diffstat | 100 files changed, 4754 insertions(+), 2114 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgsigs Wed Oct 26 22:35:15 2011 +0200 +++ b/.hgsigs Thu Oct 27 18:35:07 2011 -0500 @@ -43,3 +43,4 @@ 4a43e23b8c55b4566b8200bf69fe2158485a2634 0 iD8DBQBONzIMywK+sNU5EO8RAj5SAJ0aPS3+JHnyI6bHB2Fl0LImbDmagwCdGbDLp1S7TFobxXudOH49bX45Iik= d629f1e89021103f1753addcef6b310e4435b184 0 iD8DBQBOWAsBywK+sNU5EO8RAht4AJwJl9oNFopuGkj5m8aKuf7bqPkoAQCeNrEm7UhFsZKYT5iUOjnMV7s2LaM= 351a9292e430e35766c552066ed3e87c557b803b 0 iD8DBQBOh3zUywK+sNU5EO8RApFMAKCD3Y/u3avDFndznwqfG5UeTHMlvACfUivPIVQZyDZnhZMq0UhC6zhCEQg= +384082750f2c51dc917d85a7145748330fa6ef4d 0 iD8DBQBOmd+OywK+sNU5EO8RAgDgAJ9V/X+G7VLwhTpHrZNiOHabzSyzYQCdE2kKfIevJUYB9QLAWCWP6DPwrwI=
--- a/.hgtags Wed Oct 26 22:35:15 2011 +0200 +++ b/.hgtags Thu Oct 27 18:35:07 2011 -0500 @@ -55,3 +55,4 @@ 4a43e23b8c55b4566b8200bf69fe2158485a2634 1.9.1 d629f1e89021103f1753addcef6b310e4435b184 1.9.2 351a9292e430e35766c552066ed3e87c557b803b 1.9.3 +384082750f2c51dc917d85a7145748330fa6ef4d 2.0-rc
--- a/contrib/check-code.py Wed Oct 26 22:35:15 2011 +0200 +++ b/contrib/check-code.py Thu Oct 27 18:35:07 2011 -0500 @@ -13,7 +13,7 @@ def repquote(m): t = re.sub(r"\w", "x", m.group('text')) - t = re.sub(r"[^\sx]", "o", t) + t = re.sub(r"[^\s\nx]", "o", t) return m.group('quote') + t + m.group('quote') def reppython(m): @@ -44,13 +44,13 @@ testpats = [ [ (r'(pushd|popd)', "don't use 'pushd' or 'popd', use 'cd'"), - (r'\W\$?\(\([^\)]*\)\)', "don't use (()) or $(()), use 'expr'"), + (r'\W\$?\(\([^\)\n]*\)\)', "don't use (()) or $(()), use 'expr'"), (r'^function', "don't use 'function', use old style"), (r'grep.*-q', "don't use 'grep -q', redirect to /dev/null"), (r'echo.*\\n', "don't use 'echo \\n', use printf"), (r'echo -n', "don't use 'echo -n', use printf"), (r'^diff.*-\w*N', "don't use 'diff -N'"), - (r'(^| )wc[^|]*$', "filter wc output"), + (r'(^| )wc[^|]*$\n(?!.*\(re\))', "filter wc output"), (r'head -c', "don't use 'head -c', use 'dd'"), (r'ls.*-\w*R', "don't use 'ls -R', use 'find'"), (r'printf.*\\\d\d\d', "don't use 'printf \NNN', use Python"), @@ -63,12 +63,12 @@ (r'\$PWD', "don't use $PWD, use `pwd`"), (r'[^\n]\Z', "no trailing newline"), (r'export.*=', "don't export and assign at once"), - ('^([^"\']|("[^"]*")|(\'[^\']*\'))*\\^', "^ must be quoted"), + (r'^([^"\'\n]|("[^"\n]*")|(\'[^\'\n]*\'))*\\^', "^ 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"), - (r'[^>]>\s*\$HGRCPATH', "don't overwrite $HGRCPATH, append to it"), - (r'stop\(\)', "don't use 'stop' as a shell function name"), + (r'ls +[^|\n-]+ +-', "options to 'ls' must come before filenames"), + (r'[^>\n]>\s*\$HGRCPATH', "don't overwrite $HGRCPATH, append to it"), + (r'^stop\(\)', "don't use 'stop' as a shell function name"), (r'(\[|\btest\b).*-e ', "don't use 'test -e', use 'test -f'"), ], # warnings @@ -84,7 +84,7 @@ uprefixc = r"^ > " utestpats = [ [ - (r'^(\S| $ ).*(\S\s+|^\s+)\n', "trailing whitespace on non-output"), + (r'^(\S| $ ).*(\S[ \t]+|^[ \t]+)\n', "trailing whitespace on non-output"), (uprefix + r'.*\|\s*sed', "use regex test output patterns instead of sed"), (uprefix + r'(true|exit 0)', "explicit zero exit unnecessary"), (uprefix + r'.*\$\?', "explicit exit code checks unnecessary"), @@ -99,10 +99,10 @@ for i in [0, 1]: for p, m in testpats[i]: - if p.startswith('^'): + if p.startswith(r'^'): p = uprefix + p[1:] else: - p = uprefix + p + p = uprefix + ".*" + p utestpats[i].append((p, m)) utestfilters = [ @@ -122,16 +122,19 @@ (r'\S;\s*\n', "semicolon"), (r'\w,\w', "missing whitespace after ,"), (r'\w[+/*\-<>]\w', "missing whitespace in expression"), - (r'^\s+\w+=\w+[^,)]$', "missing whitespace in assignment"), + (r'^\s+\w+=\w+[^,)\n]$', "missing whitespace in assignment"), + (r'(\s+)try:\n((?:\n|\1\s.*\n)+?)\1except.*?:\n' + r'((?:\n|\1\s.*\n)+?)\1finally:', 'no try/except/finally in Py2.4'), (r'.{85}', "line too long"), + (r' x+[xo][\'"]\n\s+[\'"]x', 'string join across lines with no space'), (r'[^\n]\Z', "no trailing newline"), - (r'(\S\s+|^\s+)\n', "trailing whitespace"), -# (r'^\s+[^_ ][^_. ]+_[^_]+\s*=', "don't use underbars in identifiers"), + (r'(\S[ \t]+|^[ \t]+)\n', "trailing whitespace"), +# (r'^\s+[^_ \n][^_. \n]+_[^_\n]+\s*=', "don't use underbars in identifiers"), # (r'\w*[a-z][A-Z]\w*\s*=', "don't use camelcase in identifiers"), - (r'^\s*(if|while|def|class|except|try)\s[^[]*:\s*[^\]#\s]+', + (r'^\s*(if|while|def|class|except|try)\s[^[\n]*:\s*[^\\n]#\s]+', "linebreak after :"), - (r'class\s[^( ]+:', "old-style class, use class foo(object)"), - (r'class\s[^( ]+\(\):', + (r'class\s[^( \n]+:', "old-style class, use class foo(object)"), + (r'class\s[^( \n]+\(\):', "class foo() not available in Python 2.4, use class foo(object)"), (r'\b(%s)\(' % '|'.join(keyword.kwlist), "Python keyword is not a function"), @@ -153,7 +156,7 @@ (r'if\s.*\selse', "if ... else form not available in Python 2.4"), (r'^\s*(%s)\s\s' % '|'.join(keyword.kwlist), "gratuitous whitespace after Python keyword"), - (r'([\(\[]\s\S)|(\S\s[\)\]])', "gratuitous whitespace in () or []"), + (r'([\(\[][ \t]\S)|(\S[ \t][\)\]])', "gratuitous whitespace in () or []"), # (r'\s\s=', "gratuitous whitespace before ="), (r'[^>< ](\+=|-=|!=|<>|<=|>=|<<=|>>=)\S', "missing whitespace around operator"), @@ -173,6 +176,8 @@ 'hasattr(foo, bar) is broken, use util.safehasattr(foo, bar) instead'), (r'opener\([^)]*\).read\(', "use opener.read() instead"), + (r'BaseException', 'not in Py2.4, use Exception'), + (r'os\.path\.relpath', 'os.path.relpath is not in Py2.5'), (r'opener\([^)]*\).write\(', "use opener.write() instead"), (r'[\s\(](open|file)\([^)]*\)\.read\(', @@ -207,7 +212,7 @@ (r'//', "don't use //-style comments"), (r'^ ', "don't use spaces to indent"), (r'\S\t', "don't use tabs except for indent"), - (r'(\S\s+|^\s+)\n', "trailing whitespace"), + (r'(\S[ \t]+|^[ \t]+)\n', "trailing whitespace"), (r'.{85}', "line too long"), (r'(while|if|do|for)\(', "use space after while/if/do/for"), (r'return\(', "return is not a function"), @@ -332,32 +337,63 @@ else: pats = pats[0] # print post # uncomment to show filtered version - z = enumerate(zip(pre.splitlines(), post.splitlines(True))) + if debug: print "Checking %s for %s" % (name, f) - for n, l in z: - if "check-code" + "-ignore" in l[0]: - if debug: - print "Skipping %s for %s:%s (check-code -ignore)" % ( - name, f, n) - continue - for p, msg in pats: - if re.search(p, l[1]): - bd = "" - if blame: - bd = 'working directory' - if not blamecache: - blamecache = getblame(f) - if n < len(blamecache): - bl, bu, br = blamecache[n] - if bl == l[0]: - bd = '%s@%s' % (bu, br) - logfunc(f, n + 1, l[0], msg, bd) - fc += 1 - result = False + + prelines = None + errors = [] + for p, msg in pats: + # fix-up regexes for multiline searches + po = p + # \s doesn't match \n + p = re.sub(r'(?<!\\)\\s', r'[ \\t]', p) + # [^...] doesn't match newline + p = re.sub(r'(?<!\\)\[\^', r'[^\\n', p) + + #print po, '=>', p + + pos = 0 + n = 0 + for m in re.finditer(p, post, re.MULTILINE): + if prelines is None: + prelines = pre.splitlines() + postlines = post.splitlines(True) + + start = m.start() + while n < len(postlines): + step = len(postlines[n]) + if pos + step > start: + break + pos += step + n += 1 + l = prelines[n] + + if "check-code" + "-ignore" in l: + if debug: + print "Skipping %s for %s:%s (check-code -ignore)" % ( + name, f, n) + continue + bd = "" + if blame: + bd = 'working directory' + if not blamecache: + blamecache = getblame(f) + if n < len(blamecache): + bl, bu, br = blamecache[n] + if bl == l: + bd = '%s@%s' % (bu, br) + errors.append((f, n + 1, l, msg, bd)) + result = False + + errors.sort() + for e in errors: + logfunc(*e) + fc += 1 if maxerr is not None and fc >= maxerr: print " (too many errors, giving up)" break + return result if __name__ == "__main__":
--- a/contrib/shrink-revlog.py Wed Oct 26 22:35:15 2011 +0200 +++ b/contrib/shrink-revlog.py Thu Oct 27 18:35:07 2011 -0500 @@ -172,7 +172,7 @@ raise util.Abort(_('--revlog option must specify the revlog index ' 'file (*.i), not %s') % opts.get('revlog')) - indexfn = os.path.realpath(fn) + indexfn = util.realpath(fn) store = repo.sjoin('') if not indexfn.startswith(store): raise util.Abort(_('--revlog option must specify a revlog in %s, '
--- a/doc/runrst Wed Oct 26 22:35:15 2011 +0200 +++ b/doc/runrst Thu Oct 27 18:35:07 2011 -0500 @@ -20,6 +20,8 @@ except ImportError: sys.stderr.write("abort: couldn't generate documentation: docutils " "module is missing\n") + sys.stderr.write("please install python-docutils or see " + "http://docutils.sourceforge.net/\n") sys.exit(-1) def role_hg(name, rawtext, text, lineno, inliner,
--- a/hgext/convert/__init__.py Wed Oct 26 22:35:15 2011 +0200 +++ b/hgext/convert/__init__.py Thu Oct 27 18:35:07 2011 -0500 @@ -146,8 +146,8 @@ 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. + (forces target IDs to change). It takes a 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.
--- a/hgext/convert/darcs.py Wed Oct 26 22:35:15 2011 +0200 +++ b/hgext/convert/darcs.py Thu Oct 27 18:35:07 2011 -0500 @@ -45,7 +45,7 @@ if ElementTree is None: raise util.Abort(_("Python ElementTree module is not available")) - self.path = os.path.realpath(path) + self.path = util.realpath(path) self.lastrev = None self.changes = {}
--- a/hgext/convert/gnuarch.py Wed Oct 26 22:35:15 2011 +0200 +++ b/hgext/convert/gnuarch.py Thu Oct 27 18:35:07 2011 -0500 @@ -46,7 +46,7 @@ commandline.__init__(self, ui, self.execmd) - self.path = os.path.realpath(path) + self.path = util.realpath(path) self.tmppath = None self.treeversion = None
--- a/hgext/convert/subversion.py Wed Oct 26 22:35:15 2011 +0200 +++ b/hgext/convert/subversion.py Thu Oct 27 18:35:07 2011 -0500 @@ -976,7 +976,7 @@ self.wc = None self.cwd = os.getcwd() - path = os.path.realpath(path) + path = util.realpath(path) created = False if os.path.isfile(os.path.join(path, '.svn', 'entries')):
--- a/hgext/convert/transport.py Wed Oct 26 22:35:15 2011 +0200 +++ b/hgext/convert/transport.py Thu Oct 27 18:35:07 2011 -0500 @@ -18,6 +18,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +from mercurial import util from svn.core import SubversionException, Pool import svn.ra import svn.client
--- a/hgext/keyword.py Wed Oct 26 22:35:15 2011 +0200 +++ b/hgext/keyword.py Thu Oct 27 18:35:07 2011 -0500 @@ -86,7 +86,7 @@ from mercurial import scmutil from mercurial.hgweb import webcommands from mercurial.i18n import _ -import os, re, shutil, tempfile +import re, shutil, tempfile commands.optionalrepo += ' kwdemo' @@ -237,7 +237,7 @@ def iskwfile(self, cand, ctx): '''Returns subset of candidates which are configured for keyword - expansion are not symbolic links.''' + expansion but are not symbolic links.''' return [f for f in cand if self.match(f) and not 'l' in ctx.flags(f)] def overwrite(self, ctx, candidates, lookup, expand, rekw=False): @@ -647,7 +647,7 @@ source = repo.dirstate.copied(dest) if 'l' in wctx.flags(source): source = scmutil.canonpath(repo.root, cwd, - os.path.realpath(source)) + util.realpath(source)) return kwt.match(source) candidates = [f for f in repo.dirstate.copies() if
--- a/hgext/largefiles/__init__.py Wed Oct 26 22:35:15 2011 +0200 +++ b/hgext/largefiles/__init__.py Thu Oct 27 18:35:07 2011 -0500 @@ -29,7 +29,7 @@ of large files when you clone or pull. To start a new repository or add new large binary files, just add ---large to your ``hg add`` command. For example:: +--large to your :hg:`add` command. For example:: $ dd if=/dev/urandom of=randomdata count=2000 $ hg add --large randomdata @@ -49,24 +49,24 @@ If you already have large files tracked by Mercurial without the largefiles extension, you will need to convert your repository in -order to benefit from largefiles. This is done with the 'hg lfconvert' -command:: +order to benefit from largefiles. This is done with the +:hg:`lfconvert` command:: $ hg lfconvert --size 10 oldrepo newrepo In repositories that already have largefiles in them, any new file over 10MB will automatically be added as a largefile. To change this -threshhold, set ``largefiles.size`` in your Mercurial config file to -the minimum size in megabytes to track as a largefile, or use the +threshold, set ``largefiles.minsize`` in your Mercurial config file +to the minimum size in megabytes to track as a largefile, or use the --lfsize option to the add command (also in megabytes):: [largefiles] - size = 2 XXX wouldn't minsize be a better name? + minsize = 2 $ hg add --lfsize 2 The ``largefiles.patterns`` config option allows you to specify a list -of filename patterns (see ``hg help patterns``) that should always be +of filename patterns (see :hg:`help patterns`) that should always be tracked as largefiles:: [largefiles]
--- a/hgext/largefiles/basestore.py Wed Oct 26 22:35:15 2011 +0200 +++ b/hgext/largefiles/basestore.py Thu Oct 27 18:35:07 2011 -0500 @@ -74,13 +74,13 @@ at += 1 ui.note(_('getting %s:%s\n') % (filename, hash)) - cachefilename = lfutil.cachepath(self.repo, hash) - cachedir = os.path.dirname(cachefilename) + storefilename = lfutil.storepath(self.repo, hash) + storedir = os.path.dirname(storefilename) # No need to pass mode='wb' to fdopen(), since mkstemp() already # opened the file in binary mode. (tmpfd, tmpfilename) = tempfile.mkstemp( - dir=cachedir, prefix=os.path.basename(filename)) + dir=storedir, prefix=os.path.basename(filename)) tmpfile = os.fdopen(tmpfd, 'w') try: @@ -98,10 +98,10 @@ missing.append(filename) continue - if os.path.exists(cachefilename): # Windows - os.remove(cachefilename) - os.rename(tmpfilename, cachefilename) - lfutil.linktosystemcache(self.repo, hash) + if os.path.exists(storefilename): # Windows + os.remove(storefilename) + os.rename(tmpfilename, storefilename) + lfutil.linktousercache(self.repo, hash) success.append((filename, hhash)) ui.progress(_('getting largefiles'), None) @@ -121,7 +121,7 @@ cctx = self.repo[rev] cset = "%d:%s" % (cctx.rev(), node.short(cctx.node())) - failed = lfutil.any_(self._verifyfile( + failed = util.any(self._verifyfile( cctx, cset, contents, standin, verified) for standin in cctx) num_revs = len(verified) @@ -199,4 +199,4 @@ except lfutil.storeprotonotcapable: pass - raise util.Abort(_('%s does not appear to be a largefile store'), path) + raise util.Abort(_('%s does not appear to be a largefile store') % path)
--- a/hgext/largefiles/design.txt Wed Oct 26 22:35:15 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,49 +0,0 @@ -= largefiles - manage large binary files = -This extension is based off of Greg Ward's bfiles extension which can be found -at http://mercurial.selenic.com/wiki/BfilesExtension. - -== The largefile store == - -largefile stores are, in the typical use case, centralized servers that have -every past revision of a given binary file. Each largefile is identified by -its sha1 hash, and all interactions with the store take one of the following -forms. - --Download a bfile with this hash --Upload a bfile with this hash --Check if the store has a bfile with this hash - -largefiles stores can take one of two forms: - --Directories on a network file share --Mercurial wireproto servers, either via ssh or http (hgweb) - -== The Local Repository == - -The local repository has a largefile cache in .hg/largefiles which holds a -subset of the largefiles needed. On a clone only the largefiles at tip are -downloaded. When largefiles are downloaded from the central store, a copy is -saved in this store. - -== The Global Cache == - -largefiles in a local repository cache are hardlinked to files in the global -cache. Before a file is downloaded we check if it is in the global cache. - -== Implementation Details == - -Each largefile has a standin which is in .hglf. The standin is tracked by -Mercurial. The standin contains the SHA1 hash of the largefile. When a -largefile is added/removed/copied/renamed/etc the same operation is applied to -the standin. Thus the history of the standin is the history of the largefile. - -For performance reasons, the contents of a standin are only updated before a -commit. Standins are added/removed/copied/renamed from add/remove/copy/rename -Mercurial commands but their contents will not be updated. The contents of a -standin will always be the hash of the largefile as of the last commit. To -support some commands (revert) some standins are temporarily updated but will -be changed back after the command is finished. - -A Mercurial dirstate object tracks the state of the largefiles. The dirstate -uses the last modified time and current size to detect if a file has changed -(without reading the entire contents of the file).
--- a/hgext/largefiles/lfcommands.py Wed Oct 26 22:35:15 2011 +0200 +++ b/hgext/largefiles/lfcommands.py Thu Oct 27 18:35:07 2011 -0500 @@ -35,34 +35,23 @@ largefiles is enabled anywhere you intend to push the new repository. - Use --tonormal to convert largefiles back to normal files; after + Use --to-normal to convert largefiles back to normal files; after this, the DEST repository can be used without largefiles at all.''' - if opts['tonormal']: + if opts['to_normal']: tolfile = False else: tolfile = True size = lfutil.getminsize(ui, True, opts.get('size'), default=None) - try: - rsrc = hg.repository(ui, src) - if not rsrc.local(): - raise util.Abort(_('%s is not a local Mercurial repo') % src) - except error.RepoError, err: - ui.traceback() - raise util.Abort(err.args[0]) - if os.path.exists(dest): - if not os.path.isdir(dest): - raise util.Abort(_('destination %s already exists') % dest) - elif os.listdir(dest): - raise util.Abort(_('destination %s is not empty') % dest) - try: - ui.status(_('initializing destination %s\n') % dest) - rdst = hg.repository(ui, dest, create=True) - if not rdst.local(): - raise util.Abort(_('%s is not a local Mercurial repo') % dest) - except error.RepoError: - ui.traceback() - raise util.Abort(_('%s is not a repo') % dest) + + if not hg.islocal(src): + raise util.Abort(_('%s is not a local Mercurial repo') % src) + if not hg.islocal(dest): + raise util.Abort(_('%s is not a local Mercurial repo') % dest) + + rsrc = hg.repository(ui, src) + ui.status(_('initializing destination %s\n') % dest) + rdst = hg.repository(ui, dest, create=True) success = False try: @@ -109,6 +98,11 @@ except OSError: pass + # If there were any files converted to largefiles, add largefiles + # to the destination repository's requirements. + if lfiles: + rdst.requirements.add('largefiles') + rdst._writerequirements() else: for ctx in ctxs: ui.progress(_('converting revisions'), ctx.rev(), @@ -251,7 +245,7 @@ # largefile was modified, update standins fullpath = rdst.wjoin(f) - lfutil.createdir(os.path.dirname(fullpath)) + util.makedirs(os.path.dirname(fullpath)) m = util.sha1('') m.update(ctx[f].data()) hash = m.hexdigest() @@ -286,7 +280,7 @@ # doesn't change after rename or copy renamed = lfutil.standin(renamed[0]) - return context.memfilectx(f, lfiletohash[srcfname], 'l' in + return context.memfilectx(f, lfiletohash[srcfname] + '\n', 'l' in fctx.flags(), 'x' in fctx.flags(), renamed) else: try: @@ -331,9 +325,7 @@ def uploadlfiles(ui, rsrc, rdst, files): '''upload largefiles to the central store''' - # Don't upload locally. All largefiles are in the system wide cache - # so the other repo can just get them from there. - if not files or rdst.local(): + if not files: return store = basestore._openstore(rsrc, rdst, put=True) @@ -474,7 +466,7 @@ _('minimum size (MB) for files to be converted ' 'as largefiles'), 'SIZE'), - ('', 'tonormal', False, + ('', 'to-normal', False, _('convert from a largefiles repo to a normal repo')), ], _('hg lfconvert SOURCE DEST [FILE ...]')),
--- a/hgext/largefiles/lfutil.py Wed Oct 26 22:35:15 2011 +0200 +++ b/hgext/largefiles/lfutil.py Thu Oct 27 18:35:07 2011 -0500 @@ -10,9 +10,9 @@ import os import errno +import platform import shutil import stat -import hashlib from mercurial import dirstate, httpconnection, match as match_, util, scmutil from mercurial.i18n import _ @@ -61,7 +61,7 @@ def getminsize(ui, assumelfiles, opt, default=10): lfsize = opt if not lfsize and assumelfiles: - lfsize = ui.config(longname, 'size', default=default) + lfsize = ui.config(longname, 'minsize', default=default) if lfsize: try: lfsize = float(lfsize) @@ -80,31 +80,39 @@ shutil.copyfile(src, dest) os.chmod(dest, os.stat(src).st_mode) -def systemcachepath(ui, hash): - path = ui.config(longname, 'systemcache', None) +def usercachepath(ui, hash): + path = ui.configpath(longname, 'usercache', None) if path: path = os.path.join(path, hash) else: if os.name == 'nt': appdata = os.getenv('LOCALAPPDATA', os.getenv('APPDATA')) path = os.path.join(appdata, longname, hash) + elif platform.system() == 'Darwin': + path = os.path.join(os.getenv('HOME'), 'Library', 'Caches', + longname, hash) elif os.name == 'posix': - path = os.path.join(os.getenv('HOME'), '.' + longname, hash) + path = os.getenv('XDG_CACHE_HOME') + if path: + path = os.path.join(path, longname, hash) + else: + path = os.path.join(os.getenv('HOME'), '.cache', longname, hash) else: raise util.Abort(_('unknown operating system: %s\n') % os.name) return path -def insystemcache(ui, hash): - return os.path.exists(systemcachepath(ui, hash)) +def inusercache(ui, hash): + return os.path.exists(usercachepath(ui, hash)) def findfile(repo, hash): - if incache(repo, hash): - repo.ui.note(_('Found %s in cache\n') % hash) - return cachepath(repo, hash) - if insystemcache(repo.ui, hash): + if instore(repo, hash): + repo.ui.note(_('Found %s in store\n') % hash) + elif inusercache(repo.ui, hash): repo.ui.note(_('Found %s in system cache\n') % hash) - return systemcachepath(repo.ui, hash) - return None + link(usercachepath(repo.ui, hash), storepath(repo, hash)) + else: + return None + return storepath(repo, hash) class largefiles_dirstate(dirstate.dirstate): def __getitem__(self, key): @@ -127,11 +135,8 @@ ''' admin = repo.join(longname) opener = scmutil.opener(admin) - if util.safehasattr(repo.dirstate, '_validate'): - lfdirstate = largefiles_dirstate(opener, ui, repo.root, - repo.dirstate._validate) - else: - lfdirstate = largefiles_dirstate(opener, ui, repo.root) + lfdirstate = largefiles_dirstate(opener, ui, repo.root, + repo.dirstate._validate) # If the largefiles dirstate does not exist, populate and create # it. This ensures that we create it on the first meaningful @@ -188,14 +193,10 @@ for f in repo[rev].walk(matcher) if rev is not None or repo.dirstate[f] != '?'] -def incache(repo, hash): - return os.path.exists(cachepath(repo, hash)) +def instore(repo, hash): + return os.path.exists(storepath(repo, hash)) -def createdir(dir): - if not os.path.exists(dir): - os.makedirs(dir) - -def cachepath(repo, hash): +def storepath(repo, hash): return repo.join(os.path.join(longname, hash)) def copyfromcache(repo, hash, filename): @@ -211,24 +212,24 @@ shutil.copy(path, repo.wjoin(filename)) return True -def copytocache(repo, rev, file, uploaded=False): +def copytostore(repo, rev, file, uploaded=False): hash = readstandin(repo, file) - if incache(repo, hash): + if instore(repo, hash): return - copytocacheabsolute(repo, repo.wjoin(file), hash) + copytostoreabsolute(repo, repo.wjoin(file), hash) -def copytocacheabsolute(repo, file, hash): - createdir(os.path.dirname(cachepath(repo, hash))) - if insystemcache(repo.ui, hash): - link(systemcachepath(repo.ui, hash), cachepath(repo, hash)) +def copytostoreabsolute(repo, file, hash): + util.makedirs(os.path.dirname(storepath(repo, hash))) + if inusercache(repo.ui, hash): + link(usercachepath(repo.ui, hash), storepath(repo, hash)) else: - shutil.copyfile(file, cachepath(repo, hash)) - os.chmod(cachepath(repo, hash), os.stat(file).st_mode) - linktosystemcache(repo, hash) + shutil.copyfile(file, storepath(repo, hash)) + os.chmod(storepath(repo, hash), os.stat(file).st_mode) + linktousercache(repo, hash) -def linktosystemcache(repo, hash): - createdir(os.path.dirname(systemcachepath(repo.ui, hash))) - link(cachepath(repo, hash), systemcachepath(repo.ui, hash)) +def linktousercache(repo, hash): + util.makedirs(os.path.dirname(usercachepath(repo.ui, hash))) + link(storepath(repo, hash), usercachepath(repo.ui, hash)) def getstandinmatcher(repo, pats=[], opts={}): '''Return a match object that applies pats to the standin directory''' @@ -421,7 +422,7 @@ def hexsha1(data): """hexsha1 returns the hex-encoded sha1 sum of the data in the file-like object data""" - h = hashlib.sha1() + h = util.sha1() for chunk in util.filechunkiter(data): h.update(chunk) return h.hexdigest() @@ -435,14 +436,8 @@ def islfilesrepo(repo): return ('largefiles' in repo.requirements and - any_(shortname + '/' in f[0] for f in repo.store.datafiles())) + util.any(shortname + '/' in f[0] for f in repo.store.datafiles())) -def any_(gen): - for x in gen: - if x: - return True - return False - -class storeprotonotcapable(BaseException): +class storeprotonotcapable(Exception): def __init__(self, storetypes): self.storetypes = storetypes
--- a/hgext/largefiles/localstore.py Wed Oct 26 22:35:15 2011 +0200 +++ b/hgext/largefiles/localstore.py Thu Oct 27 18:35:07 2011 -0500 @@ -17,27 +17,38 @@ import basestore class localstore(basestore.basestore): - '''Because there is a system-wide cache, the local store always - uses that cache. Since the cache is updated elsewhere, we can - just read from it here as if it were the store.''' + '''localstore first attempts to grab files out of the store in the remote + Mercurial repository. Failling that, it attempts to grab the files from + the user cache.''' def __init__(self, ui, repo, remote): url = os.path.join(remote.path, '.hg', lfutil.longname) super(localstore, self).__init__(ui, repo, util.expandpath(url)) + self.remote = remote - def put(self, source, filename, hash): - '''Any file that is put must already be in the system-wide - cache so do nothing.''' - return + def put(self, source, hash): + util.makedirs(os.path.dirname(lfutil.storepath(self.remote, hash))) + if lfutil.instore(self.remote, hash): + return + lfutil.link(lfutil.storepath(self.repo, hash), + lfutil.storepath(self.remote, hash)) def exists(self, hash): - return lfutil.insystemcache(self.repo.ui, hash) + return lfutil.instore(self.remote, hash) def _getfile(self, tmpfile, filename, hash): - if lfutil.insystemcache(self.ui, hash): - return lfutil.systemcachepath(self.ui, hash) - raise basestore.StoreError(filename, hash, '', - _("Can't get file locally")) + if lfutil.instore(self.remote, hash): + path = lfutil.storepath(self.remote, hash) + elif lfutil.inusercache(self.ui, hash): + path = lfutil.usercachepath(self.ui, hash) + else: + raise basestore.StoreError(filename, hash, '', + _("Can't get file locally")) + fd = open(path, 'rb') + try: + return lfutil.copyandhash(fd, tmpfile) + finally: + fd.close() def _verifyfile(self, cctx, cset, contents, standin, verified): filename = lfutil.splitstandin(standin) @@ -50,7 +61,7 @@ expecthash = fctx.data()[0:40] verified.add(key) - if not lfutil.insystemcache(self.ui, expecthash): + if not lfutil.instore(self.remote, expecthash): self.ui.warn( _('changeset %s: %s missing\n' ' (looked for hash %s)\n') @@ -58,7 +69,7 @@ return True # failed if contents: - storepath = lfutil.systemcachepath(self.ui, expecthash) + storepath = lfutil.storepath(self.remote, expecthash) actualhash = lfutil.hashfile(storepath) if actualhash != expecthash: self.ui.warn(
--- a/hgext/largefiles/overrides.py Wed Oct 26 22:35:15 2011 +0200 +++ b/hgext/largefiles/overrides.py Thu Oct 27 18:35:07 2011 -0500 @@ -11,17 +11,11 @@ import os import copy -from mercurial import hg, commands, util, cmdutil, match as match_, node, \ - archival, error, merge +from mercurial import hg, commands, util, cmdutil, scmutil, match as match_, \ + node, archival, error, merge from mercurial.i18n import _ from mercurial.node import hex from hgext import rebase -import lfutil - -try: - from mercurial import scmutil -except ImportError: - pass import lfutil import lfcommands @@ -30,9 +24,9 @@ '''overrides scmutil.match so that the matcher it returns will ignore all largefiles''' oldmatch = None # for the closure - def override_match(repo, pats=[], opts={}, globbed=False, + def override_match(ctx, pats=[], opts={}, globbed=False, default='relpath'): - match = oldmatch(repo, pats, opts, globbed, default) + match = oldmatch(ctx, pats, opts, globbed, default) m = copy.copy(match) notlfile = lambda f: not (lfutil.isstandin(f) or lfutil.standin(f) in manifest) @@ -93,7 +87,7 @@ if exact or not exists: abovemin = (lfsize and - os.path.getsize(repo.wjoin(f)) >= lfsize * 1024 * 1024) + os.lstat(repo.wjoin(f)).st_size >= lfsize * 1024 * 1024) if large or abovemin or (lfmatcher and lfmatcher(f)): lfnames.append(f) if ui.verbose or not exact: @@ -151,18 +145,18 @@ def warn(files, reason): for f in files: - ui.warn(_('not removing %s: file %s (use -f to force removal)\n') + ui.warn(_('not removing %s: %s (use -f to force removal)\n') % (m.rel(f), reason)) if force: remove, forget = modified + deleted + clean, added elif after: remove, forget = deleted, [] - warn(modified + added + clean, _('still exists')) + warn(modified + added + clean, _('file still exists')) else: remove, forget = deleted + clean, [] - warn(modified, _('is modified')) - warn(added, _('has been marked for add')) + warn(modified, _('file is modified')) + warn(added, _('file has been marked for add')) for f in sorted(remove + forget): if ui.verbose or not m.exact(f): @@ -304,8 +298,7 @@ def makestandin(relpath): path = scmutil.canonpath(repo.root, repo.getcwd(), relpath) - return os.path.join(os.path.relpath('.', repo.getcwd()), - lfutil.standin(path)) + return os.path.join(repo.wjoin(lfutil.standin(path))) fullpats = scmutil.expandpats(pats) dest = fullpats[-1] @@ -320,14 +313,15 @@ nonormalfiles = False nolfiles = False try: - installnormalfilesmatchfn(repo[None].manifest()) - result = orig(ui, repo, pats, opts, rename) - except util.Abort, e: - if str(e) != 'no files to copy': - raise e - else: - nonormalfiles = True - result = 0 + try: + installnormalfilesmatchfn(repo[None].manifest()) + result = orig(ui, repo, pats, opts, rename) + except util.Abort, e: + if str(e) != 'no files to copy': + raise e + else: + nonormalfiles = True + result = 0 finally: restorematchfn() @@ -339,80 +333,79 @@ return result try: - # When we call orig below it creates the standins but we don't add them - # to the dir state until later so lock during that time. - wlock = repo.wlock() + try: + # When we call orig below it creates the standins but we don't add them + # to the dir state until later so lock during that time. + wlock = repo.wlock() - manifest = repo[None].manifest() - oldmatch = None # for the closure - def override_match(repo, pats=[], opts={}, globbed=False, - default='relpath'): - newpats = [] - # The patterns were previously mangled to add the standin - # directory; we need to remove that now + manifest = repo[None].manifest() + oldmatch = None # for the closure + def override_match(ctx, pats=[], opts={}, globbed=False, + default='relpath'): + newpats = [] + # The patterns were previously mangled to add the standin + # directory; we need to remove that now + for pat in pats: + if match_.patkind(pat) is None and lfutil.shortname in pat: + newpats.append(pat.replace(lfutil.shortname, '')) + else: + newpats.append(pat) + match = oldmatch(ctx, newpats, opts, globbed, default) + m = copy.copy(match) + lfile = lambda f: lfutil.standin(f) in manifest + m._files = [lfutil.standin(f) for f in m._files if lfile(f)] + m._fmap = set(m._files) + orig_matchfn = m.matchfn + m.matchfn = lambda f: (lfutil.isstandin(f) and + lfile(lfutil.splitstandin(f)) and + orig_matchfn(lfutil.splitstandin(f)) or + None) + return m + oldmatch = installmatchfn(override_match) + listpats = [] for pat in pats: - if match_.patkind(pat) is None and lfutil.shortname in pat: - newpats.append(pat.replace(lfutil.shortname, '')) + if match_.patkind(pat) is not None: + listpats.append(pat) else: - newpats.append(pat) - match = oldmatch(repo, newpats, opts, globbed, default) - m = copy.copy(match) - lfile = lambda f: lfutil.standin(f) in manifest - m._files = [lfutil.standin(f) for f in m._files if lfile(f)] - m._fmap = set(m._files) - orig_matchfn = m.matchfn - m.matchfn = lambda f: (lfutil.isstandin(f) and - lfile(lfutil.splitstandin(f)) and - orig_matchfn(lfutil.splitstandin(f)) or - None) - return m - oldmatch = installmatchfn(override_match) - listpats = [] - for pat in pats: - if match_.patkind(pat) is not None: - listpats.append(pat) - else: - listpats.append(makestandin(pat)) + listpats.append(makestandin(pat)) - try: - origcopyfile = util.copyfile - copiedfiles = [] - def override_copyfile(src, dest): - if lfutil.shortname in src and lfutil.shortname in dest: - destlfile = dest.replace(lfutil.shortname, '') - if not opts['force'] and os.path.exists(destlfile): - raise IOError('', - _('destination largefile already exists')) - copiedfiles.append((src, dest)) - origcopyfile(src, dest) + try: + origcopyfile = util.copyfile + copiedfiles = [] + def override_copyfile(src, dest): + if lfutil.shortname in src and lfutil.shortname in dest: + destlfile = dest.replace(lfutil.shortname, '') + if not opts['force'] and os.path.exists(destlfile): + raise IOError('', + _('destination largefile already exists')) + copiedfiles.append((src, dest)) + origcopyfile(src, dest) - util.copyfile = override_copyfile - result += orig(ui, repo, listpats, opts, rename) - finally: - util.copyfile = origcopyfile + util.copyfile = override_copyfile + result += orig(ui, repo, listpats, opts, rename) + finally: + util.copyfile = origcopyfile - lfdirstate = lfutil.openlfdirstate(ui, repo) - for (src, dest) in copiedfiles: - if lfutil.shortname in src and lfutil.shortname in dest: - srclfile = src.replace(lfutil.shortname, '') - destlfile = dest.replace(lfutil.shortname, '') - destlfiledir = os.path.dirname(destlfile) or '.' - if not os.path.isdir(destlfiledir): - os.makedirs(destlfiledir) - if rename: - os.rename(srclfile, destlfile) - lfdirstate.remove(os.path.relpath(srclfile, - repo.root)) - else: - util.copyfile(srclfile, destlfile) - lfdirstate.add(os.path.relpath(destlfile, - repo.root)) - lfdirstate.write() - except util.Abort, e: - if str(e) != 'no files to copy': - raise e - else: - nolfiles = True + lfdirstate = lfutil.openlfdirstate(ui, repo) + for (src, dest) in copiedfiles: + if lfutil.shortname in src and lfutil.shortname in dest: + srclfile = src.replace(lfutil.shortname, '') + destlfile = dest.replace(lfutil.shortname, '') + destlfiledir = os.path.dirname(destlfile) or '.' + if not os.path.isdir(destlfiledir): + os.makedirs(destlfiledir) + if rename: + os.rename(srclfile, destlfile) + lfdirstate.remove(repo.wjoin(srclfile)) + else: + util.copyfile(srclfile, destlfile) + lfdirstate.add(repo.wjoin(destlfile)) + lfdirstate.write() + except util.Abort, e: + if str(e) != 'no files to copy': + raise e + else: + nolfiles = True finally: restorematchfn() wlock.release() @@ -447,16 +440,12 @@ try: ctx = repo[opts.get('rev')] oldmatch = None # for the closure - def override_match(ctxorrepo, pats=[], opts={}, globbed=False, + def override_match(ctx, pats=[], opts={}, globbed=False, default='relpath'): - if util.safehasattr(ctxorrepo, 'match'): - ctx0 = ctxorrepo - else: - ctx0 = ctxorrepo[None] - match = oldmatch(ctxorrepo, pats, opts, globbed, default) + match = oldmatch(ctx, pats, opts, globbed, default) m = copy.copy(match) def tostandin(f): - if lfutil.standin(f) in ctx0 or lfutil.standin(f) in ctx: + if lfutil.standin(f) in ctx or lfutil.standin(f) in ctx: return lfutil.standin(f) elif lfutil.standin(f) in repo[None]: return None
--- a/hgext/largefiles/proto.py Wed Oct 26 22:35:15 2011 +0200 +++ b/hgext/largefiles/proto.py Thu Oct 27 18:35:07 2011 -0500 @@ -17,8 +17,8 @@ 'file.\n') def putlfile(repo, proto, sha): - '''Put a largefile into a repository's local cache and into the - system cache.''' + '''Put a largefile into a repository's local store and into the + user cache.''' f = None proto.redirect() try: @@ -28,7 +28,7 @@ f.seek(0) if sha != lfutil.hexsha1(f): return wireproto.pushres(1) - lfutil.copytocacheabsolute(repo, f.name, sha) + lfutil.copytostoreabsolute(repo, f.name, sha) except IOError: repo.ui.warn( _('error: could not put received data into largefile store'))
--- a/hgext/largefiles/reposetup.py Wed Oct 26 22:35:15 2011 +0200 +++ b/hgext/largefiles/reposetup.py Thu Oct 27 18:35:07 2011 -0500 @@ -12,8 +12,7 @@ import os import re -from mercurial import context, error, manifest, match as match_, \ - node, util +from mercurial import context, error, manifest, match as match_, node, util from mercurial.i18n import _ import lfcommands @@ -229,7 +228,7 @@ for filename in ctx.files(): if lfutil.isstandin(filename) and filename in ctx.manifest(): realfile = lfutil.splitstandin(filename) - lfutil.copytocache(self, ctx.node(), realfile) + lfutil.copytostore(self, ctx.node(), realfile) return node @@ -347,7 +346,7 @@ fstandin += os.sep # prevalidate matching standin directories - if lfutil.any_(st for st in match._files + if util.any(st for st in match._files if st.startswith(fstandin)): continue actualfiles.append(f) @@ -401,13 +400,9 @@ repo.__class__ = lfiles_repo def checkrequireslfiles(ui, repo, **kwargs): - if 'largefiles' not in repo.requirements and lfutil.any_( + if 'largefiles' not in repo.requirements and util.any( lfutil.shortname+'/' in f[0] for f in repo.store.datafiles()): - # workaround bug in Mercurial 1.9 whereby requirements is - # a list on newly-cloned repos - repo.requirements = set(repo.requirements) - - repo.requirements |= set(['largefiles']) + repo.requirements.add('largefiles') repo._writerequirements() checkrequireslfiles(ui, repo)
--- a/hgext/largefiles/uisetup.py Wed Oct 26 22:35:15 2011 +0200 +++ b/hgext/largefiles/uisetup.py Thu Oct 27 18:35:07 2011 -0500 @@ -9,7 +9,7 @@ '''setup for largefiles extension: uisetup''' from mercurial import archival, cmdutil, commands, extensions, filemerge, hg, \ - httprepo, localrepo, sshrepo, sshserver, util, wireproto + httprepo, localrepo, sshrepo, sshserver, wireproto from mercurial.i18n import _ from mercurial.hgweb import hgweb_mod, protocol @@ -23,7 +23,7 @@ entry = extensions.wrapcommand(commands.table, 'add', overrides.override_add) addopt = [('', 'large', None, _('add as largefile')), - ('', 'lfsize', '', _('add all files above this size (in megabytes)' + ('', 'lfsize', '', _('add all files above this size (in megabytes) ' 'as largefiles (default: 10)'))] entry[1].extend(addopt) @@ -82,12 +82,8 @@ extensions.wrapfunction(hg, 'merge', overrides.hg_merge) extensions.wrapfunction(archival, 'archive', overrides.override_archive) - if util.safehasattr(cmdutil, 'bailifchanged'): - extensions.wrapfunction(cmdutil, 'bailifchanged', - overrides.override_bailifchanged) - else: - extensions.wrapfunction(cmdutil, 'bail_if_changed', - overrides.override_bailifchanged) + extensions.wrapfunction(cmdutil, 'bailifchanged', + overrides.override_bailifchanged) # create the new wireproto commands ... wireproto.commands['putlfile'] = (proto.putlfile, 'sha')
--- a/hgext/largefiles/usage.txt Wed Oct 26 22:35:15 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,51 +0,0 @@ -Largefiles allows for tracking large, incompressible binary files in Mercurial -without requiring excessive bandwidth for clones and pulls. Files added as -largefiles are not tracked directly by Mercurial; rather, their revisions are -identified by a checksum, and Mercurial tracks these checksums. This way, when -you clone a repository or pull in changesets, the large files in older -revisions of the repository are not needed, and only the ones needed to update -to the current version are downloaded. This saves both disk space and -bandwidth. - -If you are starting a new repository or adding new large binary files, using -largefiles for them is as easy as adding '--large' to your hg add command. For -example: - -$ dd if=/dev/urandom of=thisfileislarge count=2000 -$ hg add --large thisfileislarge -$ hg commit -m 'add thisfileislarge, which is large, as a largefile' - -When you push a changeset that affects largefiles to a remote repository, its -largefile revisions will be uploaded along with it. Note that the remote -Mercurial must also have the largefiles extension enabled for this to work. - -When you pull a changeset that affects largefiles from a remote repository, -nothing different from Mercurial's normal behavior happens. However, when you -update to such a revision, any largefiles needed by that revision are -downloaded and cached if they have never been downloaded before. This means -that network access is required to update to revision you have not yet updated -to. - -If you already have large files tracked by Mercurial without the largefiles -extension, you will need to convert your repository in order to benefit from -largefiles. This is done with the 'hg lfconvert' command: - -$ hg lfconvert --size 10 oldrepo newrepo - -By default, in repositories that already have largefiles in them, any new file -over 10MB will automatically be added as largefiles. To change this -threshhold, set [largefiles].size in your Mercurial config file to the minimum -size in megabytes to track as a largefile, or use the --lfsize option to the -add command (also in megabytes): - -[largefiles] -size = 2 - -$ hg add --lfsize 2 - -The [largefiles].patterns config option allows you to specify specific -space-separated filename patterns (in shell glob syntax) that should always be -tracked as largefiles: - -[largefiles] -pattens = *.jpg *.{png,bmp} library.zip content/audio/*
--- a/hgext/mq.py Wed Oct 26 22:35:15 2011 +0200 +++ b/hgext/mq.py Thu Oct 27 18:35:07 2011 -0500 @@ -2614,8 +2614,6 @@ r.dirstate.drop(patch) r.dirstate.add(name) else: - if r.dirstate[name] == 'r': - wctx.undelete([name]) wctx.copy(patch, name) wctx.forget([patch]) finally:
--- a/hgext/rebase.py Wed Oct 26 22:35:15 2011 +0200 +++ b/hgext/rebase.py Thu Oct 27 18:35:07 2011 -0500 @@ -162,10 +162,10 @@ raise util.Abort(_('cannot specify both a ' 'source and a base')) if revf and basef: - raise util.Abort(_('cannot specify both a' + raise util.Abort(_('cannot specify both a ' 'revision and a base')) if revf and srcf: - raise util.Abort(_('cannot specify both a' + raise util.Abort(_('cannot specify both a ' 'revision and a source')) if detachf: if not srcf:
--- a/i18n/polib.py Wed Oct 26 22:35:15 2011 +0200 +++ b/i18n/polib.py Thu Oct 27 18:35:07 2011 -0500 @@ -5,113 +5,48 @@ # vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: """ -**polib** allows you to manipulate, create, modify gettext files (pot, po -and mo files). You can load existing files, iterate through it's entries, -add, modify entries, comments or metadata, etc... or create new po files -from scratch. - -**polib** provides a simple and pythonic API, exporting only three -convenience functions (*pofile*, *mofile* and *detect_encoding*), and the -four core classes, *POFile*, *MOFile*, *POEntry* and *MOEntry* for creating -new files/entries. - -**Basic example**: +**polib** allows you to manipulate, create, modify gettext files (pot, po and +mo files). You can load existing files, iterate through it's entries, add, +modify entries, comments or metadata, etc. or create new po files from scratch. ->>> import polib ->>> # load an existing po file ->>> po = polib.pofile('tests/test_utf8.po') ->>> for entry in po: -... # do something with entry... -... pass ->>> # add an entry ->>> entry = polib.POEntry(msgid='Welcome', msgstr='Bienvenue') ->>> entry.occurrences = [('welcome.py', '12'), ('anotherfile.py', '34')] ->>> po.append(entry) ->>> # to save our modified po file: ->>> # po.save() ->>> # or you may want to compile the po file ->>> # po.save_as_mofile('tests/test_utf8.mo') +**polib** provides a simple and pythonic API via the :func:`~polib.pofile` and +:func:`~polib.mofile` convenience functions. """ -__author__ = 'David JEAN LOUIS <izimobil@gmail.com>' -__version__ = '0.5.2' +__author__ = 'David Jean Louis <izimobil@gmail.com>' +__version__ = '0.6.4' __all__ = ['pofile', 'POFile', 'POEntry', 'mofile', 'MOFile', 'MOEntry', 'detect_encoding', 'escape', 'unescape', 'detect_encoding',] +import array import codecs +import os +import re import struct +import sys import textwrap import types -import re + +# the default encoding to use when encoding cannot be detected default_encoding = 'utf-8' -# function pofile() {{{ - -def pofile(fpath, **kwargs): - """ - Convenience function that parse the po/pot file *fpath* and return - a POFile instance. - - **Keyword arguments**: - - *fpath*: string, full or relative path to the po/pot file to parse - - *wrapwidth*: integer, the wrap width, only useful when -w option was - passed to xgettext (optional, default to 78) - - *autodetect_encoding*: boolean, if set to False the function will - not try to detect the po file encoding (optional, default to True) - - *encoding*: string, an encoding, only relevant if autodetect_encoding - is set to False - - *check_for_duplicates*: whether to check for duplicate entries when - adding entries to the file, default: False (optional) - - **Example**: +# _pofile_or_mofile {{{ - >>> import polib - >>> po = polib.pofile('tests/test_weird_occurrences.po', - ... check_for_duplicates=True) - >>> po #doctest: +ELLIPSIS - <POFile instance at ...> - >>> import os, tempfile - >>> all_attrs = ('msgctxt', 'msgid', 'msgstr', 'msgid_plural', - ... 'msgstr_plural', 'obsolete', 'comment', 'tcomment', - ... 'occurrences', 'flags', 'previous_msgctxt', - ... 'previous_msgid', 'previous_msgid_plural') - >>> for fname in ['test_iso-8859-15.po', 'test_utf8.po']: - ... orig_po = polib.pofile('tests/'+fname) - ... tmpf = tempfile.NamedTemporaryFile().name - ... orig_po.save(tmpf) - ... try: - ... new_po = polib.pofile(tmpf) - ... for old, new in zip(orig_po, new_po): - ... for attr in all_attrs: - ... if getattr(old, attr) != getattr(new, attr): - ... getattr(old, attr) - ... getattr(new, attr) - ... finally: - ... os.unlink(tmpf) - >>> po_file = polib.pofile('tests/test_save_as_mofile.po') - >>> tmpf = tempfile.NamedTemporaryFile().name - >>> po_file.save_as_mofile(tmpf) - >>> try: - ... mo_file = polib.mofile(tmpf) - ... for old, new in zip(po_file, mo_file): - ... if po_file._encode(old.msgid) != mo_file._encode(new.msgid): - ... 'OLD: ', po_file._encode(old.msgid) - ... 'NEW: ', mo_file._encode(new.msgid) - ... if po_file._encode(old.msgstr) != mo_file._encode(new.msgstr): - ... 'OLD: ', po_file._encode(old.msgstr) - ... 'NEW: ', mo_file._encode(new.msgstr) - ... print new.msgstr - ... finally: - ... os.unlink(tmpf) +def _pofile_or_mofile(f, type, **kwargs): + """ + Internal function used by :func:`polib.pofile` and :func:`polib.mofile` to + honor the DRY concept. """ - if kwargs.get('autodetect_encoding', True): - enc = detect_encoding(fpath) - else: - enc = kwargs.get('encoding', default_encoding) - check_for_duplicates = kwargs.get('check_for_duplicates', False) - parser = _POFileParser( - fpath, + # get the file encoding + enc = kwargs.get('encoding') + if enc is None: + enc = detect_encoding(f, type == 'mofile') + + # parse the file + kls = type == 'pofile' and _POFileParser or _MOFileParser + parser = kls( + f, encoding=enc, check_for_duplicates=kwargs.get('check_for_duplicates', False) ) @@ -120,95 +55,108 @@ return instance # }}} +# function pofile() {{{ + +def pofile(pofile, **kwargs): + """ + Convenience function that parses the po or pot file ``pofile`` and returns + a :class:`~polib.POFile` instance. + + Arguments: + + ``pofile`` + string, full or relative path to the po/pot file or its content (data). + + ``wrapwidth`` + integer, the wrap width, only useful when the ``-w`` option was passed + to xgettext (optional, default: ``78``). + + ``encoding`` + string, the encoding to use (e.g. "utf-8") (default: ``None``, the + encoding will be auto-detected). + + ``check_for_duplicates`` + whether to check for duplicate entries when adding entries to the + file (optional, default: ``False``). + """ + return _pofile_or_mofile(pofile, 'pofile', **kwargs) + +# }}} # function mofile() {{{ -def mofile(fpath, **kwargs): +def mofile(mofile, **kwargs): """ - Convenience function that parse the mo file *fpath* and return - a MOFile instance. + Convenience function that parses the mo file ``mofile`` and returns a + :class:`~polib.MOFile` instance. - **Keyword arguments**: - - *fpath*: string, full or relative path to the mo file to parse - - *wrapwidth*: integer, the wrap width, only useful when -w option was - passed to xgettext to generate the po file that was used to format - the mo file (optional, default to 78) - - *autodetect_encoding*: boolean, if set to False the function will - not try to detect the po file encoding (optional, default to True) - - *encoding*: string, an encoding, only relevant if autodetect_encoding - is set to False - - *check_for_duplicates*: whether to check for duplicate entries when - adding entries to the file, default: False (optional) + Arguments: - **Example**: + ``mofile`` + string, full or relative path to the mo file or its content (data). - >>> import polib - >>> mo = polib.mofile('tests/test_utf8.mo', check_for_duplicates=True) - >>> mo #doctest: +ELLIPSIS - <MOFile instance at ...> - >>> import os, tempfile - >>> for fname in ['test_iso-8859-15.mo', 'test_utf8.mo']: - ... orig_mo = polib.mofile('tests/'+fname) - ... tmpf = tempfile.NamedTemporaryFile().name - ... orig_mo.save(tmpf) - ... try: - ... new_mo = polib.mofile(tmpf) - ... for old, new in zip(orig_mo, new_mo): - ... if old.msgid != new.msgid: - ... old.msgstr - ... new.msgstr - ... finally: - ... os.unlink(tmpf) + ``wrapwidth`` + integer, the wrap width, only useful when the ``-w`` option was passed + to xgettext to generate the po file that was used to format the mo file + (optional, default: ``78``). + + ``encoding`` + string, the encoding to use (e.g. "utf-8") (default: ``None``, the + encoding will be auto-detected). + + ``check_for_duplicates`` + whether to check for duplicate entries when adding entries to the + file (optional, default: ``False``). """ - if kwargs.get('autodetect_encoding', True): - enc = detect_encoding(fpath, True) - else: - enc = kwargs.get('encoding', default_encoding) - parser = _MOFileParser( - fpath, - encoding=enc, - check_for_duplicates=kwargs.get('check_for_duplicates', False) - ) - instance = parser.parse() - instance.wrapwidth = kwargs.get('wrapwidth', 78) - return instance + return _pofile_or_mofile(mofile, 'mofile', **kwargs) # }}} # function detect_encoding() {{{ -def detect_encoding(fpath, binary_mode=False): +def detect_encoding(file, binary_mode=False): """ - Try to detect the encoding used by the file *fpath*. The function will - return polib default *encoding* if it's unable to detect it. + Try to detect the encoding used by the ``file``. The ``file`` argument can + be a PO or MO file path or a string containing the contents of the file. + If the encoding cannot be detected, the function will return the value of + ``default_encoding``. - **Keyword argument**: - - *fpath*: string, full or relative path to the mo file to parse. + Arguments: + + ``file`` + string, full or relative path to the po/mo file or its content. - **Examples**: + ``binary_mode`` + boolean, set this to True if ``file`` is a mo file. + """ + rx = re.compile(r'"?Content-Type:.+? charset=([\w_\-:\.]+)') - >>> print(detect_encoding('tests/test_noencoding.po')) - utf-8 - >>> print(detect_encoding('tests/test_utf8.po')) - UTF-8 - >>> print(detect_encoding('tests/test_utf8.mo', True)) - UTF-8 - >>> print(detect_encoding('tests/test_iso-8859-15.po')) - ISO_8859-15 - >>> print(detect_encoding('tests/test_iso-8859-15.mo', True)) - ISO_8859-15 - """ - import re - rx = re.compile(r'"?Content-Type:.+? charset=([\w_\-:\.]+)') - if binary_mode: - mode = 'rb' + def charset_exists(charset): + """Check whether ``charset`` is valid or not.""" + try: + codecs.lookup(charset) + except LookupError: + return False + return True + + if not os.path.exists(file): + match = rx.search(file) + if match: + enc = match.group(1).strip() + if charset_exists(enc): + return enc else: - mode = 'r' - f = open(fpath, mode) - for l in f.readlines(): - match = rx.search(l) - if match: - f.close() - return match.group(1).strip() - f.close() + if binary_mode: + mode = 'rb' + else: + mode = 'r' + f = open(file, mode) + for l in f.readlines(): + match = rx.search(l) + if match: + f.close() + enc = match.group(1).strip() + if charset_exists(enc): + return enc + f.close() return default_encoding # }}} @@ -216,12 +164,8 @@ def escape(st): """ - Escape special chars and return the given string *st*. - - **Examples**: - - >>> escape('\\t and \\n and \\r and " and \\\\') - '\\\\t and \\\\n and \\\\r and \\\\" and \\\\\\\\' + Escapes the characters ``\\\\``, ``\\t``, ``\\n``, ``\\r`` and ``"`` in + the given string ``st`` and returns it. """ return st.replace('\\', r'\\')\ .replace('\t', r'\t')\ @@ -234,18 +178,8 @@ def unescape(st): """ - Unescape special chars and return the given string *st*. - - **Examples**: - - >>> unescape('\\\\t and \\\\n and \\\\r and \\\\" and \\\\\\\\') - '\\t and \\n and \\r and " and \\\\' - >>> unescape(r'\\n') - '\\n' - >>> unescape(r'\\\\n') - '\\\\n' - >>> unescape(r'\\\\n\\n') - '\\\\n\\n' + Unescapes the characters ``\\\\``, ``\\t``, ``\\n``, ``\\r`` and ``"`` in + the given string ``st`` and returns it. """ def unescape_repl(m): m = m.group(1) @@ -265,27 +199,36 @@ class _BaseFile(list): """ - Common parent class for POFile and MOFile classes. - This class must **not** be instanciated directly. + Common base class for the :class:`~polib.POFile` and :class:`~polib.MOFile` + classes. This class should **not** be instanciated directly. """ def __init__(self, *args, **kwargs): """ - Constructor. + Constructor, accepts the following keyword arguments: + + ``pofile`` + string, the path to the po or mo file, or its content as a string. - **Keyword arguments**: - - *fpath*: string, path to po or mo file - - *wrapwidth*: integer, the wrap width, only useful when -w option - was passed to xgettext to generate the po file that was used to - format the mo file, default to 78 (optional), - - *encoding*: string, the encoding to use, defaults to - "default_encoding" global variable (optional), - - *check_for_duplicates*: whether to check for duplicate entries - when adding entries to the file, default: False (optional). + ``wrapwidth`` + integer, the wrap width, only useful when the ``-w`` option was + passed to xgettext (optional, default: ``78``). + + ``encoding`` + string, the encoding to use, defaults to ``default_encoding`` + global variable (optional). + + ``check_for_duplicates`` + whether to check for duplicate entries when adding entries to the + file, (optional, default: ``False``). """ list.__init__(self) # the opened file handle - self.fpath = kwargs.get('fpath') + pofile = kwargs.get('pofile', None) + if pofile and os.path.exists(pofile): + self.fpath = pofile + else: + self.fpath = kwargs.get('fpath') # the width at which lines should be wrapped self.wrapwidth = kwargs.get('wrapwidth', 78) # the file encoding @@ -298,66 +241,56 @@ self.metadata = {} self.metadata_is_fuzzy = 0 - def __str__(self): + def __unicode__(self): """ - String representation of the file. + Returns the unicode representation of the file. """ ret = [] entries = [self.metadata_as_entry()] + \ [e for e in self if not e.obsolete] for entry in entries: - ret.append(entry.__str__(self.wrapwidth)) + ret.append(entry.__unicode__(self.wrapwidth)) for entry in self.obsolete_entries(): - ret.append(entry.__str__(self.wrapwidth)) - return '\n'.join(ret) + ret.append(entry.__unicode__(self.wrapwidth)) + ret = '\n'.join(ret) + + if type(ret) != types.UnicodeType: + return unicode(ret, self.encoding) + return ret + + def __str__(self): + """ + Returns the string representation of the file. + """ + return unicode(self).encode(self.encoding) def __contains__(self, entry): """ - Overriden method to implement the membership test (in and not in). - The method considers that an entry is in the file if it finds an - entry that has the same msgid (case sensitive). - - **Keyword argument**: - - *entry*: an instance of polib._BaseEntry + Overriden ``list`` method to implement the membership test (in and + not in). + The method considers that an entry is in the file if it finds an entry + that has the same msgid (the test is **case sensitive**). - **Tests**: - >>> po = POFile() - >>> e1 = POEntry(msgid='foobar', msgstr='spam') - >>> e2 = POEntry(msgid='barfoo', msgstr='spam') - >>> e3 = POEntry(msgid='foobar', msgstr='eggs') - >>> e4 = POEntry(msgid='spameggs', msgstr='eggs') - >>> po.append(e1) - >>> po.append(e2) - >>> e1 in po - True - >>> e2 not in po - False - >>> e3 in po - True - >>> e4 in po - False + Argument: + + ``entry`` + an instance of :class:`~polib._BaseEntry`. """ return self.find(entry.msgid, by='msgid') is not None + + def __eq__(self, other): + return unicode(self) == unicode(other) def append(self, entry): """ Overriden method to check for duplicates entries, if a user tries to - add an entry that already exists, the method will raise a ValueError - exception. - - **Keyword argument**: - - *entry*: an instance of polib._BaseEntry + add an entry that is already in the file, the method will raise a + ``ValueError`` exception. - **Tests**: - >>> e1 = POEntry(msgid='foobar', msgstr='spam') - >>> e2 = POEntry(msgid='foobar', msgstr='eggs') - >>> po = POFile(check_for_duplicates=True) - >>> po.append(e1) - >>> try: - ... po.append(e2) - ... except ValueError, e: - ... unicode(e) - u'Entry "foobar" already exists' + Argument: + + ``entry`` + an instance of :class:`~polib._BaseEntry`. """ if self.check_for_duplicates and entry in self: raise ValueError('Entry "%s" already exists' % entry.msgid) @@ -366,70 +299,50 @@ def insert(self, index, entry): """ Overriden method to check for duplicates entries, if a user tries to - insert an entry that already exists, the method will raise a ValueError - exception. + add an entry that is already in the file, the method will raise a + ``ValueError`` exception. - **Keyword arguments**: - - *index*: index at which the entry should be inserted - - *entry*: an instance of polib._BaseEntry + Arguments: - **Tests**: - >>> import polib - >>> polib.check_for_duplicates = True - >>> e1 = POEntry(msgid='foobar', msgstr='spam') - >>> e2 = POEntry(msgid='barfoo', msgstr='eggs') - >>> e3 = POEntry(msgid='foobar', msgstr='eggs') - >>> po = POFile(check_for_duplicates=True) - >>> po.insert(0, e1) - >>> po.insert(1, e2) - >>> try: - ... po.insert(0, e3) - ... except ValueError, e: - ... unicode(e) - u'Entry "foobar" already exists' + ``index`` + index at which the entry should be inserted. + + ``entry`` + an instance of :class:`~polib._BaseEntry`. """ if self.check_for_duplicates and entry in self: raise ValueError('Entry "%s" already exists' % entry.msgid) super(_BaseFile, self).insert(index, entry) - def __repr__(self): - """Return the official string representation of the object.""" - return '<%s instance at %x>' % (self.__class__.__name__, id(self)) - def metadata_as_entry(self): """ - Return the metadata as an entry: - - >>> import polib - >>> po = polib.pofile('tests/test_fuzzy_header.po') - >>> unicode(po) == unicode(open('tests/test_fuzzy_header.po').read()) - True + Returns the file metadata as a :class:`~polib.POFile` instance. """ e = POEntry(msgid='') mdata = self.ordered_metadata() if mdata: strs = [] - e._multiline_str['msgstr'] = '' for name, value in mdata: # Strip whitespace off each line in a multi-line entry strs.append('%s: %s' % (name, value)) e.msgstr = '\n'.join(strs) + '\n' - e._multiline_str['msgstr'] = '__POLIB__NL__'.join( - [s + '\n' for s in strs]) if self.metadata_is_fuzzy: e.flags.append('fuzzy') return e def save(self, fpath=None, repr_method='__str__'): """ - Save the po file to file *fpath* if no file handle exists for - the object. If there's already an open file and no fpath is - provided, then the existing file is rewritten with the modified - data. + Saves the po file to ``fpath``. + If it is an existing file and no ``fpath`` is provided, then the + existing file is rewritten with the modified data. + + Keyword arguments: - **Keyword arguments**: - - *fpath*: string, full or relative path to the file. - - *repr_method*: string, the method to use for output. + ``fpath`` + string, full or relative path to the file. + + ``repr_method`` + string, the method to use for output. """ if self.fpath is None and fpath is None: raise IOError('You must provide a file path to save() method') @@ -444,38 +357,47 @@ contents = contents.decode(self.encoding) fhandle.write(contents) fhandle.close() - - def find(self, st, by='msgid'): - """ - Find entry which msgid (or property identified by the *by* - attribute) matches the string *st*. + # set the file path if not set + if self.fpath is None and fpath: + self.fpath = fpath - **Keyword arguments**: - - *st*: string, the string to search for - - *by*: string, the comparison attribute + def find(self, st, by='msgid', include_obsolete_entries=False, + msgctxt=False): + """ + Find the entry which msgid (or property identified by the ``by`` + argument) matches the string ``st``. - **Examples**: + Keyword arguments: + + ``st`` + string, the string to search for. - >>> po = pofile('tests/test_utf8.po') - >>> entry = po.find('Thursday') - >>> entry.msgstr - u'Jueves' - >>> entry = po.find('Some unexistant msgid') - >>> entry is None - True - >>> entry = po.find('Jueves', 'msgstr') - >>> entry.msgid - u'Thursday' + ``by`` + string, the property to use for comparison (default: ``msgid``). + + ``include_obsolete_entries`` + boolean, whether to also search in entries that are obsolete. + + ``msgctxt`` + string, allows to specify a specific message context for the + search. """ - for e in self: + if include_obsolete_entries: + entries = self[:] + else: + entries = [e for e in self if not e.obsolete] + for e in entries: if getattr(e, by) == st: + if msgctxt and e.msgctxt != msgctxt: + continue return e return None def ordered_metadata(self): """ - Convenience method that return the metadata ordered. The return - value is list of tuples (metadata name, metadata_value). + Convenience method that returns an ordered version of the metadata + dictionnary. The return value is list of tuples (metadata name, + metadata_value). """ # copy the dict first metadata = self.metadata.copy() @@ -497,9 +419,10 @@ ordered_data.append((data, value)) except KeyError: pass - # the rest of the metadata won't be ordered there are no specs for this + # the rest of the metadata will be alphabetically ordered since there + # are no specs for this AFAIK keys = metadata.keys() - list(keys).sort() + keys.sort() for data in keys: value = metadata[data] ordered_data.append((data, value)) @@ -507,45 +430,51 @@ def to_binary(self): """ - Return the mofile binary representation. + Return the binary representation of the file. """ - import array - import struct - import types offsets = [] entries = self.translated_entries() # the keys are sorted in the .mo file def cmp(_self, other): - if _self.msgid > other.msgid: + # msgfmt compares entries with msgctxt if it exists + self_msgid = _self.msgctxt and _self.msgctxt or _self.msgid + other_msgid = other.msgctxt and other.msgctxt or other.msgid + if self_msgid > other_msgid: return 1 - elif _self.msgid < other.msgid: + elif self_msgid < other_msgid: return -1 else: return 0 # add metadata entry entries.sort(cmp) mentry = self.metadata_as_entry() - mentry.msgstr = mentry.msgstr.replace('\\n', '').lstrip() + #mentry.msgstr = mentry.msgstr.replace('\\n', '').lstrip() entries = [mentry] + entries entries_len = len(entries) ids, strs = '', '' for e in entries: # For each string, we need size and file offset. Each string is # NUL terminated; the NUL does not count into the size. + msgid = '' + if e.msgctxt: + # Contexts are stored by storing the concatenation of the + # context, a <EOT> byte, and the original string + msgid = self._encode(e.msgctxt + '\4') if e.msgid_plural: indexes = e.msgstr_plural.keys() indexes.sort() msgstr = [] for index in indexes: msgstr.append(e.msgstr_plural[index]) - msgid = self._encode(e.msgid + '\0' + e.msgid_plural) + msgid += self._encode(e.msgid + '\0' + e.msgid_plural) msgstr = self._encode('\0'.join(msgstr)) else: - msgid = self._encode(e.msgid) + msgid += self._encode(e.msgid) msgstr = self._encode(e.msgstr) offsets.append((len(ids), len(msgid), len(strs), len(msgstr))) ids += msgid + '\0' strs += msgstr + '\0' + # The header is 7 32-bit unsigned integers. keystart = 7*4+16*entries_len # and the values start after the keys @@ -558,22 +487,31 @@ koffsets += [l1, o1+keystart] voffsets += [l2, o2+valuestart] offsets = koffsets + voffsets - output = struct.pack("IIIIIII", - 0x950412de, # Magic number - 0, # Version - entries_len, # # of entries - 7*4, # start of key index - 7*4+entries_len*8, # start of value index - 0, 0) # size and offset of hash table - output += array.array("I", offsets).tostring() + # check endianness for magic number + if struct.pack('@h', 1) == struct.pack('<h', 1): + magic_number = MOFile.LITTLE_ENDIAN + else: + magic_number = MOFile.BIG_ENDIAN + + output = struct.pack( + "Iiiiiii", + magic_number, # Magic number + 0, # Version + entries_len, # # of entries + 7*4, # start of key index + 7*4+entries_len*8, # start of value index + 0, keystart # size and offset of hash table + # Important: we don't use hash tables + ) + output += array.array("i", offsets).tostring() output += ids output += strs return output def _encode(self, mixed): """ - Encode the given argument with the file encoding if the type is unicode - and return the encoded string. + Encodes the given ``mixed`` argument with the file encoding if and + only if it's an unicode string and returns the encoded string. """ if type(mixed) == types.UnicodeType: return mixed.encode(self.encoding) @@ -583,88 +521,43 @@ # class POFile {{{ class POFile(_BaseFile): - ''' + """ Po (or Pot) file reader/writer. - POFile objects inherit the list objects methods. - - **Example**: + This class inherits the :class:`~polib._BaseFile` class and, by extension, + the python ``list`` type. + """ - >>> po = POFile() - >>> entry1 = POEntry( - ... msgid="Some english text", - ... msgstr="Un texte en anglais" - ... ) - >>> entry1.occurrences = [('testfile', 12),('another_file', 1)] - >>> entry1.comment = "Some useful comment" - >>> entry2 = POEntry( - ... msgid="Peace in some languages", - ... msgstr="Pace سلام שלום Hasîtî 和平" - ... ) - >>> entry2.occurrences = [('testfile', 15),('another_file', 5)] - >>> entry2.comment = "Another useful comment" - >>> entry3 = POEntry( - ... msgid='Some entry with quotes " \\"', - ... msgstr='Un message unicode avec des quotes " \\"' - ... ) - >>> entry3.comment = "Test string quoting" - >>> po.append(entry1) - >>> po.append(entry2) - >>> po.append(entry3) - >>> po.header = "Some Header" - >>> print(po) - # Some Header - msgid "" - msgstr "" - <BLANKLINE> - #. Some useful comment - #: testfile:12 another_file:1 - msgid "Some english text" - msgstr "Un texte en anglais" - <BLANKLINE> - #. Another useful comment - #: testfile:15 another_file:5 - msgid "Peace in some languages" - msgstr "Pace سلام שלום Hasîtî 和平" - <BLANKLINE> - #. Test string quoting - msgid "Some entry with quotes \\" \\"" - msgstr "Un message unicode avec des quotes \\" \\"" - <BLANKLINE> - ''' - - def __str__(self): - """Return the string representation of the po file""" + def __unicode__(self): + """ + Returns the unicode representation of the po file. + """ ret, headers = '', self.header.split('\n') for header in headers: if header[:1] in [',', ':']: ret += '#%s\n' % header else: ret += '# %s\n' % header - return ret + _BaseFile.__str__(self) + + if type(ret) != types.UnicodeType: + ret = unicode(ret, self.encoding) + + return ret + _BaseFile.__unicode__(self) def save_as_mofile(self, fpath): """ - Save the binary representation of the file to *fpath*. + Saves the binary representation of the file to given ``fpath``. - **Keyword arguments**: - - *fpath*: string, full or relative path to the file. + Keyword argument: + + ``fpath`` + string, full or relative path to the mo file. """ _BaseFile.save(self, fpath, 'to_binary') def percent_translated(self): """ - Convenience method that return the percentage of translated + Convenience method that returns the percentage of translated messages. - - **Example**: - - >>> import polib - >>> po = polib.pofile('tests/test_pofile_helpers.po') - >>> po.percent_translated() - 50 - >>> po = POFile() - >>> po.percent_translated() - 100 """ total = len([e for e in self if not e.obsolete]) if total == 0: @@ -674,91 +567,52 @@ def translated_entries(self): """ - Convenience method that return a list of translated entries. - - **Example**: - - >>> import polib - >>> po = polib.pofile('tests/test_pofile_helpers.po') - >>> len(po.translated_entries()) - 6 + Convenience method that returns the list of translated entries. """ return [e for e in self if e.translated()] def untranslated_entries(self): """ - Convenience method that return a list of untranslated entries. - - **Example**: - - >>> import polib - >>> po = polib.pofile('tests/test_pofile_helpers.po') - >>> len(po.untranslated_entries()) - 4 + Convenience method that returns the list of untranslated entries. """ return [e for e in self if not e.translated() and not e.obsolete \ and not 'fuzzy' in e.flags] def fuzzy_entries(self): """ - Convenience method that return the list of 'fuzzy' entries. - - **Example**: - - >>> import polib - >>> po = polib.pofile('tests/test_pofile_helpers.po') - >>> len(po.fuzzy_entries()) - 2 + Convenience method that returns the list of fuzzy entries. """ return [e for e in self if 'fuzzy' in e.flags] def obsolete_entries(self): """ - Convenience method that return the list of obsolete entries. - - **Example**: - - >>> import polib - >>> po = polib.pofile('tests/test_pofile_helpers.po') - >>> len(po.obsolete_entries()) - 4 + Convenience method that returns the list of obsolete entries. """ return [e for e in self if e.obsolete] def merge(self, refpot): """ - XXX this could not work if encodings are different, needs thinking - and general refactoring of how polib handles encoding... - - Convenience method that merge the current pofile with the pot file + Convenience method that merges the current pofile with the pot file provided. It behaves exactly as the gettext msgmerge utility: - - comments of this file will be preserved, but extracted comments - and occurrences will be discarded - - any translations or comments in the file will be discarded, - however dot comments and file positions will be preserved - - **Keyword argument**: - - *refpot*: object POFile, the reference catalog. + * comments of this file will be preserved, but extracted comments and + occurrences will be discarded; + * any translations or comments in the file will be discarded, however, + dot comments and file positions will be preserved; + * the fuzzy flags are preserved. - **Example**: + Keyword argument: - >>> import polib - >>> refpot = polib.pofile('tests/test_merge.pot') - >>> po = polib.pofile('tests/test_merge_before.po') - >>> po.merge(refpot) - >>> expected_po = polib.pofile('tests/test_merge_after.po') - >>> unicode(po) == unicode(expected_po) - True + ``refpot`` + object POFile, the reference catalog. """ for entry in refpot: - e = self.find(entry.msgid) + e = self.find(entry.msgid, include_obsolete_entries=True) if e is None: e = POEntry() self.append(e) e.merge(entry) - # ok, now we must "obsolete" entries that are not in the refpot - # anymore + # ok, now we must "obsolete" entries that are not in the refpot anymore for entry in self: if refpot.find(entry.msgid) is None: entry.obsolete = True @@ -767,48 +621,18 @@ # class MOFile {{{ class MOFile(_BaseFile): - ''' + """ Mo file reader/writer. - MOFile objects inherit the list objects methods. - - **Example**: - - >>> mo = MOFile() - >>> entry1 = POEntry( - ... msgid="Some english text", - ... msgstr="Un texte en anglais" - ... ) - >>> entry2 = POEntry( - ... msgid="I need my dirty cheese", - ... msgstr="Je veux mon sale fromage" - ... ) - >>> entry3 = MOEntry( - ... msgid='Some entry with quotes " \\"', - ... msgstr='Un message unicode avec des quotes " \\"' - ... ) - >>> mo.append(entry1) - >>> mo.append(entry2) - >>> mo.append(entry3) - >>> print(mo) - msgid "" - msgstr "" - <BLANKLINE> - msgid "Some english text" - msgstr "Un texte en anglais" - <BLANKLINE> - msgid "I need my dirty cheese" - msgstr "Je veux mon sale fromage" - <BLANKLINE> - msgid "Some entry with quotes \\" \\"" - msgstr "Un message unicode avec des quotes \\" \\"" - <BLANKLINE> - ''' + This class inherits the :class:`~polib._BaseFile` class and, by + extension, the python ``list`` type. + """ + BIG_ENDIAN = 0xde120495 + LITTLE_ENDIAN = 0x950412de def __init__(self, *args, **kwargs): """ - MOFile constructor. Mo files have two other properties: - - magic_number: the magic_number of the binary file, - - version: the version of the mo spec. + Constructor, accepts all keywords arguments accepted by + :class:`~polib._BaseFile` class. """ _BaseFile.__init__(self, *args, **kwargs) self.magic_number = None @@ -816,19 +640,23 @@ def save_as_pofile(self, fpath): """ - Save the string representation of the file to *fpath*. + Saves the mofile as a pofile to ``fpath``. - **Keyword argument**: - - *fpath*: string, full or relative path to the file. + Keyword argument: + + ``fpath`` + string, full or relative path to the file. """ _BaseFile.save(self, fpath) - def save(self, fpath): + def save(self, fpath=None): """ - Save the binary representation of the file to *fpath*. + Saves the mofile to ``fpath``. - **Keyword argument**: - - *fpath*: string, full or relative path to the file. + Keyword argument: + + ``fpath`` + string, full or relative path to the file. """ _BaseFile.save(self, fpath, 'to_binary') @@ -867,29 +695,47 @@ class _BaseEntry(object): """ - Base class for POEntry or MOEntry objects. - This class must *not* be instanciated directly. + Base class for :class:`~polib.POEntry` and :class:`~polib.MOEntry` classes. + This class should **not** be instanciated directly. """ def __init__(self, *args, **kwargs): - """Base Entry constructor.""" + """ + Constructor, accepts the following keyword arguments: + + ``msgid`` + string, the entry msgid. + + ``msgstr`` + string, the entry msgstr. + + ``msgid_plural`` + string, the entry msgid_plural. + + ``msgstr_plural`` + list, the entry msgstr_plural lines. + + ``msgctxt`` + string, the entry context (msgctxt). + + ``obsolete`` + bool, whether the entry is "obsolete" or not. + + ``encoding`` + string, the encoding to use, defaults to ``default_encoding`` + global variable (optional). + """ self.msgid = kwargs.get('msgid', '') self.msgstr = kwargs.get('msgstr', '') self.msgid_plural = kwargs.get('msgid_plural', '') self.msgstr_plural = kwargs.get('msgstr_plural', {}) + self.msgctxt = kwargs.get('msgctxt', None) self.obsolete = kwargs.get('obsolete', False) self.encoding = kwargs.get('encoding', default_encoding) - self.msgctxt = kwargs.get('msgctxt', None) - self._multiline_str = {} - def __repr__(self): - """Return the official string representation of the object.""" - return '<%s instance at %x>' % (self.__class__.__name__, id(self)) - - def __str__(self, wrapwidth=78): + def __unicode__(self, wrapwidth=78): """ - Common string representation of the POEntry and MOEntry - objects. + Returns the unicode representation of the entry. """ if self.obsolete: delflag = '#~ ' @@ -898,12 +744,12 @@ ret = [] # write the msgctxt if any if self.msgctxt is not None: - ret += self._str_field("msgctxt", delflag, "", self.msgctxt) + ret += self._str_field("msgctxt", delflag, "", self.msgctxt, wrapwidth) # write the msgid - ret += self._str_field("msgid", delflag, "", self.msgid) + ret += self._str_field("msgid", delflag, "", self.msgid, wrapwidth) # write the msgid_plural if any if self.msgid_plural: - ret += self._str_field("msgid_plural", delflag, "", self.msgid_plural) + ret += self._str_field("msgid_plural", delflag, "", self.msgid_plural, wrapwidth) if self.msgstr_plural: # write the msgstr_plural if any msgstrs = self.msgstr_plural @@ -912,23 +758,51 @@ for index in keys: msgstr = msgstrs[index] plural_index = '[%s]' % index - ret += self._str_field("msgstr", delflag, plural_index, msgstr) + ret += self._str_field("msgstr", delflag, plural_index, msgstr, wrapwidth) else: # otherwise write the msgstr - ret += self._str_field("msgstr", delflag, "", self.msgstr) + ret += self._str_field("msgstr", delflag, "", self.msgstr, wrapwidth) ret.append('') - return '\n'.join(ret) + ret = '\n'.join(ret) + + if type(ret) != types.UnicodeType: + return unicode(ret, self.encoding) + return ret + + def __str__(self): + """ + Returns the string representation of the entry. + """ + return unicode(self).encode(self.encoding) + + def __eq__(self, other): + return unicode(self) == unicode(other) - def _str_field(self, fieldname, delflag, plural_index, field): - if (fieldname + plural_index) in self._multiline_str: - field = self._multiline_str[fieldname + plural_index] - lines = [''] + field.split('__POLIB__NL__') + def _str_field(self, fieldname, delflag, plural_index, field, wrapwidth=78): + lines = field.splitlines(True) + if len(lines) > 1: + lines = [''] + lines # start with initial empty line else: - lines = field.splitlines(True) - if len(lines) > 1: - lines = ['']+lines # start with initial empty line + escaped_field = escape(field) + specialchars_count = 0 + for c in ['\\', '\n', '\r', '\t', '"']: + specialchars_count += field.count(c) + # comparison must take into account fieldname length + one space + # + 2 quotes (eg. msgid "<string>") + flength = len(fieldname) + 3 + if plural_index: + flength += len(plural_index) + real_wrapwidth = wrapwidth - flength + specialchars_count + if wrapwidth > 0 and len(field) > real_wrapwidth: + # Wrap the line but take field name into account + lines = [''] + [unescape(item) for item in wrap( + escaped_field, + wrapwidth - 2, # 2 for quotes "" + drop_whitespace=False, + break_long_words=False + )] else: - lines = [field] # needed for the empty string case + lines = [field] if fieldname.startswith('previous_'): # quick and dirty trick to get the real field name fieldname = fieldname[9:] @@ -945,50 +819,33 @@ class POEntry(_BaseEntry): """ Represents a po file entry. - - **Examples**: - - >>> entry = POEntry(msgid='Welcome', msgstr='Bienvenue') - >>> entry.occurrences = [('welcome.py', 12), ('anotherfile.py', 34)] - >>> print(entry) - #: welcome.py:12 anotherfile.py:34 - msgid "Welcome" - msgstr "Bienvenue" - <BLANKLINE> - >>> entry = POEntry() - >>> entry.occurrences = [('src/some-very-long-filename-that-should-not-be-wrapped-even-if-it-is-larger-than-the-wrap-limit.c', 32), ('src/eggs.c', 45)] - >>> entry.comment = 'A plural translation. This is a very very very long line please do not wrap, this is just for testing comment wrapping...' - >>> entry.tcomment = 'A plural translation. This is a very very very long line please do not wrap, this is just for testing comment wrapping...' - >>> entry.flags.append('c-format') - >>> entry.previous_msgctxt = '@somecontext' - >>> entry.previous_msgid = 'I had eggs but no spam !' - >>> entry.previous_msgid_plural = 'I had eggs and %d spam !' - >>> entry.msgctxt = '@somenewcontext' - >>> entry.msgid = 'I have spam but no egg !' - >>> entry.msgid_plural = 'I have spam and %d eggs !' - >>> entry.msgstr_plural[0] = "J'ai du jambon mais aucun oeuf !" - >>> entry.msgstr_plural[1] = "J'ai du jambon et %d oeufs !" - >>> print(entry) - #. A plural translation. This is a very very very long line please do not - #. wrap, this is just for testing comment wrapping... - # A plural translation. This is a very very very long line please do not wrap, - # this is just for testing comment wrapping... - #: src/some-very-long-filename-that-should-not-be-wrapped-even-if-it-is-larger-than-the-wrap-limit.c:32 - #: src/eggs.c:45 - #, c-format - #| msgctxt "@somecontext" - #| msgid "I had eggs but no spam !" - #| msgid_plural "I had eggs and %d spam !" - msgctxt "@somenewcontext" - msgid "I have spam but no egg !" - msgid_plural "I have spam and %d eggs !" - msgstr[0] "J'ai du jambon mais aucun oeuf !" - msgstr[1] "J'ai du jambon et %d oeufs !" - <BLANKLINE> """ def __init__(self, *args, **kwargs): - """POEntry constructor.""" + """ + Constructor, accepts the following keyword arguments: + + ``comment`` + string, the entry comment. + + ``tcomment`` + string, the entry translator comment. + + ``occurrences`` + list, the entry occurrences. + + ``flags`` + list, the entry flags. + + ``previous_msgctxt`` + string, the entry previous context. + + ``previous_msgid`` + string, the entry previous msgid. + + ``previous_msgid_plural`` + string, the entry previous msgid_plural. + """ _BaseEntry.__init__(self, *args, **kwargs) self.comment = kwargs.get('comment', '') self.tcomment = kwargs.get('tcomment', '') @@ -998,33 +855,31 @@ self.previous_msgid = kwargs.get('previous_msgid', None) self.previous_msgid_plural = kwargs.get('previous_msgid_plural', None) - def __str__(self, wrapwidth=78): + def __unicode__(self, wrapwidth=78): """ - Return the string representation of the entry. + Returns the unicode representation of the entry. """ if self.obsolete: - return _BaseEntry.__str__(self) + return _BaseEntry.__unicode__(self, wrapwidth) + ret = [] - # comment first, if any (with text wrapping as xgettext does) - if self.comment != '': - for comment in self.comment.split('\n'): - if wrapwidth > 0 and len(comment) > wrapwidth-3: - ret += textwrap.wrap(comment, wrapwidth, - initial_indent='#. ', - subsequent_indent='#. ', - break_long_words=False) - else: - ret.append('#. %s' % comment) - # translator comment, if any (with text wrapping as xgettext does) - if self.tcomment != '': - for tcomment in self.tcomment.split('\n'): - if wrapwidth > 0 and len(tcomment) > wrapwidth-2: - ret += textwrap.wrap(tcomment, wrapwidth, - initial_indent='# ', - subsequent_indent='# ', - break_long_words=False) - else: - ret.append('# %s' % tcomment) + # comments first, if any (with text wrapping as xgettext does) + comments = [('comment', '#. '), ('tcomment', '# ')] + for c in comments: + val = getattr(self, c[0]) + if val: + for comment in val.split('\n'): + if wrapwidth > 0 and len(comment) + len(c[1]) > wrapwidth: + ret += wrap( + comment, + wrapwidth, + initial_indent=c[1], + subsequent_indent=c[1], + break_long_words=False + ) + else: + ret.append('%s%s' % (c[1], comment)) + # occurrences (with text wrapping as xgettext does) if self.occurrences: filelist = [] @@ -1034,79 +889,43 @@ else: filelist.append(fpath) filestr = ' '.join(filelist) - if wrapwidth > 0 and len(filestr)+3 > wrapwidth: - # XXX textwrap split words that contain hyphen, this is not + if wrapwidth > 0 and len(filestr) + 3 > wrapwidth: + # textwrap split words that contain hyphen, this is not # what we want for filenames, so the dirty hack is to # temporally replace hyphens with a char that a file cannot # contain, like "*" - lines = textwrap.wrap(filestr.replace('-', '*'), - wrapwidth, - initial_indent='#: ', - subsequent_indent='#: ', - break_long_words=False) - # end of the replace hack - for line in lines: - ret.append(line.replace('*', '-')) + ret += [l.replace('*', '-') for l in wrap( + filestr.replace('-', '*'), + wrapwidth, + initial_indent='#: ', + subsequent_indent='#: ', + break_long_words=False + )] else: - ret.append('#: '+filestr) - # flags + ret.append('#: ' + filestr) + + # flags (TODO: wrapping ?) if self.flags: - flags = [] - for flag in self.flags: - flags.append(flag) - ret.append('#, %s' % ', '.join(flags)) + ret.append('#, %s' % ', '.join(self.flags)) # previous context and previous msgid/msgid_plural - if self.previous_msgctxt: - ret += self._str_field("previous_msgctxt", "#| ", "", - self.previous_msgctxt) - if self.previous_msgid: - ret += self._str_field("previous_msgid", "#| ", "", - self.previous_msgid) - if self.previous_msgid_plural: - ret += self._str_field("previous_msgid_plural", "#| ", "", - self.previous_msgid_plural) + fields = ['previous_msgctxt', 'previous_msgid', 'previous_msgid_plural'] + for f in fields: + val = getattr(self, f) + if val: + ret += self._str_field(f, "#| ", "", val, wrapwidth) - ret.append(_BaseEntry.__str__(self)) - return '\n'.join(ret) + ret.append(_BaseEntry.__unicode__(self, wrapwidth)) + ret = '\n'.join(ret) + + if type(ret) != types.UnicodeType: + return unicode(ret, self.encoding) + return ret def __cmp__(self, other): - ''' + """ Called by comparison operations if rich comparison is not defined. - - **Tests**: - >>> a = POEntry(msgid='a', occurrences=[('b.py', 1), ('b.py', 3)]) - >>> b = POEntry(msgid='b', occurrences=[('b.py', 1), ('b.py', 3)]) - >>> c1 = POEntry(msgid='c1', occurrences=[('a.py', 1), ('b.py', 1)]) - >>> c2 = POEntry(msgid='c2', occurrences=[('a.py', 1), ('a.py', 3)]) - >>> po = POFile() - >>> po.append(a) - >>> po.append(b) - >>> po.append(c1) - >>> po.append(c2) - >>> po.sort() - >>> print(po) - # - msgid "" - msgstr "" - <BLANKLINE> - #: a.py:1 a.py:3 - msgid "c2" - msgstr "" - <BLANKLINE> - #: a.py:1 b.py:1 - msgid "c1" - msgstr "" - <BLANKLINE> - #: b.py:1 b.py:3 - msgid "a" - msgstr "" - <BLANKLINE> - #: b.py:1 b.py:3 - msgid "b" - msgstr "" - <BLANKLINE> - ''' + """ def compare_occurrences(a, b): """ Compare an entry occurrence with another one. @@ -1153,7 +972,8 @@ def translated(self): """ - Return True if the entry has been translated or False. + Returns ``True`` if the entry has been translated or ``False`` + otherwise. """ if self.obsolete or 'fuzzy' in self.flags: return False @@ -1170,11 +990,19 @@ """ Merge the current entry with the given pot entry. """ - self.msgid = other.msgid - self.occurrences = other.occurrences - self.comment = other.comment - self.flags = other.flags + self.msgid = other.msgid + self.msgctxt = other.msgctxt + self.occurrences = other.occurrences + self.comment = other.comment + fuzzy = 'fuzzy' in self.flags + self.flags = other.flags[:] # clone flags + if fuzzy: + self.flags.append('fuzzy') self.msgid_plural = other.msgid_plural + self.obsolete = other.obsolete + self.previous_msgctxt = other.previous_msgctxt + self.previous_msgid = other.previous_msgid + self.previous_msgid_plural = other.previous_msgid_plural if other.msgstr_plural: for pos in other.msgstr_plural: try: @@ -1189,23 +1017,8 @@ class MOEntry(_BaseEntry): """ Represents a mo file entry. - - **Examples**: - - >>> entry = MOEntry() - >>> entry.msgid = 'translate me !' - >>> entry.msgstr = 'traduisez moi !' - >>> print(entry) - msgid "translate me !" - msgstr "traduisez moi !" - <BLANKLINE> """ - - def __str__(self, wrapwidth=78): - """ - Return the string representation of the entry. - """ - return _BaseEntry.__str__(self, wrapwidth) + pass # }}} # class _POFileParser {{{ @@ -1216,28 +1029,37 @@ file format. """ - def __init__(self, fpath, *args, **kwargs): + def __init__(self, pofile, *args, **kwargs): """ Constructor. - **Arguments**: - - *fpath*: string, path to the po file - - *encoding*: string, the encoding to use, defaults to - "default_encoding" global variable (optional), - - *check_for_duplicates*: whether to check for duplicate entries - when adding entries to the file, default: False (optional). + Keyword arguments: + + ``pofile`` + string, path to the po file or its content + + ``encoding`` + string, the encoding to use, defaults to ``default_encoding`` + global variable (optional). + + ``check_for_duplicates`` + whether to check for duplicate entries when adding entries to the + file (optional, default: ``False``). """ enc = kwargs.get('encoding', default_encoding) - check_dup = kwargs.get('check_for_duplicates', False) - try: - self.fhandle = codecs.open(fpath, 'rU', enc) - except LookupError: - enc = default_encoding - self.fhandle = codecs.open(fpath, 'rU', enc) + if os.path.exists(pofile): + try: + self.fhandle = codecs.open(pofile, 'rU', enc) + except LookupError: + enc = default_encoding + self.fhandle = codecs.open(pofile, 'rU', enc) + else: + self.fhandle = pofile.splitlines() + self.instance = POFile( - fpath=fpath, + pofile=pofile, encoding=enc, - check_for_duplicates=check_dup + check_for_duplicates=kwargs.get('check_for_duplicates', False) ) self.transitions = {} self.current_entry = POEntry() @@ -1289,59 +1111,103 @@ Run the state machine, parse the file line by line and call process() with the current matched symbol. """ - i, lastlen = 1, 0 + i = 0 + + keywords = { + 'msgctxt': 'CT', + 'msgid': 'MI', + 'msgstr': 'MS', + 'msgid_plural': 'MP', + } + prev_keywords = { + 'msgid_plural': 'PP', + 'msgid': 'PM', + 'msgctxt': 'PC', + } + for line in self.fhandle: + i += 1 line = line.strip() if line == '': - i = i+1 continue - if line[:3] == '#~ ': - line = line[3:] + + tokens = line.split(None, 2) + nb_tokens = len(tokens) + + if tokens[0] == '#~' and nb_tokens > 1: + line = line[3:].strip() + tokens = tokens[1:] + nb_tokens -= 1 self.entry_obsolete = 1 else: self.entry_obsolete = 0 + + # Take care of keywords like + # msgid, msgid_plural, msgctxt & msgstr. + if tokens[0] in keywords and nb_tokens > 1: + line = line[len(tokens[0]):].lstrip() + self.current_token = line + self.process(keywords[tokens[0]], i) + continue + self.current_token = line - if line[:2] == '#:': + + if tokens[0] == '#:' and nb_tokens > 1: # we are on a occurrences line self.process('OC', i) - elif line[:9] == 'msgctxt "': - # we are on a msgctxt - self.process('CT', i) - elif line[:7] == 'msgid "': - # we are on a msgid - self.process('MI', i) - elif line[:8] == 'msgstr "': - # we are on a msgstr - self.process('MS', i) - elif line[:1] == '"' or line[:4] == '#| "': - # we are on a continuation line or some metadata + + elif line[:1] == '"': + # we are on a continuation line self.process('MC', i) - elif line[:14] == 'msgid_plural "': - # we are on a msgid plural - self.process('MP', i) + elif line[:7] == 'msgstr[': # we are on a msgstr plural self.process('MX', i) - elif line[:3] == '#, ': + + elif tokens[0] == '#,' and nb_tokens > 1: # we are on a flags line self.process('FL', i) - elif line[:2] == '# ' or line == '#': - if line == '#': line = line + ' ' + + elif tokens[0] == '#': + if line == '#': line += ' ' # we are on a translator comment line self.process('TC', i) - elif line[:2] == '#.': + + elif tokens[0] == '#.' and nb_tokens > 1: # we are on a generated comment line self.process('GC', i) - elif line[:15] == '#| msgid_plural': - # we are on a previous msgid_plural - self.process('PP', i) - elif line[:8] == '#| msgid': - self.process('PM', i) - # we are on a previous msgid - elif line[:10] == '#| msgctxt': - # we are on a previous msgctxt - self.process('PC', i) - i = i+1 + + elif tokens[0] == '#|': + if nb_tokens < 2: + self.process('??', i) + continue + + # Remove the marker and any whitespace right after that. + line = line[2:].lstrip() + self.current_token = line + + if tokens[1].startswith('"'): + # Continuation of previous metadata. + self.process('MC', i) + continue + + if nb_tokens == 2: + # Invalid continuation line. + self.process('??', i) + + # we are on a "previous translation" comment line, + if tokens[1] not in prev_keywords: + # Unknown keyword in previous translation comment. + self.process('??', i) + + # Remove the keyword and any whitespace + # between it and the starting quote. + line = line[len(tokens[1]):].lstrip() + self.current_token = line + self.process(prev_keywords[tokens[1]], i) + + else: + self.process('??', i) if self.current_entry: # since entries are added when another entry is found, we must add @@ -1363,17 +1229,24 @@ if key is not None: self.instance.metadata[key] += '\n'+ msg.strip() # close opened file - self.fhandle.close() + if isinstance(self.fhandle, file): + self.fhandle.close() return self.instance def add(self, symbol, states, next_state): """ Add a transition to the state machine. + Keywords arguments: - symbol -- string, the matched token (two chars symbol) - states -- list, a list of states (two chars symbols) - next_state -- the next state the fsm will have after the action + ``symbol`` + string, the matched token (two chars symbol). + + ``states`` + list, a list of states (two chars symbols). + + ``next_state`` + the next state the fsm will have after the action. """ for state in states: action = getattr(self, 'handle_%s' % next_state.lower()) @@ -1385,8 +1258,12 @@ symbol provided. Keywords arguments: - symbol -- string, the matched token (two chars symbol) - linenum -- integer, the current line number of the parsed file + + ``symbol`` + string, the matched token (two chars symbol). + + ``linenum`` + integer, the current line number of the parsed file. """ try: (action, state) = self.transitions[(symbol, self.current_state)] @@ -1456,7 +1333,7 @@ self.instance.append(self.current_entry) self.current_entry = POEntry() self.current_entry.previous_msgid_plural = \ - unescape(self.current_token[17:-1]) + unescape(self.current_token[1:-1]) return True def handle_pm(self): @@ -1465,7 +1342,7 @@ self.instance.append(self.current_entry) self.current_entry = POEntry() self.current_entry.previous_msgid = \ - unescape(self.current_token[10:-1]) + unescape(self.current_token[1:-1]) return True def handle_pc(self): @@ -1474,7 +1351,7 @@ self.instance.append(self.current_entry) self.current_entry = POEntry() self.current_entry.previous_msgctxt = \ - unescape(self.current_token[12:-1]) + unescape(self.current_token[1:-1]) return True def handle_ct(self): @@ -1482,7 +1359,7 @@ if self.current_state in ['MC', 'MS', 'MX']: self.instance.append(self.current_entry) self.current_entry = POEntry() - self.current_entry.msgctxt = unescape(self.current_token[9:-1]) + self.current_entry.msgctxt = unescape(self.current_token[1:-1]) return True def handle_mi(self): @@ -1491,17 +1368,17 @@ self.instance.append(self.current_entry) self.current_entry = POEntry() self.current_entry.obsolete = self.entry_obsolete - self.current_entry.msgid = unescape(self.current_token[7:-1]) + self.current_entry.msgid = unescape(self.current_token[1:-1]) return True def handle_mp(self): """Handle a msgid plural.""" - self.current_entry.msgid_plural = unescape(self.current_token[14:-1]) + self.current_entry.msgid_plural = unescape(self.current_token[1:-1]) return True def handle_ms(self): """Handle a msgstr.""" - self.current_entry.msgstr = unescape(self.current_token[8:-1]) + self.current_entry.msgstr = unescape(self.current_token[1:-1]) return True def handle_mx(self): @@ -1541,10 +1418,6 @@ typ = 'previous_msgctxt' token = token[3:] self.current_entry.previous_msgctxt += token - if typ not in self.current_entry._multiline_str: - self.current_entry._multiline_str[typ] = token - else: - self.current_entry._multiline_str[typ] += "__POLIB__NL__" + token # don't change the current state return False @@ -1555,43 +1428,41 @@ """ A class to parse binary mo files. """ - BIG_ENDIAN = 0xde120495 - LITTLE_ENDIAN = 0x950412de - def __init__(self, fpath, *args, **kwargs): + def __init__(self, mofile, *args, **kwargs): """ Constructor. - **Arguments**: - - *fpath*: string, path to the po file - - *encoding*: string, the encoding to use, defaults to - "default_encoding" global variable (optional), - - *check_for_duplicates*: whether to check for duplicate entries - when adding entries to the file, default: False (optional). + Keyword arguments: + + ``mofile`` + string, path to the mo file or its content + + ``encoding`` + string, the encoding to use, defaults to ``default_encoding`` + global variable (optional). + + ``check_for_duplicates`` + whether to check for duplicate entries when adding entries to the + file (optional, default: ``False``). """ - enc = kwargs.get('encoding', default_encoding) - check_dup = kwargs.get('check_for_duplicates', False) - self.fhandle = open(fpath, 'rb') + self.fhandle = open(mofile, 'rb') self.instance = MOFile( - fpath=fpath, - encoding=enc, - check_for_duplicates=check_dup + fpath=mofile, + encoding=kwargs.get('encoding', default_encoding), + check_for_duplicates=kwargs.get('check_for_duplicates', False) ) - def parse_magicnumber(self): - """ - Parse the magic number and raise an exception if not valid. - """ - def parse(self): """ Build the instance with the file handle provided in the constructor. """ + # parse magic number magic_number = self._readbinary('<I', 4) - if magic_number == self.LITTLE_ENDIAN: + if magic_number == MOFile.LITTLE_ENDIAN: ii = '<II' - elif magic_number == self.BIG_ENDIAN: + elif magic_number == MOFile.BIG_ENDIAN: ii = '>II' else: raise IOError('Invalid mo file, magic number is incorrect !') @@ -1630,18 +1501,35 @@ # test if we have a plural entry msgid_tokens = msgid.split('\0') if len(msgid_tokens) > 1: - entry = MOEntry( + entry = self._build_entry( msgid=msgid_tokens[0], msgid_plural=msgid_tokens[1], - msgstr_plural=dict((k,v) for k,v in \ - enumerate(msgstr.split('\0'))) + msgstr_plural=dict((k,v) for k,v in enumerate(msgstr.split('\0'))) ) else: - entry = MOEntry(msgid=msgid, msgstr=msgstr) + entry = self._build_entry(msgid=msgid, msgstr=msgstr) self.instance.append(entry) # close opened file self.fhandle.close() return self.instance + + def _build_entry(self, msgid, msgstr=None, msgid_plural=None, + msgstr_plural=None): + msgctxt_msgid = msgid.split('\x04') + if len(msgctxt_msgid) > 1: + kwargs = { + 'msgctxt': msgctxt_msgid[0], + 'msgid' : msgctxt_msgid[1], + } + else: + kwargs = {'msgid': msgid} + if msgstr: + kwargs['msgstr'] = msgstr + if msgid_plural: + kwargs['msgid_plural'] = msgid_plural + if msgstr_plural: + kwargs['msgstr_plural'] = msgstr_plural + return MOEntry(**kwargs) def _readbinary(self, fmt, numbytes): """ @@ -1655,26 +1543,97 @@ return tup # }}} -# __main__ {{{ +# class TextWrapper {{{ -if __name__ == '__main__': +class TextWrapper(textwrap.TextWrapper): """ - **Main function**:: - - to **test** the module just run: *python polib.py [-v]* - - to **profile** the module: *python polib.py -p <some_pofile.po>* + Subclass of textwrap.TextWrapper that backport the + drop_whitespace option. """ - import sys - if len(sys.argv) > 2 and sys.argv[1] == '-p': - def test(f): - if f.endswith('po'): - p = pofile(f) + def __init__(self, *args, **kwargs): + drop_whitespace = kwargs.pop('drop_whitespace', True) + textwrap.TextWrapper.__init__(self, *args, **kwargs) + self.drop_whitespace = drop_whitespace + + def _wrap_chunks(self, chunks): + """_wrap_chunks(chunks : [string]) -> [string] + + Wrap a sequence of text chunks and return a list of lines of + length 'self.width' or less. (If 'break_long_words' is false, + some lines may be longer than this.) Chunks correspond roughly + to words and the whitespace between them: each chunk is + indivisible (modulo 'break_long_words'), but a line break can + come between any two chunks. Chunks should not have internal + whitespace; ie. a chunk is either all whitespace or a "word". + Whitespace chunks will be removed from the beginning and end of + lines, but apart from that whitespace is preserved. + """ + lines = [] + if self.width <= 0: + raise ValueError("invalid width %r (must be > 0)" % self.width) + + # Arrange in reverse order so items can be efficiently popped + # from a stack of chucks. + chunks.reverse() + + while chunks: + + # Start the list of chunks that will make up the current line. + # cur_len is just the length of all the chunks in cur_line. + cur_line = [] + cur_len = 0 + + # Figure out which static string will prefix this line. + if lines: + indent = self.subsequent_indent else: - p = mofile(f) - s = unicode(p) - import profile - profile.run('test("'+sys.argv[2]+'")') - else: - import doctest - doctest.testmod() + indent = self.initial_indent + + # Maximum width for this line. + width = self.width - len(indent) + + # First chunk on line is whitespace -- drop it, unless this + # is the very beginning of the text (ie. no lines started yet). + if self.drop_whitespace and chunks[-1].strip() == '' and lines: + del chunks[-1] + + while chunks: + l = len(chunks[-1]) + + # Can at least squeeze this chunk onto the current line. + if cur_len + l <= width: + cur_line.append(chunks.pop()) + cur_len += l + + # Nope, this line is full. + else: + break + + # The current line is full, and the next chunk is too big to + # fit on *any* line (not just this one). + if chunks and len(chunks[-1]) > width: + self._handle_long_word(chunks, cur_line, cur_len, width) + + # If the last chunk on this line is all whitespace, drop it. + if self.drop_whitespace and cur_line and cur_line[-1].strip() == '': + del cur_line[-1] + + # Convert current line back to a string and store it in list + # of all lines (return value). + if cur_line: + lines.append(indent + ''.join(cur_line)) + + return lines # }}} +# function wrap() {{{ + +def wrap(text, width=70, **kwargs): + """ + Wrap a single paragraph of text, returning a list of wrapped lines. + """ + if sys.version_info < (2, 6): + return TextWrapper(width=width, **kwargs).wrap(text) + return textwrap.wrap(text, width=width, **kwargs) + +#}}}
--- a/i18n/pt_BR.po Wed Oct 26 22:35:15 2011 +0200 +++ b/i18n/pt_BR.po Thu Oct 27 18:35:07 2011 -0500 @@ -31,18 +31,19 @@ msgstr "" "Project-Id-Version: Mercurial\n" "Report-Msgid-Bugs-To: <mercurial-devel@selenic.com>\n" -"POT-Creation-Date: 2011-06-20 16:55-0300\n" +"POT-Creation-Date: 2011-10-18 09:38-0200\n" "PO-Revision-Date: 2011-06-28 09:55+0200\n" "Last-Translator: Wagner Bruna <wbruna@yahoo.com>\n" "Language-Team: Brazilian Portuguese\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Generated-By: pygettext.py 1.5\n" +"Language: \n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: KBabel 1.11.4\n" +"X-Poedit-Country: BRAZIL\n" "X-Poedit-Language: Portuguese\n" -"Generated-By: pygettext.py 1.5\n" -"X-Poedit-Country: BRAZIL\n" -"X-Generator: KBabel 1.11.4\n" #, python-format msgid " (default: %s)" @@ -57,8 +58,13 @@ msgid "Extensions" msgstr "Extensões" -msgid "This section contains help for extensions that are distributed together with Mercurial. Help for other extensions is available in the help system." -msgstr "Esta seção contém texto de ajuda para extensões que são distribuídas junto com o Mercurial. A ajuda para outras extensões está disponível no sistema de ajuda." +msgid "" +"This section contains help for extensions that are distributed together with" +" Mercurial. Help for other extensions is available in the help system." +msgstr "" +"Esta seção contém texto de ajuda para extensões que são distribuídas junto " +"com o Mercurial. A ajuda para outras extensões está disponível no sistema de" +" ajuda." msgid "Options:" msgstr "Opções:" @@ -381,8 +387,11 @@ msgstr "O grupo '%s' não está definido" #, python-format -msgid "config error - hook type \"%s\" cannot stop incoming changesets nor commits" -msgstr "erro de configuração - tipo de gancho \"%s\" não pode interromper consolidações nem revisões de entrada" +msgid "" +"config error - hook type \"%s\" cannot stop incoming changesets nor commits" +msgstr "" +"erro de configuração - tipo de gancho \"%s\" não pode interromper " +"consolidações nem revisões de entrada" #, python-format msgid "acl: user \"%s\" denied on branch \"%s\" (changeset \"%s\")" @@ -393,8 +402,12 @@ msgstr "acl: usuário \"%s\" não tem acesso ao ramo \"%s\" (revisão \"%s\")" #, python-format -msgid "acl: access denied for changeset %s" -msgstr "acl: acesso negado para a revisão %s" +msgid "acl: user \"%s\" denied on \"%s\" (changeset \"%s\")" +msgstr "acl: o acesso do usuário \"%s\" a \"%s\" foi negado (revisão \"%s\")" + +#, python-format +msgid "acl: user \"%s\" not allowed on \"%s\" (changeset \"%s\")" +msgstr "acl: o acesso do usuário \"%s\" a \"%s\" não foi permitido (revisão \"%s\")" msgid "hooks for integrating with the Bugzilla bug tracker" msgstr "ganchos para integração com o bug tracker Bugzilla" @@ -415,7 +428,8 @@ msgid "Three basic modes of access to Bugzilla are provided:" msgstr "Três modos básicos de acesso ao Bugzilla são fornecidos:" -msgid "1. Access via the Bugzilla XMLRPC interface. Requires Bugzilla 3.4 or later." +msgid "" +"1. Access via the Bugzilla XMLRPC interface. Requires Bugzilla 3.4 or later." msgstr "" "1. Acesso através da interface XMLRPC do Bugzilla. Exige a versão\n" "3.4 ou posterior do Bugzilla." @@ -591,7 +605,8 @@ " em modelos como ``{hgweb}``." msgid "Configuration items common to XMLRPC+email and MySQL access modes:" -msgstr "Itens de configuração comuns aos modos de acesso XMLRPC+email e MySQL:" +msgstr "" +"Itens de configuração comuns aos modos de acesso XMLRPC+email e MySQL:" msgid "" "bugzilla.usermap\n" @@ -1180,7 +1195,8 @@ "conhecidos como códigos de escape ANSI)." msgid "Default effects may be overridden from your configuration file::" -msgstr "Os efeitos padrão podem ser redefinidos pelo seu arquivo de configuração::" +msgstr "" +"Os efeitos padrão podem ser redefinidos pelo seu arquivo de configuração::" msgid "" " [color]\n" @@ -1260,6 +1276,13 @@ " branches.inactive = none" msgid "" +" tags.normal = green\n" +" tags.local = black bold" +msgstr "" +" tags.normal = green\n" +" tags.local = black bold" + +msgid "" "The available effects in terminfo mode are 'blink', 'bold', 'dim',\n" "'inverse', 'invisible', 'italic', 'standout', and 'underline'; in\n" "ECMA-48 mode, the options are 'bold', 'inverse', 'italic', and\n" @@ -1349,7 +1372,8 @@ "desabilitará a coloração.\n" msgid "no terminfo entry for setab/setaf: reverting to ECMA-48 color\n" -msgstr "nenhuma entrada terminfo para setab/setaf: revertendo para cores ECMA-48\n" +msgstr "" +"nenhuma entrada terminfo para setab/setaf: revertendo para cores ECMA-48\n" #, python-format msgid "warning: failed to set color mode to %s\n" @@ -1362,7 +1386,9 @@ #. i18n: 'always', 'auto', and 'never' are keywords and should #. not be translated msgid "when to colorize (boolean, always, auto, or never)" -msgstr "quando colorir (booleana, ou \"always\" (sempre), \"never\" (nunca) ou \"auto\" (automaticamente))" +msgstr "" +"quando colorir (booleana, ou \"always\" (sempre), \"never\" (nunca) ou " +"\"auto\" (automaticamente))" msgid "TYPE" msgstr "TIPO" @@ -1645,8 +1671,8 @@ msgid "" " :convert.hg.saverev: store original revision ID in changeset\n" -" (forces target IDs to change). It takes and boolean argument\n" -" and defaults to False." +" (forces target IDs to change). It takes a boolean argument and\n" +" defaults to False." msgstr "" " :convert.hg.saverev: armazena o identificador da revisão de origem\n" " (forçando a mudança de IDs de etiquetas). Esta opção recebe um\n" @@ -2013,7 +2039,9 @@ msgstr ":svnpath: String. Caminho do projeto Subversion convertido." msgid ":svnuuid: String. Converted subversion revision repository identifier." -msgstr ":svnuuid: String. Identificador do repositório do Subversion da revisão convertida." +msgstr "" +":svnuuid: String. Identificador do repositório do Subversion da revisão " +"convertida." #, python-format msgid "%s does not look like a Bazaar repository" @@ -2022,8 +2050,12 @@ msgid "Bazaar modules could not be loaded" msgstr "os módulos do Bazaar não puderam ser carregados" -msgid "warning: lightweight checkouts may cause conversion failures, try with a regular branch instead.\n" -msgstr "aviso: checkouts \"lightweight\" podem causar falhas de conversão, tente com um branch comum.\n" +msgid "" +"warning: lightweight checkouts may cause conversion failures, try with a " +"regular branch instead.\n" +msgstr "" +"aviso: checkouts \"lightweight\" podem causar falhas de conversão, tente com" +" um branch comum.\n" msgid "bzr source type could not be determined\n" msgstr "o tipo de origem bzr não pôde ser determinado\n" @@ -2158,8 +2190,12 @@ msgstr "autenticação pserver do CVS falhou" #, python-format -msgid "unexpected response from CVS server (expected \"Valid-requests\", but got %r)" -msgstr "resposta inesperada do servidor CVS (\"Valid-requests\" esperada, %r recebida)" +msgid "" +"unexpected response from CVS server (expected \"Valid-requests\", but got " +"%r)" +msgstr "" +"resposta inesperada do servidor CVS (\"Valid-requests\" esperada, %r " +"recebida)" #, python-format msgid "%d bytes missing from remote file" @@ -2211,7 +2247,9 @@ msgstr "revisão deve ser seguida por uma linha de data" msgid "log cache overlaps with new log entries, re-run without cache." -msgstr "o cache do log se sobrepõe a novas entradas do log, execute novamente sem o cache." +msgstr "" +"o cache do log se sobrepõe a novas entradas do log, execute novamente sem o " +"cache." #, python-format msgid "writing cvs log cache %s\n" @@ -2313,8 +2351,11 @@ msgstr "analisando versão da árvore %s...\n" #, python-format -msgid "tree analysis stopped because it points to an unregistered archive %s...\n" -msgstr "análise da árvore parou porque esta aponta para um arquivo não registrado %s...\n" +msgid "" +"tree analysis stopped because it points to an unregistered archive %s...\n" +msgstr "" +"análise da árvore parou porque esta aponta para um arquivo não registrado " +"%s...\n" #, python-format msgid "could not parse cat-log of %s" @@ -2407,10 +2448,16 @@ msgstr "coletando changelists do p4\n" msgid "Mercurial failed to run itself, check hg executable is in PATH" -msgstr "Mercurial falhou ao executar a si próprio, veja se o executável hg está no PATH" - -msgid "svn: cannot probe remote repository, assume it could be a subversion repository. Use --source-type if you know better.\n" -msgstr "svn: não é possível sondar o repositório remoto; a conversão irá assumir que é um repositório remoto do Subversion. Use --source-type se necessário.\n" +msgstr "" +"Mercurial falhou ao executar a si próprio, veja se o executável hg está no " +"PATH" + +msgid "" +"svn: cannot probe remote repository, assume it could be a subversion " +"repository. Use --source-type if you know better.\n" +msgstr "" +"svn: não é possível sondar o repositório remoto; a conversão irá assumir que" +" é um repositório remoto do Subversion. Use --source-type se necessário.\n" #, python-format msgid "%s does not look like a Subversion repository" @@ -2421,10 +2468,14 @@ #, python-format msgid "Subversion python bindings %d.%d found, 1.4 or later required" -msgstr "Encontrados módulos Python para o Subversion %d.%d, requerida a versão 1.4 ou posterior" +msgstr "" +"Encontrados módulos Python para o Subversion %d.%d, requerida a versão 1.4 " +"ou posterior" msgid "Subversion python bindings are too old, 1.4 or later required" -msgstr "Módulos Python para o Subversion são antigos demais, requerida a versão 1.4 ou posterior" +msgstr "" +"Módulos Python para o Subversion são antigos demais, requerida a versão 1.4 " +"ou posterior" #, python-format msgid "svn: revision %s is not an integer" @@ -2617,13 +2668,15 @@ " todos os arquivos." msgid "" -"The extension uses an optional ``[eol]`` section in your hgrc file\n" -"(not the ``.hgeol`` file) for settings that control the overall\n" -"behavior. There are two settings:" -msgstr "" -"A extensão também usa uma seção opcional ``[eol]`` em seu arquivo\n" -"hgrc (diferente do arquivo ``.hgeol``) para configurações que controlam\n" -"seu comportamento geral. Há duas configurações:" +"The extension uses an optional ``[eol]`` section read from both the\n" +"normal Mercurial configuration files and the ``.hgeol`` file, with the\n" +"latter overriding the former. You can use that section to control the\n" +"overall behavior. There are three settings:" +msgstr "" +"A extensão também usa uma seção opcional ``[eol]`` lida tanto a partir\n" +"dos arquivos de configuração normais do Mercurial como do arquivo\n" +"``.hgeol``, sendo que este último sobrepõe os anteriores. Você pode usar\n" +"essa seção para controlar o comportamento global. Há três configurações:" msgid "" "- ``eol.native`` (default ``os.linesep``) can be set to ``LF`` or\n" @@ -2651,6 +2704,15 @@ " quebras de linha seja intencional." msgid "" +"- ``eol.fix-trailing-newline`` (default False) can be set to True to\n" +" ensure that converted files end with a EOL character (either ``\\n``\n" +" or ``\\r\\n`` as per the configured patterns)." +msgstr "" +"- ``eol.fix-trailing-newline`` (padrão False) pode ser definida para True\n" +" para garantir que arquivos convertidos terminem com um caractere de fim\n" +" de linha (``\\n`` ou ``\\r\\n``, de acordo com os padrões configurados)." + +msgid "" "The extension provides ``cleverencode:`` and ``cleverdecode:`` filters\n" "like the deprecated win32text extension does. This means that you can\n" "disable win32text and enable eol and your filters will still work. You\n" @@ -2782,7 +2844,9 @@ " vimdiff = gvim -f '+next' '+execute \"DirDiff\" argv(0) argv(1)'" msgid "Tool arguments can include variables that are expanded at runtime::" -msgstr "Parâmetros de ferramentas podem incluir variáveis que são expandidas durante a execução::" +msgstr "" +"Parâmetros de ferramentas podem incluir variáveis que são expandidas durante" +" a execução::" msgid "" " $parent1, $plabel1 - filename, descriptive label of first parent\n" @@ -2967,7 +3031,9 @@ " " msgid "working dir not at branch tip (use \"hg update\" to check out branch tip)" -msgstr "o diretório de trabalho não está na tip do ramo (use \"hg update\" para obter a tip do ramo)" +msgstr "" +"o diretório de trabalho não está na tip do ramo (use \"hg update\" para " +"obter a tip do ramo)" msgid "outstanding uncommitted merge" msgstr "mesclagem não consolidada pendente" @@ -2985,12 +3051,20 @@ msgid "pulling from %s\n" msgstr "trazendo revisões de %s\n" -msgid "Other repository doesn't support revision lookup, so a rev cannot be specified." -msgstr "O outro repositório não suporta busca por revisão, portanto uma revisão não pode ser especificada." - -#, python-format -msgid "not merging with %d other new branch heads (use \"hg heads .\" and \"hg merge\" to merge them)\n" -msgstr "não mesclando com %d outros novas cabeças de ramo (use \"hg heads .\" e \"hg merge\" para mescla-los)\n" +msgid "" +"Other repository doesn't support revision lookup, so a rev cannot be " +"specified." +msgstr "" +"O outro repositório não suporta busca por revisão, portanto uma revisão não " +"pode ser especificada." + +#, python-format +msgid "" +"not merging with %d other new branch heads (use \"hg heads .\" and \"hg " +"merge\" to merge them)\n" +msgstr "" +"não mesclando com %d outros novas cabeças de ramo (use \"hg heads .\" e \"hg" +" merge\" para mescla-los)\n" #, python-format msgid "updating to %d:%s\n" @@ -3051,7 +3125,9 @@ msgstr "hg sigcheck REVISÃO" msgid "verify all the signatures there may be for a particular revision" -msgstr "verifica todas as assinaturas que podem existir para uma revisão em particular" +msgstr "" +"verifica todas as assinaturas que podem existir para uma revisão em " +"particular" #, python-format msgid "No valid signature for %s\n" @@ -3110,8 +3186,12 @@ msgid "error while signing" msgstr "erro ao assinar" -msgid "working copy of .hgsigs is changed (please commit .hgsigs manually or use --force)" -msgstr "a cópia de trabalho de .hgsigs foi mudada (por favor consolide .hgsigs manualmente ou use --force)" +msgid "" +"working copy of .hgsigs is changed (please commit .hgsigs manually or use " +"--force)" +msgstr "" +"a cópia de trabalho de .hgsigs foi mudada (por favor consolide .hgsigs " +"manualmente ou use --force)" msgid "unknown signature version" msgstr "versão de assinatura desconhecida" @@ -3384,6 +3464,7 @@ msgid "hg debug-merge-base REV REV" msgstr "hg debug-merge-base REV REV" +#. i18n: bisect changeset status msgid "ignored" msgstr "ignorado" @@ -3463,7 +3544,8 @@ msgstr "hg inserve [OPÇÃO]..." msgid "inotify-client: found dead inotify server socket; removing it\n" -msgstr "inotify-client: encontrado socket de um servidor inotify morto; removendo\n" +msgstr "" +"inotify-client: encontrado socket de um servidor inotify morto; removendo\n" #, python-format msgid "inotify-client: could not start inotify server: %s\n" @@ -3471,7 +3553,8 @@ #, python-format msgid "inotify-client: could not talk to new inotify server: %s\n" -msgstr "inotify-client: não foi possível falar com o novo servidor inotify: %s\n" +msgstr "" +"inotify-client: não foi possível falar com o novo servidor inotify: %s\n" #, python-format msgid "inotify-client: failed to contact inotify server: %s\n" @@ -3482,7 +3565,8 @@ #, python-format msgid "(inotify: received response from incompatible server version %d)\n" -msgstr "(inotify: recebida resposta de uma versão de servidor incompatível %d)\n" +msgstr "" +"(inotify: recebida resposta de uma versão de servidor incompatível %d)\n" #, python-format msgid "(inotify: received '%s' response when expecting '%s')\n" @@ -3496,7 +3580,9 @@ msgstr "*** o limite atual por usuário do número de inotify watches é %s\n" msgid "*** this limit is too low to watch every directory in this repository\n" -msgstr "*** este limite é muito baixo para acompanhar cada diretório neste repositório\n" +msgstr "" +"*** este limite é muito baixo para acompanhar cada diretório neste " +"repositório\n" msgid "*** counting directories: " msgstr "*** contando diretórios: " @@ -3515,7 +3601,9 @@ #, python-format msgid "cannot watch %s until inotify watch limit is raised" -msgstr "impossível observar %s até que o limite de observação do inotify seja alcançado" +msgstr "" +"impossível observar %s até que o limite de observação do inotify seja " +"alcançado" #, python-format msgid "inotify service not available: %s" @@ -3574,8 +3662,12 @@ msgid "cannot start: socket is already bound" msgstr "não é possível iniciar: o socket já está associado" -msgid "cannot start: tried linking .hg/inotify.sock to a temporary socket but .hg/inotify.sock already exists" -msgstr "não é possível iniciar: tentou lincar .hg/inotify.sock para um socket temporário mas .hg/inotify.sock já existe" +msgid "" +"cannot start: tried linking .hg/inotify.sock to a temporary socket but " +".hg/inotify.sock already exists" +msgstr "" +"não é possível iniciar: tentou lincar .hg/inotify.sock para um socket " +"temporário mas .hg/inotify.sock já existe" #, python-format msgid "answering query for %r\n" @@ -3949,7 +4041,8 @@ msgstr "reverte palavras chave expandidas no diretório de trabalho" msgid " Must be run before changing/disabling active keywords." -msgstr " Deve ser executado após mudar / desabilitar palavras chave ativas." +msgstr "" +" Deve ser executado após mudar / desabilitar palavras chave ativas." msgid "" " kwshrink refuses to run if given files contain local changes.\n" @@ -3959,6 +4052,487 @@ " mudanças locais.\n" " " +msgid "track large binary files" +msgstr "rastreia arquivos binários grandes" + +msgid "" +"Large binary files tend to be not very compressible, not very\n" +"diffable, and not at all mergeable. Such files are not handled\n" +"efficiently by Mercurial's storage format (revlog), which is based on\n" +"compressed binary deltas; storing large binary files as regular\n" +"Mercurial files wastes bandwidth and disk space and increases\n" +"Mercurial's memory usage. The largefiles extension addresses these\n" +"problems by adding a centralized client-server layer on top of\n" +"Mercurial: largefiles live in a *central store* out on the network\n" +"somewhere, and you only fetch the revisions that you need when you\n" +"need them." +msgstr "" +"Arquivos binários grandes tendem a não ser muito comprimíveis,\n" +"não gerar diffs úteis, e não serem mescláveis. Tais arquivos não\n" +"são gerenciados de modo eficiente pelo formato de armazenamento do\n" +"Mercurial (revlog), que se baseia em deltas binários comprimidos;\n" +"armazenar arquivos binários grandes como arquivos comuns no\n" +"Mercurial desperdiça banda e espaço em disco e aumenta o uso de\n" +"memória do Mercurial. A extensão largefiles trata esses problemas\n" +"adicionando uma camada cliente-servidor centralizada sobre o\n" +"Mercurial: largefiles se localiza em um *armazenamento central*\n" +"em algum lugar da rede, e você obtém apenas as revisões necessárias\n" +"no momento em que são necessárias." + +msgid "" +"largefiles works by maintaining a \"standin file\" in .hglf/ for each\n" +"largefile. The standins are small (41 bytes: an SHA-1 hash plus\n" +"newline) and are tracked by Mercurial. Largefile revisions are\n" +"identified by the SHA-1 hash of their contents, which is written to\n" +"the standin. largefiles uses that revision ID to get/put largefile\n" +"revisions from/to the central store. This saves both disk space and\n" +"bandwidth, since you don't need to retrieve all historical revisions\n" +"of large files when you clone or pull." +msgstr "" +"largefiles funciona mantendo um arquivo \"standin\" em .hglf/ para cada\n" +"largefile. Os arquivos standin são pequenos (41 bytes: um hash SHA-1 e\n" +"uma quebra de linha) e são rastreados pelo Mercurial. As revisões\n" +"largefile são identificadas pelo hash SHA-1 de seus conteúdos, que\n" +"são registrados no standin. largefiles usa tal ID de revisão para \n" +"obter ou enviar revisões largefile de ou para o armazenamento central.\n" +"Isto economiza tanto espaço em disco como banda de rede, já que não é\n" +"necessário obter todas as revisões históricas de arquivos grandes em\n" +"um clone ou pull." + +msgid "" +"To start a new repository or add new large binary files, just add\n" +"--large to your :hg:`add` command. For example::" +msgstr "" +"Para iniciar um novo repositório ou adicionar novos arquivos\n" +"binários grandes, adicione --large ao seu comando :hg:`add`.\n" +"Por exemplo::" + +msgid "" +" $ dd if=/dev/urandom of=randomdata count=2000\n" +" $ hg add --large randomdata\n" +" $ hg commit -m 'add randomdata as a largefile'" +msgstr "" +" $ dd if=/dev/urandom of=randomdata count=2000\n" +" $ hg add --large randomdata\n" +" $ hg commit -m 'add randomdata as a largefile'" + +msgid "" +"When you push a changeset that adds/modifies largefiles to a remote\n" +"repository, its largefile revisions will be uploaded along with it.\n" +"Note that the remote Mercurial must also have the largefiles extension\n" +"enabled for this to work." +msgstr "" +"Ao enviar uma revisão que adiciona/modifica arquivos grandes para um\n" +"repositório remoto, sua revisão largefile correspondente será também\n" +"enviada. Note que o Mercurial remoto também deve ter a extensão\n" +"largefiles habilitada." + +msgid "" +"When you pull a changeset that affects largefiles from a remote\n" +"repository, Mercurial behaves as normal. However, when you update to\n" +"such a revision, any largefiles needed by that revision are downloaded\n" +"and cached (if they have never been downloaded before). This means\n" +"that network access may be required to update to changesets you have\n" +"not previously updated to." +msgstr "" +"Ao trazer revisões de um repositório remoto que afetam largefiles, o\n" +"Mercurial se comporta normalmente. No entanto, au atualizar para tal\n" +"revisão, quaisquer largefiles necessárias para tal revisão serão\n" +"baixadas e guardadas em um cache (se elas nunca foram baixadas antes)\n" +". Isto quer dizer que acesso à rede pode ser necessário para atualizar\n" +"para revisões que ainda não estiveram no diretório de trabalho." + +msgid "" +"If you already have large files tracked by Mercurial without the\n" +"largefiles extension, you will need to convert your repository in\n" +"order to benefit from largefiles. This is done with the\n" +":hg:`lfconvert` command::" +msgstr "" +"Se você já tiver arquivos grandes rastreados pelo Mercurial sem a\n" +"extensão largefiles, será preciso converter seu repositório para se\n" +"beneficiar da extensão largefiles. Isto é feito usando o comando\n" +":hg:`lfconvert` ::" + +msgid " $ hg lfconvert --size 10 oldrepo newrepo" +msgstr " $ hg lfconvert --size 10 oldrepo newrepo" + +msgid "" +"In repositories that already have largefiles in them, any new file\n" +"over 10MB will automatically be added as a largefile. To change this\n" +"threshold, set ``largefiles.minsize`` in your Mercurial config file\n" +"to the minimum size in megabytes to track as a largefile, or use the\n" +"--lfsize option to the add command (also in megabytes)::" +msgstr "" +"Em repositórios que já possuem algum largefile, qualquer novo arquivo\n" +"acima de 10MB será automaticamente adicionado como largefile. Para\n" +"mudar esse limiar, defina ``largefiles.minsize`` em seu arquivo de\n" +"configuração do Mercurial para o tamanho mínimo em megabytes para\n" +"rastrear o arquivo como largefile, ou use a opção --lfsize no comando\n" +"add (também em megabytes)::" + +msgid "" +" [largefiles]\n" +" minsize = 2" +msgstr "" +" [largefiles]\n" +" minsize = 2" + +msgid " $ hg add --lfsize 2" +msgstr " $ hg add --lfsize 2" + +msgid "" +"The ``largefiles.patterns`` config option allows you to specify a list\n" +"of filename patterns (see :hg:`help patterns`) that should always be\n" +"tracked as largefiles::" +msgstr "" +"A opção de configuração ``largefiles.patterns`` permite especificar\n" +"uma lista de padrões de nomes de arquivo (veja :hg:`help patterns`)\n" +"que devam ser sempre tratados como largefiles::" + +msgid "" +" [largefiles]\n" +" patterns =\n" +" *.jpg\n" +" re:.*\\.(png|bmp)$\n" +" library.zip\n" +" content/audio/*" +msgstr "" +" [largefiles]\n" +" patterns =\n" +" *.jpg\n" +" re:.*\\.(png|bmp)$\n" +" library.zip\n" +" content/audio/*" + +msgid "" +"Files that match one of these patterns will be added as largefiles\n" +"regardless of their size.\n" +msgstr "" +"Arquivos que corresponderem a um desses padrões serão adicionados\n" +"como largefiles sem que seus tamanhos sejam considerados.\n" + +msgid "convert a normal repository to a largefiles repository" +msgstr "converte um repositório normal em um repositório largefiles" + +msgid "" +" Convert repository SOURCE to a new repository DEST, identical to\n" +" SOURCE except that certain files will be converted as largefiles:\n" +" specifically, any file that matches any PATTERN *or* whose size is\n" +" above the minimum size threshold is converted as a largefile. The\n" +" size used to determine whether or not to track a file as a\n" +" largefile is the size of the first version of the file. The\n" +" minimum size can be specified either with --size or in\n" +" configuration as ``largefiles.size``." +msgstr "" +" Converte o repositório ORIGEM em um novo repositório DEST,\n" +" idêntico a ORIGEM exceto por certos arquivos que serão\n" +" convertidos como largefiles:\n" +" especificamente, qualquer arquivo que combinar com qualquer\n" +" PADRÃO *ou* cujo tamanho esteja acima do limiar de tamanho\n" +" mínimo será convertido como um largefile. O tamanho usado para\n" +" determinar se o arquivo será rastreado como largefile será o\n" +" tamanho da primeira versão do arquivo. O tamanho mínimo pode\n" +" ser especificado usando o parâmetro --size ou a opção de\n" +" configuração ``largefiles.size``." + +msgid "" +" After running this command you will need to make sure that\n" +" largefiles is enabled anywhere you intend to push the new\n" +" repository." +msgstr "" +" Após a execução deste comando, você deve se certificar de\n" +" que largefiles esteja habilitado em todos os repositórios que\n" +" receberão revisões do novo repositório." + +msgid "" +" Use --to-normal to convert largefiles back to normal files; after\n" +" this, the DEST repository can be used without largefiles at all." +msgstr "" +" Use --to-normal para converter largefiles de volta a arquivos\n" +" normais; após essa conversão, o repositório DEST poderá ser\n" +" usado normalmente, sem a extensão largefiles." + +msgid "getting largefiles" +msgstr "obtendo largefiles" + +#, python-format +msgid "getting %s:%s\n" +msgstr "obtendo %s:%s\n" + +#, python-format +msgid "%s: data corruption (expected %s, got %s)\n" +msgstr "%s: corrupção de dados (esperado %s, obtido %s)\n" + +#, python-format +msgid "searching %d changesets for largefiles\n" +msgstr "procurando em %d revisões por largefiles\n" + +#, python-format +msgid "verified contents of %d revisions of %d largefiles\n" +msgstr "verificado o conteúdo de %d revisões de %d largefiles\n" + +#, python-format +msgid "verified existence of %d revisions of %d largefiles\n" +msgstr "verificada a existência de %d revisões de %d largefiles\n" + +#, python-format +msgid "unsupported URL scheme %r" +msgstr "esquema URL %r não suportado" + +#, python-format +msgid "%s does not appear to be a largefile store" +msgstr "'%s' não parece ser um repositório de largefiles" + +#, python-format +msgid "%s is not a local Mercurial repo" +msgstr "%s não é um repositório local do Mercurial" + +#, python-format +msgid "initializing destination %s\n" +msgstr "iniciando destino %s\n" + +msgid "converting revisions" +msgstr "convertendo revisões" + +#, python-format +msgid "Renamed/copied largefile %s becomes symlink" +msgstr "O largefile %s renomeado/copiado se tornou um link simbólico" + +#, python-format +msgid "largefile %s becomes symlink" +msgstr "o largefile %s se tornou um link simbólico" + +msgid "uploading largefiles" +msgstr "enviando largefiles" + +#, python-format +msgid "largefile %s missing from store (needs to be uploaded)" +msgstr "o largefile %s está faltando no repositório (deve ser enviado)" + +msgid "getting changed largefiles\n" +msgstr "obtendo largefiles modificados\n" + +#, python-format +msgid "%d largefiles updated, %d removed\n" +msgstr "%d largefiles atualizados, %d removidos\n" + +msgid "minimum size (MB) for files to be converted as largefiles" +msgstr "tamanho mínimo (MB) para arquivos serem convertidos em largefiles" + +msgid "convert from a largefiles repo to a normal repo" +msgstr "converte um repositório largefiles em um repositório normal" + +msgid "hg lfconvert SOURCE DEST [FILE ...]" +msgstr "hg lfconvert ORIGEM DEST [ARQUIVO ...]" + +#, python-format +msgid "largefiles: size must be number (not %s)\n" +msgstr "largefiles: o tamanho deve ser um número (e não %s)\n" + +msgid "minimum size for largefiles must be specified" +msgstr "o tamanho mínimo para largefiles deve ser especificado" + +#, python-format +msgid "unknown operating system: %s\n" +msgstr "sistema operacional desconhecido: %s\n" + +#, python-format +msgid "Found %s in store\n" +msgstr "Encontrado %s no armazenamento\n" + +#, python-format +msgid "Found %s in system cache\n" +msgstr "Encontrado %s no cache do sistema\n" + +#, python-format +msgid "bad hash in '%s' (only %d bytes long)" +msgstr "hash ruim em '%s' (o comprimento é de apenas %d bytes)" + +msgid "Can't get file locally" +msgstr "Não é possível obter o arquivo localmente" + +#, python-format +msgid "" +"changeset %s: %s missing\n" +" (looked for hash %s)\n" +msgstr "" +"revisão %s: %s faltando\n" +" (procurou pelo hash %s)\n" + +#, python-format +msgid "" +"changeset %s: %s: contents differ\n" +" (%s:\n" +" expected hash %s,\n" +" but got %s)\n" +msgstr "" +"revisão %s: %s: o conteúdo é diferente\n" +" (%s:\n" +" esperado hash %s,\n" +" mas obteve %s)\n" + +#, python-format +msgid "%s already a largefile\n" +msgstr "%s já é um largefile\n" + +#, python-format +msgid "adding %s as a largefile\n" +msgstr "adicionando %s como largefile\n" + +msgid "no files specified" +msgstr "nenhum arquivo especificado" + +#, python-format +msgid "not removing %s: %s (use -f to force removal)\n" +msgstr "%s não removido: %s (use -f para forçar a remoção)\n" + +msgid "file still exists" +msgstr "o arquivo já existe" + +msgid "file is modified" +msgstr "o arquivo foi modificado" + +msgid "file has been marked for add" +msgstr "o arquivo foi marcado para adição" + +#, python-format +msgid "removing %s\n" +msgstr "removendo %s\n" + +msgid "uncommitted local changes" +msgstr "alterações locais pendentes" + +#, python-format +msgid "merging %s and %s to %s\n" +msgstr "mesclando %s e %s para %s\n" + +#, python-format +msgid "merging %s\n" +msgstr "mesclando %s\n" + +#, python-format +msgid "" +"largefile %s has a merge conflict\n" +"keep (l)ocal or take (o)ther?" +msgstr "" +"largefile %s tem um conflito de mesclagem\n" +"manter (l)ocal ou usar (o)utro?" + +msgid "&Local" +msgstr "&Local" + +msgid "&Other" +msgstr "&Outra" + +msgid "destination largefile already exists" +msgstr "largefile de destino já existe" + +msgid "no files to copy" +msgstr "nenhum arquivo para copiar" + +#, python-format +msgid "unknown archive type '%s'" +msgstr "tipo de arquivo '%s' desconhecido" + +msgid "cannot give prefix when archiving to files" +msgstr "não é possível fornecer prefixo ao arquivar para arquivos" + +#, python-format +msgid "not removing %s: file is already untracked\n" +msgstr "%s não removido: arquivo já não é rastreado\n" + +msgid "largefiles: No remote repo\n" +msgstr "largefiles: Nenhum repositório remoto\n" + +msgid "largefiles to upload:\n" +msgstr "largefiles a serem enviados:\n" + +#, python-format +msgid "largefiles: %d to upload\n" +msgstr "largefiles: %d a serem enviados\n" + +msgid "addremove cannot be run on a repo with largefiles" +msgstr "addremove não pode ser executado em um repositório com largefiles" + +msgid "error: could not put received data into largefile store" +msgstr "" +"erro: não foi possível colocar os dados recebidos no armazenamento de " +"largefiles" + +#, python-format +msgid "requested largefile %s not present in cache" +msgstr "largefile %s pedido não está presente no cache" + +msgid "putlfile failed:" +msgstr "putlfile falhou:" + +msgid "putlfile failed (unexpected response):" +msgstr "putlfile falhou (resposta inesperada):" + +msgid "unexpected response:" +msgstr "resposta inesperada:" + +#, python-format +msgid "remotestore: could not put %s to remote store %s" +msgstr "remotestore: não foi possível colocar %s no armazenamento remoto %s" + +#, python-format +msgid "remotestore: put %s to remote store %s" +msgstr "remotestore: %s foi colocado no armazenamento remoto %s" + +#, python-format +msgid "remotestore: could not open file %s: %s" +msgstr "remotestore: não foi possível abrir arquivo %s: %s" + +#, python-format +msgid "remotestore: largefile %s is invalid" +msgstr "remotestore: largefile %s é inválido" + +#, python-format +msgid "remotestore: largefile %s is missing" +msgstr "remotestore: largefile %s está faltando" + +#, python-format +msgid "changeset %s: %s: contents differ\n" +msgstr "revisão %s: %s: o conteúdo está diferente\n" + +#, python-format +msgid "changeset %s: %s missing\n" +msgstr "revisão %s: %s faltando\n" + +#, python-format +msgid "" +"largefiles: repo method %r appears to have already been wrapped by another " +"extension: largefiles may behave incorrectly\n" +msgstr "" +"largefiles: o método %r do repositório parece já ter sido sobreposto\n" +"por uma outra extensão: largefiles pode se comportar incorretamente\n" + +#, python-format +msgid "file \"%s\" is a largefile standin" +msgstr "o arquivo \"%s\" é um standin largefile" + +msgid "add as largefile" +msgstr "adiciona como largefile" + +msgid "" +"add all files above this size (in megabytes) as largefiles (default: 10)" +msgstr "" +"adiciona todos os arquivos acima deste tamanho (em megabytes) como " +"largefiles (padrão: 10)" + +msgid "verify largefiles" +msgstr "verifica largefiles" + +msgid "verify all revisions of largefiles not just current" +msgstr "verifica todas as revisões de largefiles, não apenas a revisão atual" + +msgid "verify largefile contents not just existence" +msgstr "verifica conteúdos de largefiles, não apenas existência" + +msgid "display outgoing largefiles" +msgstr "exibe largefiles a serem enviados" + msgid "manage a stack of patches" msgstr "gerencia uma pilha de patches" @@ -4311,7 +4885,8 @@ msgstr "tentando desempilhar nó desconhecido %s" msgid "popping would remove a revision not managed by this patch queue" -msgstr "desempilhar removeria uma revisão não gerenciada por esta fila de patches" +msgstr "" +"desempilhar removeria uma revisão não gerenciada por esta fila de patches" msgid "deletions found between repo revs" msgstr "remoções encontradas entre revisões do repositório" @@ -4326,8 +4901,12 @@ msgid "cannot refresh a revision with children" msgstr "não se pode renovar uma revisão com filhos" -msgid "refresh interrupted while patch was popped! (revert --all, qpush to recover)\n" -msgstr "renovação interrompida enquanto o patch foi desempilhado! (revert --all, qpush para recuperar)\n" +msgid "" +"refresh interrupted while patch was popped! (revert --all, qpush to " +"recover)\n" +msgstr "" +"renovação interrompida enquanto o patch foi desempilhado! (revert --all, " +"qpush para recuperar)\n" msgid "patch queue directory already exists" msgstr "o diretório de fila de patches já existe" @@ -5130,11 +5709,23 @@ msgid "copy %s to %s\n" msgstr "copia %s para %s\n" +msgid "" +"strip specified revision (optional, can specify revisions without this " +"option)" +msgstr "" +"remove a revisão especificada (opcional, não é necessário especificar " +"explicitamente esta opção para remover revisões)" + msgid "force removal of changesets, discard uncommitted changes (no backup)" -msgstr "força a remoção de revisões, descarta mudanças não consolidadas (sem backup)" - -msgid "bundle only changesets with local revision number greater than REV which are not descendants of REV (DEPRECATED)" -msgstr "adiciona ao bundle apenas revisões cujo número local de revisão for maior que REV e que não forem seus descendentes (OBSOLETA)" +msgstr "" +"força a remoção de revisões, descarta mudanças não consolidadas (sem backup)" + +msgid "" +"bundle only changesets with local revision number greater than REV which are" +" not descendants of REV (DEPRECATED)" +msgstr "" +"adiciona ao bundle apenas revisões cujo número local de revisão for maior " +"que REV e que não forem seus descendentes (OBSOLETA)" msgid "no backups" msgstr "nenhuma cópia de segurança" @@ -5359,6 +5950,9 @@ msgid "list all available queues" msgstr "lista todas as filas disponíveis" +msgid "print name of active queue" +msgstr "imprime o nome da fila ativa" + msgid "create new queue" msgstr "cria uma nova fila" @@ -5387,12 +5981,14 @@ msgid "" " Omitting a queue name or specifying -l/--list will show you the registered\n" " queues - by default the \"normal\" patches queue is registered. The currently\n" -" active queue will be marked with \"(active)\"." +" active queue will be marked with \"(active)\". Specifying --active will print\n" +" only the name of the active queue." msgstr "" " Omitir um nome de fila ou especificar -l/--list fará com que o\n" " comando mostre as filas registradas - por padrão a fila de\n" " patches \"normal\" é registrada. A fila ativa no momento será\n" -" marcada com \"(ativa)\"." +" marcada com \"(ativa)\". Especificar --active fará com que apenas\n" +" o nome da fila ativa seja imprimido." msgid "" " To create a new queue, use -c/--create. The queue is automatically made\n" @@ -5492,118 +6088,64 @@ msgid "operate on patch repository" msgstr "opera no repositório de patches" -msgid "hooks for sending email notifications at commit/push time" -msgstr "gancho para enviar notificações por e-mail em commit/push" - -msgid "" -"Subscriptions can be managed through a hgrc file. Default mode is to\n" -"print messages to stdout, for testing and configuring." -msgstr "" -"Assinantes podem ser gerenciados através do arquivo hgrc. O modo padrão é\n" -"imprimir as mensagens para stdout, para testes e configuração." - -msgid "" -"To use, configure the notify extension and enable it in hgrc like\n" -"this::" -msgstr "" -"Para usar, configure e habilite a extensão notify no hgrc da seguinte\n" -"forma::" - -msgid "" -" [extensions]\n" -" notify =" -msgstr "" -" [extensions]\n" -" notify =" +msgid "hooks for sending email push notifications" +msgstr "gancho para enviar notificações por e-mail em um push" + +msgid "" +"This extension let you run hooks sending email notifications when\n" +"changesets are being pushed, from the sending or receiving side." +msgstr "" +"Esta extensão fornece ganchos para o envio de emails de notificação do\n" +"envio de revisões, tanto do lado que recebe como do lado que envia as\n" +"revisões." + +msgid "" +"First, enable the extension as explained in :hg:`help extensions`, and\n" +"register the hook you want to run. ``incoming`` and ``outgoing`` hooks\n" +"are run by the changesets receiver while the ``outgoing`` one is for\n" +"the sender::" +msgstr "" +"Em primeiro lugar, habilite a extensão como explicado em\n" +":hg:`help extensions`, e registre o gancho que você deseja executar.\n" +"O gancho ``outgoing`` é executado do lado que envia revisões; os\n" +"ganchos ``incoming`` e ``outgoing`` são executados do lado que recebe\n" +"as revisões::" msgid "" " [hooks]\n" " # one email for each incoming changeset\n" " incoming.notify = python:hgext.notify.hook\n" -" # batch emails when many changesets incoming at one time\n" -" changegroup.notify = python:hgext.notify.hook\n" -" # batch emails when many changesets outgoing at one time (client side)\n" -" outgoing.notify = python:hgext.notify.hook" +" # one email for all incoming changesets\n" +" changegroup.notify = python:hgext.notify.hook" msgstr "" " [hooks]\n" -" # um e-mail para cada revisão que chegar\n" +" # um e-mail para cada revisão recebida\n" " incoming.notify = python:hgext.notify.hook\n" -" # e-mails em lote quando muitas revisões chegarem de uma vez\n" -" changegroup.notify = python:hgext.notify.hook\n" -" # e-mails em lote quando muitas revisões saírem de uma vez\n" -" # (lado do cliente)\n" +" # um único e-mail para todas as revisões recebidas\n" +" changegroup.notify = python:hgext.notify.hook" + +msgid "" +" # one email for all outgoing changesets\n" +" outgoing.notify = python:hgext.notify.hook" +msgstr "" +" # um e-mail para todas as revisões enviadas\n" " outgoing.notify = python:hgext.notify.hook" msgid "" -" [notify]\n" -" # config items go here" -msgstr "" -" [notify]\n" -" # itens de configuração vão aqui" - -msgid "Required configuration items::" -msgstr "Itens de configuração necessários::" - -msgid " config = /path/to/file # file containing subscriptions" -msgstr " config = /caminho/arquivo # arquivo contendo assinantes" - -msgid "Optional configuration items::" -msgstr "Itens de configuração opcionais::" - -msgid "" -" test = True # print messages to stdout for testing\n" -" strip = 3 # number of slashes to strip for url paths\n" -" domain = example.com # domain to use if committer missing domain\n" -" style = ... # style file to use when formatting email\n" -" template = ... # template to use when formatting email\n" -" incoming = ... # template to use when run as incoming hook\n" -" outgoing = ... # template to use when run as outgoing hook\n" -" changegroup = ... # template to use when run as changegroup hook\n" -" maxdiff = 300 # max lines of diffs to include (0=none, -1=all)\n" -" maxsubject = 67 # truncate subject line longer than this\n" -" diffstat = True # add a diffstat before the diff content\n" -" sources = serve # notify if source of incoming changes in this list\n" -" # (serve == ssh or http, push, pull, bundle)\n" -" merge = False # send notification for merges (default True)\n" -" [email]\n" -" from = user@host.com # email address to send as if none given\n" -" [web]\n" -" baseurl = http://hgserver/... # root of hg web site for browsing commits" -msgstr "" -" test = True # imprime mensagens para stdout para teste\n" -" strip = 3 # número de barras a remover de URLs\n" -" domain = example.com # domínio a usar se autor não tiver domínio\n" -" style = ... # arquivo de estilo para formatar o e-mail\n" -" template = ... # modelo para formatar o e-mail\n" -" incoming = ... # modelo ao rodar como gancho de entrada\n" -" outgoing = ... # modelo ao rodar como gancho de saída\n" -" changegroup = ... # modelo ao rodar como gancho changegroup\n" -" maxdiff = 300 # no. máximo de linhas de diff incluídas\n" -" # (0=nenhuma, -1=todas)\n" -" maxsubject = 67 # trunca linhas de assunto maiores que isso\n" -" diffstat = True # adiciona um diffstat antes do diff\n" -" sources = serve # notifica se a fonte de mudanças recebidas\n" -" # estiver nessa lista\n" -" # (serve == ssh ou http, push, pull, bundle)\n" -" merge = False # envia notificação de mesclagens (padrão: True)\n" -" [email]\n" -" from = user@host.com # endereço de e-mail de envio se não houver\n" -" [web]\n" -" baseurl = http://hgserver/... # raiz do web site hg para\n" -" # visualizar consolidações" - -msgid "" -"The notify config file has same format as a regular hgrc file. It has\n" -"two sections so you can express subscriptions in whatever way is\n" -"handier for you." -msgstr "" -"O arquivo de configuração do notify tem o mesmo formato que um\n" -"hgrc comum. Possui duas seções, com isso você pode exprimir as\n" -"assinaturas do modo mais conveniente para você." +"Now the hooks are running, subscribers must be assigned to\n" +"repositories. Use the ``[usersubs]`` section to map repositories to a\n" +"given email or the ``[reposubs]`` section to map emails to a single\n" +"repository::" +msgstr "" +"Uma vez que os ganchos estejam instalados, os assinantes devem ser\n" +"inscritos. Use a seção ``[usersubs]`` para mapear repositórios para\n" +"um dado e-mail ou a seção ``[reposubs]`` para mapear e-mails para um\n" +"únioco repositório::" msgid "" " [usersubs]\n" -" # key is subscriber email, value is \",\"-separated list of glob patterns\n" +" # key is subscriber email, value is a comma-separated list of glob\n" +" # patterns\n" " user@host = pattern" msgstr "" " [usersubs]\n" @@ -5613,7 +6155,8 @@ msgid "" " [reposubs]\n" -" # key is glob pattern, value is \",\"-separated list of subscriber emails\n" +" # key is glob pattern, value is a comma-separated list of subscriber\n" +" # emails\n" " pattern = user@host" msgstr "" " [reposubs]\n" @@ -5621,16 +6164,189 @@ " # vírgulas de e-mails dos assinantes\n" " padrão = user@host" -msgid "Glob patterns are matched against path to repository root." -msgstr "Padrões glob são casados com o caminho da raiz do repositório." - -msgid "" -"If you like, you can put notify config file in repository that users\n" -"can push changes to, they can manage their own subscriptions.\n" -msgstr "" -"Se você quiser, você pode colocar o arquivo de configuração do\n" -"notify em um repositório com acesso de envio para os usuários,\n" -"de modo que eles possam gerenciar suas próprias assinaturas.\n" +msgid "" +"Glob patterns are matched against absolute path to repository\n" +"root. The subscriptions can be defined in their own file and\n" +"referenced with::" +msgstr "" +"Os padrões glob correspondem ao caminho absoluto da raiz do\n" +"repositório. As inscrições podem ser definidas em seu próprio\n" +"arquivo e referenciadas com::" + +msgid "" +" [notify]\n" +" config = /path/to/subscriptionsfile" +msgstr "" +" [notify]\n" +" config = /caminho/para/arquivo/de/assinantes" + +msgid "" +"Alternatively, they can be added to Mercurial configuration files by\n" +"setting the previous entry to an empty value." +msgstr "" +"Alternativamente, podem ser adicionados aos arquivos de configuração\n" +"do Mercurial definindo a entrada anterior para um valor vazio." + +msgid "" +"At this point, notifications should be generated but will not be sent until you\n" +"set the ``notify.test`` entry to ``False``." +msgstr "" +"Neste ponto, notificações serão geradas, mas não serão enviadas\n" +"até que você defina a entrada ``notify.test`` como ``False``." + +msgid "" +"Notifications content can be tweaked with the following configuration " +"entries:" +msgstr "" +"O conteúdo das notificações pode ser ajustado com as seguintes\n" +"entradas de configuração:" + +msgid "" +"notify.test\n" +" If ``True``, print messages to stdout instead of sending them. Default: True." +msgstr "" +"notify.test\n" +" Se ``True``, imprime as mensagens para a saída padrão, ao\n" +" invés de enviá-las. O padrão é True." + +msgid "" +"notify.sources\n" +" Space separated list of change sources. Notifications are sent only\n" +" if it includes the incoming or outgoing changes source. Incoming\n" +" sources can be ``serve`` for changes coming from http or ssh,\n" +" ``pull`` for pulled changes, ``unbundle`` for changes added by\n" +" :hg:`unbundle` or ``push`` for changes being pushed\n" +" locally. Outgoing sources are the same except for ``unbundle`` which\n" +" is replaced by ``bundle``. Default: serve." +msgstr "" +"notify.sources\n" +" Lista separada por espaços de origens das mudanças. As notificações\n" +" são enviadas apenas se esta lista incluir a origem das mudanças\n" +" enviadas ou recebidas. Mudanças recebidas podem ser ``serve`` para\n" +" mudanças provenientes de http ou ssh, ``pull`` para mudanças trazidas\n" +" por :hg:`pull`, ``unbundle`` para mudanças adicionadas por\n" +" :hg:`unbundle` ou ``push`` para mudanças sendo enviadas localmente.\n" +" As origens de saída são as mesmas, exceto por ``unbundle`` que é\n" +" substituída por ``bundle``. Padrão: serve." + +msgid "" +"notify.strip\n" +" Number of leading slashes to strip from url paths. By default, notifications\n" +" references repositories with their absolute path. ``notify.strip`` let you\n" +" turn them into relative paths. For example, ``notify.strip=3`` will change\n" +" ``/long/path/repository`` into ``repository``. Default: 0." +msgstr "" +"notify.strip\n" +" Número de barras \"/\" à esquerda a serem removidas de urls. Por\n" +" padrão, notificações referenciam repositórios usando caminhos\n" +" absolutos. ``notify.strip`` pode ser usado para suportar caminhos\n" +" relativos. Por exemplo, ``notify.strip=3`` mudará\n" +" ``/caminho/longo/repositorio`` para ``repositorio``. Padrão: 0." + +msgid "" +"notify.domain\n" +" If subscribers emails or the from email have no domain set, complete them\n" +" with this value." +msgstr "" +"notify.domain\n" +" Se os e-mails de assinantes ou do endereço de envio não tiverem um\n" +" domínio, eles serão completados usando este valor." + +msgid "" +"notify.style\n" +" Style file to use when formatting emails." +msgstr "" +"notify.style\n" +" O arquivo de estilo usado para formatar os e-mails." + +msgid "" +"notify.template\n" +" Template to use when formatting emails." +msgstr "" +"notify.template\n" +" O modelo usado para formatar os e-mails." + +msgid "" +"notify.incoming\n" +" Template to use when run as incoming hook, override ``notify.template``." +msgstr "" +"notify.incoming\n" +" O modelo usado ao executar o gancho incoming; sobrepõe\n" +" ``notify.template``." + +msgid "" +"notify.outgoing\n" +" Template to use when run as outgoing hook, override ``notify.template``." +msgstr "" +"notify.incoming\n" +" O modelo usado ao executar o gancho outgoing; sobrepõe\n" +" ``notify.template``." + +msgid "" +"notify.changegroup\n" +" Template to use when running as changegroup hook, override\n" +" ``notify.template``." +msgstr "" +"notify.changegroup\n" +" O modelo usado ao executar o gancho changegroup; sobrepõe\n" +" ``notify.template``." + +msgid "" +"notify.maxdiff\n" +" Maximum number of diff lines to include in notification email. Set to 0\n" +" to disable the diff, -1 to include all of it. Default: 300." +msgstr "" +"notify.maxdiff\n" +" Número máximo de linhas de diff incluídas no e-mail de notificação.\n" +" Use 0 para desabilitar o diff, e -1 para incluir o diff completo.\n" +" Padrão: 300." + +msgid "" +"notify.maxsubject\n" +" Maximum number of characters in emails subject line. Default: 67." +msgstr "" +"notify.maxsubject\n" +" Número máximo de caracteres na linha de assunto do e-mail. Padrão: 67." + +msgid "" +"notify.diffstat\n" +" Set to True to include a diffstat before diff content. Default: True." +msgstr "" +"notify.diffstat\n" +" Use True para incluir um diffstat antes do conteúdo do diff.\n" +" Padrão: True." + +msgid "" +"notify.merge\n" +" If True, send notifications for merge changesets. Default: True." +msgstr "" +"notify.merge\n" +" Se True, envia notificações para revisões de mesclagem. Padrão: True." + +msgid "" +"If set, the following entries will also be used to customize the " +"notifications:" +msgstr "" +"Se definidas, as seguintes entradas também serão usadas para\n" +"modificar as notificações:" + +msgid "" +"email.from\n" +" Email ``From`` address to use if none can be found in generated email content." +msgstr "" +"email.from\n" +" Endereço ``From`` do e-mail se um endereço não for encontrado\n" +" no conteúdo do e-mail gerado." + +msgid "" +"web.baseurl\n" +" Root repository browsing URL to combine with repository paths when making\n" +" references. See also ``notify.strip``." +msgstr "" +"web.baseurl\n" +" URL raiz de visualização do repositório a ser combinada com\n" +" o caminho do repositório ao criar referências. Veja também\n" +" ``notify.strip``." #, python-format msgid "%s: %d new changesets" @@ -5752,7 +6468,9 @@ "auto para comportamento normal.\n" msgid "when to paginate (boolean, always, auto, or never)" -msgstr "quando paginar (booleana, ou \"always\" (sempre), \"never\" (nunca) ou \"auto\" (automaticamente))" +msgstr "" +"quando paginar (booleana, ou \"always\" (sempre), \"never\" (nunca) ou " +"\"auto\" (automaticamente))" msgid "command to send changesets as (a series of) patch emails" msgstr "comando para enviar revisões como uma série de e-mails de patch" @@ -5843,13 +6561,6 @@ "Veja as seções [email] e [smtp] na página de manual hgrc(5) para\n" "mais detalhes.\n" -#, python-format -msgid "%s Please enter a valid value" -msgstr "%s Por favor forneça um valor válido" - -msgid "Please enter a valid value.\n" -msgstr "Por favor, entre um valor válido.\n" - msgid "send patches as attachments" msgstr "envia patches como anexos" @@ -5916,8 +6627,10 @@ msgid "run even when remote repository is unrelated (with -b/--bundle)" msgstr "executa mesmo se o repositório não for relacionado (com -b/--bundle)" -msgid "a base changeset to specify instead of a destination (with -b/--bundle)" -msgstr "uma revisão base especificada ao invés de um destino (com -b/--bundle)" +msgid "" +"a base changeset to specify instead of a destination (with -b/--bundle)" +msgstr "" +"uma revisão base especificada ao invés de um destino (com -b/--bundle)" msgid "send an introduction email for a single patch" msgstr "manda um e-mail introdutório para um patch único" @@ -6108,7 +6821,8 @@ msgstr "especifique ao menos uma revisão com -r ou -o" msgid "--outgoing mode always on with --bundle; do not re-specify --outgoing" -msgstr "modo é sempre --outgoing com --bundle; não especifique --outgoing novamente" +msgstr "" +"modo é sempre --outgoing com --bundle; não especifique --outgoing novamente" msgid "too many destinations" msgstr "muitos destinos" @@ -6127,6 +6841,9 @@ msgid "This patch series consists of %d patches." msgstr "Esta série de patches consiste de %d patches." +msgid "no recipient addresses provided" +msgstr "nenhum endereço de destinatário fornecido" + msgid "" "\n" "Final summary:" @@ -6181,6 +6898,9 @@ msgid "" " [progress]\n" " delay = 3 # number of seconds (float) before showing the progress bar\n" +" changedelay = 1 # changedelay: minimum delay before showing a new topic.\n" +" # If set to less than 3 * refresh, that value will\n" +" # be used instead.\n" " refresh = 0.1 # time in seconds between refreshes of the progress bar\n" " format = topic bar number estimate # format of the progress bar\n" " width = <none> # if set, the maximum width of the progress information\n" @@ -6192,6 +6912,9 @@ msgstr "" " [progress]\n" " delay = 3 # número de segundos (float) antes que a barra seja mostrada\n" +" changedelay = 1 # changedelay: atraso mínimo antes que um novo tópico\n" +" # seja mostrado. Se for definido para menos de\n" +" # 3 * refresh, tal valor será usado em seu lugar.\n" " refresh = 0.1 # tempo em segundos entre atualizações da\n" " # barra de progresso\n" " format = topic bar number estimate # formato da barra de progresso\n" @@ -6265,7 +6988,8 @@ msgstr "imprime os nomes de arquivo ao invés de removê-los" msgid "end filenames with NUL, for use with xargs (implies -p/--print)" -msgstr "termina nomes de arquivo com NUL, para uso com xargs (implica -p/--print)" +msgstr "" +"termina nomes de arquivo com NUL, para uso com xargs (implica -p/--print)" msgid "hg purge [OPTION]... [DIR]..." msgstr "hg purge [OPÇÃO]... [DIR]..." @@ -6362,8 +7086,15 @@ msgid "rebase from the specified changeset" msgstr "rebaseia a partir da revisão especificada" -msgid "rebase from the base of the specified changeset (up to greatest common ancestor of base and dest)" -msgstr "rebaseia a partir da base da revisão especificada (até o maior ancestral comum de base e dest)" +msgid "" +"rebase from the base of the specified changeset (up to greatest common " +"ancestor of base and dest)" +msgstr "" +"rebaseia a partir da base da revisão especificada (até o maior ancestral " +"comum de base e dest)" + +msgid "rebase these revisions" +msgstr "rebaseia estas revisões" msgid "rebase onto the specified changeset" msgstr "rebaseia sobre a revisão especificada" @@ -6374,6 +7105,9 @@ msgid "use text as collapse commit message" msgstr "usa o texto como mensagem de consolidação da revisão colapsada" +msgid "invoke editor on commit messages" +msgstr "chama um editor para mensagens de consolidação" + msgid "read collapse commit message from file" msgstr "lê de um arquivo a mensagem de consolidação da revisão colapsada" @@ -6527,15 +7261,29 @@ msgid "tool option will be ignored\n" msgstr "a opção tool será ignorada\n" +msgid "cannot specify both a source and a base" +msgstr "não se pode especificar ao mesmo tempo uma origem e uma base" + msgid "cannot specify both a revision and a base" msgstr "não se pode especificar ao mesmo tempo uma revisão e uma base" +msgid "cannot specify both a revision and a source" +msgstr "não se pode especificar ao mesmo tempo uma revisão e uma origem" + msgid "detach requires a revision to be specified" msgstr "detach exige que uma revisão seja especificada" msgid "cannot specify a base with detach" msgstr "não se pode especificar base com detach" +msgid "can't remove original changesets with unrebased descendants" +msgstr "" +"não é possível remover revisões originais que tenham descendentes não " +"rebaseados" + +msgid "use --keep to keep original changesets" +msgstr "use --keep para manter as revisões originais" + msgid "nothing to rebase\n" msgstr "nada para rebasear\n" @@ -6549,7 +7297,9 @@ msgstr "revisões" msgid "unresolved conflicts (see hg resolve, then hg rebase --continue)" -msgstr "conflitos não resolvidos (veja hg resolve, e em seguida hg rebase --continue)" +msgstr "" +"conflitos não resolvidos (veja hg resolve, e em seguida hg rebase " +"--continue)" #, python-format msgid "no changes, revision %d skipped\n" @@ -6559,7 +7309,8 @@ msgstr "mesclagem de rebaseamento completada\n" msgid "warning: new changesets detected on source branch, not stripping\n" -msgstr "aviso: novas revisões detectadas no ramo de origem, strip não realizado\n" +msgstr "" +"aviso: novas revisões detectadas no ramo de origem, strip não realizado\n" msgid "rebase completed\n" msgstr "rebaseamento completado\n" @@ -6579,7 +7330,9 @@ msgstr "nenhum rebaseamento em progresso" msgid "warning: new changesets detected on target branch, can't abort\n" -msgstr "aviso: novas revisões detectadas no ramo de destino, não é possível abortar\n" +msgstr "" +"aviso: novas revisões detectadas no ramo de destino, não é possível " +"abortar\n" msgid "rebase aborted\n" msgstr "rebaseamento abortado\n" @@ -6587,12 +7340,15 @@ msgid "cannot rebase onto an applied mq patch" msgstr "não se pode rebasear para um patch mq aplicado" +msgid "no matching revisions" +msgstr "nenhuma revisão correspondente" + +msgid "can't rebase multiple roots" +msgstr "não é possível rebasear múltiplas raízes" + msgid "source is ancestor of destination" msgstr "origem é ancestral do destino" -msgid "source is descendant of destination" -msgstr "origem é descendente do destino" - msgid "--tool can only be used with --rebase" msgstr "--tool só pode ser usada em conjunto com --rebase" @@ -6603,7 +7359,8 @@ msgstr "especifica o utilitário de mesclagem para o rebaseamento" msgid "commands to interactively select changes for commit/qrefresh" -msgstr "comandos para selecionar interativamente mudanças em um commit ou qrefresh" +msgstr "" +"comandos para selecionar interativamente mudanças em um commit ou qrefresh" msgid "ignore white space when comparing lines" msgstr "ignora espaços em branco ao comparar linhas" @@ -6720,7 +7477,8 @@ msgstr " ? - exibe o texto de ajuda" msgid " This command is not available when committing a merge." -msgstr " Este comando não está disponível para a consolidação de uma mesclagem." +msgstr "" +" Este comando não está disponível para a consolidação de uma mesclagem." msgid "interactively record a new patch" msgstr "grava um novo patch interativamente" @@ -6977,6 +7735,20 @@ " exista (por exemplo, a tip).\n" " " +msgid "convert a shared repository to a normal one" +msgstr "converte um repositório compartilhado para um repositório normal" + +msgid "" +" Copy the store data to the repo and remove the sharedpath data.\n" +" " +msgstr "" +" Copia os dados armazenados na origem e remove os dados\n" +" de compartilhamento de repositório.\n" +" " + +msgid "this is not a shared repo" +msgstr "este não é um repositório compartilhado" + msgid "do not create a working copy" msgstr "não cria uma cópia de trabalho" @@ -7098,7 +7870,8 @@ msgstr "filtra revisões através do comando" msgid "hg transplant [-s REPO] [-b BRANCH [-a]] [-p REV] [-m REV] [REV]..." -msgstr "hg transplant [-s REPOSITÓRIO] [-b RAMO [-a]] [-p REV] [-m REV] [REV]..." +msgstr "" +"hg transplant [-s REPOSITÓRIO] [-b RAMO [-a]] [-p REV] [-m REV] [REV]..." msgid "transplant changesets from another branch" msgstr "transplanta revisões de outro ramo" @@ -7295,7 +8068,8 @@ " encoding = sjis" msgid "It is useful for the users who want to commit with UTF-8 log message.\n" -msgstr "Isto é útil para usuários que preferem mensagens de consolidação em UTF-8.\n" +msgstr "" +"Isto é útil para usuários que preferem mensagens de consolidação em UTF-8.\n" #, python-format msgid "[win32mbcs] filename conversion failed with %s encoding\n" @@ -7350,7 +8124,9 @@ " ** = cleverdecode:\n" " # or ** = macdecode:" -msgid "If not doing conversion, to make sure you do not commit CRLF/CR by accident::" +msgid "" +"If not doing conversion, to make sure you do not commit CRLF/CR by " +"accident::" msgstr "" "Se a conversão não estiver sendo feita, para garantir que você não\n" "consolide CRLF/CR acidentalmente::" @@ -7395,7 +8171,9 @@ #, python-format msgid "Attempt to commit or push text file(s) using %s line endings\n" -msgstr "Tentativa de consolidação ou push de arquivo(s) texto usando quebras de linha %s\n" +msgstr "" +"Tentativa de consolidação ou push de arquivo(s) texto usando quebras de " +"linha %s\n" #, python-format msgid "in %s: %s\n" @@ -7439,8 +8217,11 @@ "[decode]\n" "** = %sdecode:\n" -msgid "win32text is deprecated: http://mercurial.selenic.com/wiki/Win32TextExtension\n" -msgstr "win32text é obsoleta: http://mercurial.selenic.com/wiki/Win32TextExtension\n" +msgid "" +"win32text is deprecated: " +"http://mercurial.selenic.com/wiki/Win32TextExtension\n" +msgstr "" +"win32text é obsoleta: http://mercurial.selenic.com/wiki/Win32TextExtension\n" msgid "discover and advertise repositories on the local network" msgstr "descobre e anuncia repositórios na rede local" @@ -7485,17 +8266,14 @@ msgid "archive prefix contains illegal components" msgstr "prefixo de arquivo contém componentes ilegais" -msgid "cannot give prefix when archiving to files" -msgstr "não é possível fornecer prefixo ao arquivar para arquivos" - -#, python-format -msgid "unknown archive type '%s'" -msgstr "tipo de arquivo '%s' desconhecido" - msgid "archiving" msgstr "empacotando" #, python-format +msgid "malformed line in .hg/bookmarks: %r\n" +msgstr "linha malformada em .hg/bookmarks: %r\n" + +#, python-format msgid "bookmark '%s' contains illegal character" msgstr "o marcador '%s' contém um caractere ilegal" @@ -7529,7 +8307,8 @@ #, python-format msgid "stream ended unexpectedly (got %d bytes, expected %d)" -msgstr "dados recebidos terminaram inesperadamente (%d bytes obtidos, %d esperados)" +msgstr "" +"dados recebidos terminaram inesperadamente (%d bytes obtidos, %d esperados)" #, python-format msgid "invalid chunk length %d" @@ -7554,6 +8333,10 @@ msgid "the name '%s' is reserved" msgstr "o nome '%s' é reservado" +#, python-format +msgid "uncommitted changes in subrepo %s" +msgstr "mudanças não consolidadas no sub-repositório %s" + msgid "options --message and --logfile are mutually exclusive" msgstr "opções --message e --logfile são mutuamente exclusivas" @@ -7575,10 +8358,12 @@ msgstr "não é possível especificar simultaneamente --changelog e --manifest" msgid "cannot specify filename with --changelog or --manifest" -msgstr "não é possível especificar um nome de arquivo com --changelog ou --manifest" +msgstr "" +"não é possível especificar um nome de arquivo com --changelog ou --manifest" msgid "cannot specify --changelog or --manifest without a repository" -msgstr "não é possível especificar --changelog ou --manifest sem um repositório" +msgstr "" +"não é possível especificar --changelog ou --manifest sem um repositório" msgid "invalid arguments" msgstr "argumentos inválidos" @@ -7640,9 +8425,6 @@ msgid "destination %s is not a directory" msgstr "o destino %s não é um diretório" -msgid "no files to copy" -msgstr "nenhum arquivo para copiar" - msgid "(consider using --after)\n" msgstr "(considere usar --after)\n" @@ -7725,7 +8507,9 @@ msgstr "não é possível seguir arquivo inexistente: \"%s\"" msgid "can only follow copies/renames for explicit filenames" -msgstr "é possível acompanhar cópias/renomeações apenas para nomes de arquivo explícitos" +msgstr "" +"é possível acompanhar cópias/renomeações apenas para nomes de arquivo " +"explícitos" #, python-format msgid "adding %s\n" @@ -7777,7 +8561,8 @@ msgstr "mensagem de consolidação vazia" msgid "repository root directory or name of overlay bundle file" -msgstr "diretório raiz do repositório ou nome de arquivo de bundle para sobreposição" +msgstr "" +"diretório raiz do repositório ou nome de arquivo de bundle para sobreposição" msgid "DIR" msgstr "DIR" @@ -7786,7 +8571,9 @@ msgstr "muda o diretório de trabalho" msgid "do not prompt, automatically pick the first choice for all prompts" -msgstr "não consulta o usuário, usa automaticamente a primeira opção em todas as escolhas" +msgstr "" +"não consulta o usuário, usa automaticamente a primeira opção em todas as " +"escolhas" msgid "suppress output" msgstr "suprime saída" @@ -7843,7 +8630,9 @@ msgstr "especifica comando hg para executar do lado remoto" msgid "do not verify server certificate (ignoring web.cacerts config)" -msgstr "não verifica o certificado do servidor (ignorando a opção de configuração web.cacerts)" +msgstr "" +"não verifica o certificado do servidor (ignorando a opção de configuração " +"web.cacerts)" msgid "PATTERN" msgstr "PADRÃO" @@ -8114,6 +8903,21 @@ " O tipo de arquivo é detectado automaticamente com base na extensão\n" " do arquivo (ou forçado através de -t/--type)." +msgid " Examples:" +msgstr " Exemplos::" + +msgid " - create a zip file containing the 1.0 release::" +msgstr " - cria um arquivo zip contendo a versão 1.0::" + +msgid " hg archive -r 1.0 project-1.0.zip" +msgstr " hg archive -r 1.0 project-1.0.zip" + +msgid " - create a tarball excluding .hg files::" +msgstr " - cria um tarball excluindo arquivos .hg::" + +msgid " hg archive project.tar.gz -X \".hg*\"" +msgstr " hg archive project.tar.gz -X \".hg*\"" + msgid " Valid types are:" msgstr " Tipos válidos:" @@ -8163,8 +8967,8 @@ msgid "merge with old dirstate parent after backout" msgstr "mesclar com pai do dirstate anterior após o backout" -msgid "parent to choose when backing out merge" -msgstr "pai a ser escolhido ao fazer o backout de mesclagem" +msgid "parent to choose when backing out merge (DEPRECATED)" +msgstr "pai a ser escolhido ao fazer o backout de mesclagem (OBSOLETO)" msgid "revision to backout" msgstr "revisão para fazer o backout" @@ -8193,26 +8997,35 @@ " manualmente." msgid "" -" By default, the pending changeset will have one parent,\n" -" maintaining a linear history. With --merge, the pending changeset\n" -" will instead have two parents: the old parent of the working\n" -" directory and a new child of REV that simply undoes REV." -msgstr "" -" Por padrão, a revisão pendente terá apenas um pai, mantendo assim\n" -" um histórico linear. Se a opção --merge for usada, a revisão\n" -" pendente terá dois pais: o antigo pai do diretório de trabalho e\n" -" uma nova revisão filha de REV que desfaz o conteúdo de REV." - -msgid "" -" Before version 1.7, the behavior without --merge was equivalent to\n" -" specifying --merge followed by :hg:`update --clean .` to cancel\n" -" the merge and leave the child of REV as a head to be merged\n" -" separately." -msgstr "" -" Antes da versao 1.7 do Mercurial, o comportamento do comando\n" -" backout sem --merge era equivalente a especificar --merge seguido por\n" -" :hg:`update --clean .`, cancelando a mesclagem e deixando a filha\n" -" de REV como uma cabeça a ser mesclada explicitamente." +" .. note::\n" +" backout cannot be used to fix either an unwanted or\n" +" incorrect merge." +msgstr "" +" .. note::\n" +" backout não pode ser usado para corrigir uma mesclagem\n" +" incorreta ou indesejada." + +msgid "" +" By default, the pending changeset will have one parent,\n" +" maintaining a linear history. With --merge, the pending\n" +" changeset will instead have two parents: the old parent of the\n" +" working directory and a new child of REV that simply undoes REV." +msgstr "" +" Por padrão, a revisão pendente terá apenas um pai, mantendo assim\n" +" um histórico linear. Se a opção --merge for usada, a revisão\n" +" pendente terá dois pais: o antigo pai do diretório de trabalho e\n" +" uma nova revisão filha de REV que desfaz o conteúdo de REV." + +msgid "" +" Before version 1.7, the behavior without --merge was equivalent\n" +" to specifying --merge followed by :hg:`update --clean .` to\n" +" cancel the merge and leave the child of REV as a head to be\n" +" merged separately." +msgstr "" +" Antes da versao 1.7 do Mercurial, o comportamento do comando\n" +" backout sem --merge era equivalente a especificar --merge seguido por\n" +" :hg:`update --clean .`, cancelando a mesclagem e deixando a filha\n" +" de REV como uma cabeça a ser mesclada explicitamente." msgid "please specify just one revision" msgstr "por favor especifique apenas uma revisão" @@ -8226,8 +9039,8 @@ msgid "cannot backout a change with no parents" msgstr "não se pode anular uma mudança sem pais" -msgid "cannot backout a merge changeset without --parent" -msgstr "não se pode anular uma revisão de mesclagem sem --parent" +msgid "cannot backout a merge changeset" +msgstr "não se pode anular revisões de mesclagem" #, python-format msgid "%s is not a parent of %s" @@ -8312,6 +9125,101 @@ " abortará a bissecção, e qualquer outro código maior que 0\n" " marcará a revisão como ruim." +msgid " Some examples:" +msgstr " Alguns exemplos::" + +msgid "" +" - start a bisection with known bad revision 12, and good revision 34::" +msgstr "" +" - inicia uma bissecção com a revisão ruim 12, e a revisão boa 34::" + +msgid "" +" hg bisect --bad 34\n" +" hg bisect --good 12" +msgstr "" +" hg bisect --bad 34\n" +" hg bisect --good 12" + +msgid "" +" - advance the current bisection by marking current revision as good or\n" +" bad::" +msgstr "" +" - avança a bisecção atual marcando a revisão atual como\n" +" boa ou ruim::" + +msgid "" +" hg bisect --good\n" +" hg bisect --bad" +msgstr "" +" hg bisect --good\n" +" hg bisect --bad" + +msgid "" +" - mark the current revision, or a known revision, to be skipped (eg. if\n" +" that revision is not usable because of another issue)::" +msgstr "" +" - marca a revisão atual, ou uma revisão conhecida, para que\n" +" seja omitida (por exemplo, se tal revisão não for usável\n" +" devido a algum outro problema)::" + +msgid "" +" hg bisect --skip\n" +" hg bisect --skip 23" +msgstr "" +" hg bisect --skip\n" +" hg bisect --skip 23" + +msgid " - forget the current bisection::" +msgstr " - esquece a bisecção atual::" + +msgid " hg bisect --reset" +msgstr " hg bisect --reset" + +msgid "" +" - use 'make && make tests' to automatically find the first broken\n" +" revision::" +msgstr "" +" - usa 'make && make tests' para encontrar a primeira revisão\n" +" quebrada automaticamente::" + +msgid "" +" hg bisect --reset\n" +" hg bisect --bad 34\n" +" hg bisect --good 12\n" +" hg bisect --command 'make && make tests'" +msgstr "" +" hg bisect --reset\n" +" hg bisect --bad 34\n" +" hg bisect --good 12\n" +" hg bisect --command 'make && make tests'" + +msgid "" +" - see all changesets whose states are already known in the current\n" +" bisection::" +msgstr "" +" - mostra todas as revisões cujos estados já são conhecidos\n" +" na bisecção atual::" + +msgid " hg log -r \"bisect(pruned)\"" +msgstr " hg log -r \"bisect(pruned)\"" + +msgid " - see all changesets that took part in the current bisection::" +msgstr " - mostra todas as revisões que tomam parte na bisecção atual::" + +msgid " hg log -r \"bisect(range)\"" +msgstr " hg log -r \"bisect(range)\"" + +msgid " - with the graphlog extension, you can even get a nice graph::" +msgstr " - a extensão graphlog pode inclusive fornecer um grafo::" + +msgid " hg log --graph -r \"bisect(range)\"" +msgstr " hg log --graph -r \"bisect(range)\"" + +msgid " See :hg:`help revsets` for more about the `bisect()` keyword." +msgstr "" +" Veja :hg:`help revsets` para mais informações sobre a palavra\n" +" chave `bisect()`." + msgid "The first good revision is:\n" msgstr "A primeira revisão boa é:\n" @@ -8329,10 +9237,14 @@ "ancestral comum, %s.\n" msgid "Due to skipped revisions, the first good revision could be any of:\n" -msgstr "Devido a revisões omitidas, a primeira revisão boa pode ser qualquer uma entre:\n" +msgstr "" +"Devido a revisões omitidas, a primeira revisão boa pode ser qualquer uma " +"entre:\n" msgid "Due to skipped revisions, the first bad revision could be any of:\n" -msgstr "Devido a revisões omitidas, a primeira revisão ruim pode ser qualquer uma entre:\n" +msgstr "" +"Devido a revisões omitidas, a primeira revisão ruim pode ser qualquer uma " +"entre:\n" msgid "cannot bisect (no known good revisions)" msgstr "não é possível fazer o bisect (nenhuma revisão boa conhecida)" @@ -8500,14 +9412,13 @@ " fechado.\n" " " -msgid " .. note::" -msgstr " .. note::" - -msgid "" +msgid "" +" .. note::\n" " Branch names are permanent. Use :hg:`bookmark` to create a\n" " light-weight bookmark instead. See :hg:`help glossary` for more\n" " information about named branches and bookmarks." msgstr "" +" .. note::\n" " Nomes de ramos são permanentes. Alternativamente, Use :hg:`bookmark`\n" " para criar um marcador leve temporário. Veja :hg:`help glossary`\n" " para mais informações sobre ramos nomeados e marcadores." @@ -8734,124 +9645,169 @@ " repositório, como o padrão a ser usado para futuros comandos\n" " pull." -msgid " See :hg:`help urls` for valid source format details." -msgstr " Veja :hg:`help urls` para formatos válidos da origem." - -msgid "" -" It is possible to specify an ``ssh://`` URL as the destination, but no\n" -" ``.hg/hgrc`` and working directory will be created on the remote side.\n" -" Please see :hg:`help urls` for important details about ``ssh://`` URLs." -msgstr "" -" É possível especificar uma URL ``ssh://`` como destino, mas o\n" -" ``.hg/hgrc`` e a cópia de trabalho não serão criados do lado remoto.\n" -" Por favor veja :hg:`help urls` para detalhes importantes sobre\n" -" URLs ``ssh://`` ." - -msgid "" -" A set of changesets (tags, or branch names) to pull may be specified\n" -" by listing each changeset (tag, or branch name) with -r/--rev.\n" -" If -r/--rev is used, the cloned repository will contain only a subset\n" -" of the changesets of the source repository. Only the set of changesets\n" -" defined by all -r/--rev options (including all their ancestors)\n" -" will be pulled into the destination repository.\n" -" No subsequent changesets (including subsequent tags) will be present\n" -" in the destination." -msgstr "" -" Um conjunto de revisões (etiquetas, ou nomes de ramo) a serem trazidas\n" -" pode ser especificado listando cada revisão (etiqueta, ou nome de\n" -" ramo) com -r/--rev. Se -r/--rev for usado, o repositório clonado irá\n" -" conter apenas um subconjunto das revisões do repositório de origem.\n" -" Apenas o conjunto de revisões definidas por todas as opções -r/--rev\n" -" (incluindo todos os seus ancestrais) será trazido para o repositório\n" -" de destino. Nenhuma revisão subsequente (incluindo etiquetas\n" -" subsequentes) estará presente no repositório." - -msgid "" -" Using -r/--rev (or 'clone src#rev dest') implies --pull, even for\n" -" local source repositories." -msgstr "" -" A opção -r/--rev (ou 'clone origem#revisão destino') implica --pull,\n" -" mesmo em repositórios locais." - -msgid "" -" For efficiency, hardlinks are used for cloning whenever the source\n" -" and destination are on the same filesystem (note this applies only\n" -" to the repository data, not to the working directory). Some\n" -" filesystems, such as AFS, implement hardlinking incorrectly, but\n" -" do not report errors. In these cases, use the --pull option to\n" -" avoid hardlinking." -msgstr "" -" Por eficiência, hardlinks são usados para a clonagem sempre que a\n" -" origem e o destino estiverem no mesmo sistema de arquivos (note\n" -" que isso se aplica apenas aos dados do repositório, e não aos\n" -" arquivos da cópia de trabalho). Alguns sistemas de arquivo, como\n" -" o AFS, implementam hardlinks incorretamente, mas não informam\n" -" erros. Nesses casos, use a opção --pull para evitar o uso de\n" -" hardlinks." - -msgid "" -" In some cases, you can clone repositories and the working directory\n" -" using full hardlinks with ::" -msgstr "" -" Em alguns casos, você pode clonar repositórios e o diretório de\n" -" trabalho usando hardlinks completos com ::" - -msgid " $ cp -al REPO REPOCLONE" -msgstr " $ cp -al REPO REPOCLONE" - -msgid "" -" This is the fastest way to clone, but it is not always safe. The\n" -" operation is not atomic (making sure REPO is not modified during\n" -" the operation is up to you) and you have to make sure your editor\n" -" breaks hardlinks (Emacs and most Linux Kernel tools do so). Also,\n" -" this is not compatible with certain extensions that place their\n" -" metadata under the .hg directory, such as mq." -msgstr "" -" Este é o jeito mais rápido de clonar, mas não é sempre seguro. A\n" -" operação não é atômica (garantir que REPO não seja modificado\n" -" durante a operação é sua responsabilidade) e você deve ter\n" -" certeza que seu editor quebre hardlinks (o Emacs e muitos\n" -" utilitários do kernel Linux fazem isso). Além disso, esse modo de\n" -" criar um clone não é compatível com certas extensões que colocam\n" -" seus metadados sob o diretório hg, como a mq." - -msgid "" -" Mercurial will update the working directory to the first applicable\n" -" revision from this list:" -msgstr "" -" O Mercurial atualizará o diretório de trabalho para a primeira revisão\n" -" aplicável da seguinte lista:" - -msgid "" -" a) null if -U or the source repository has no changesets\n" -" b) if -u . and the source repository is local, the first parent of\n" -" the source repository's working directory\n" -" c) the changeset specified with -u (if a branch name, this means the\n" -" latest head of that branch)\n" -" d) the changeset specified with -r\n" -" e) the tipmost head specified with -b\n" -" f) the tipmost head specified with the url#branch source syntax\n" -" g) the tipmost head of the default branch\n" -" h) tip" -msgstr "" -" a) null, se for passada a opção -U ou se o repositório de origem não\n" -" tiver revisões\n" -" b) o primeiro pai do diretório de trabalho do repositório de origem,\n" -" se for passada a opção -u e o repositório de origem for local\n" -" c) a revisão especificada por -u (se for um nome de ramo, é a última\n" -" cabeça de tal ramo)\n" -" d) a revisão especificada com -r\n" -" e) a cabeça mais recente especificada com -b\n" -" f) a cabeça mais recente especificada com a sintaxe de origem\n" -" url#ramo\n" -" g) a cabeça mais recente do ramo default\n" -" h) a tip" +msgid "" +" Only local paths and ``ssh://`` URLs are supported as\n" +" destinations. For ``ssh://`` destinations, no working directory or\n" +" ``.hg/hgrc`` will be created on the remote side." +msgstr "" +" Apenas caminhos locais e URLs ``ssh://`` são suportados no\n" +" destino. Para destinos ``ssh://``, a cópia de trabalho e arquivo\n" +" ``.hg/hgrc`` não serão criados no repositório remoto." + +msgid "" +" To pull only a subset of changesets, specify one or more revisions\n" +" identifiers with -r/--rev or branches with -b/--branch. The\n" +" resulting clone will contain only the specified changesets and\n" +" their ancestors. These options (or 'clone src#rev dest') imply\n" +" --pull, even for local source repositories. Note that specifying a\n" +" tag will include the tagged changeset but not the changeset\n" +" containing the tag." +msgstr "" +" Para trazer apenas um subconjunto de revisões, especifique um\n" +" ou mais identificadores de revisão com -r/--rev ou remos com\n" +" -b/--branch. O clone resultante conterá apenas as revisões\n" +" especificadas e seus ancestrais. Estas opções (ou\n" +" 'clone origem#rev dest') impicam --pull, mesmo para repositórios\n" +" locais. Note que especificar uma etiqueta incluirá a revisão\n" +" etiquetada mas não incluirá a revisão que define a etiqueta em si." + +msgid "" +" To check out a particular version, use -u/--update, or\n" +" -U/--noupdate to create a clone with no working directory." +msgstr "" +" Para obter uma revisão em particular, use -u/--update, ou\n" +" -U/--noupdate para criar um clone sem um diretório de trabalho." + +msgid "" +" For efficiency, hardlinks are used for cloning whenever the\n" +" source and destination are on the same filesystem (note this\n" +" applies only to the repository data, not to the working\n" +" directory). Some filesystems, such as AFS, implement hardlinking\n" +" incorrectly, but do not report errors. In these cases, use the\n" +" --pull option to avoid hardlinking." +msgstr "" +" Por eficiência, hardlinks são usados para a clonagem sempre que a\n" +" origem e o destino estiverem no mesmo sistema de arquivos (note\n" +" que isso se aplica apenas aos dados do repositório, e não aos\n" +" arquivos da cópia de trabalho). Alguns sistemas de arquivo, como\n" +" o AFS, implementam hardlinks incorretamente, mas não informam\n" +" erros. Nesses casos, use a opção --pull para evitar o uso de\n" +" hardlinks." + +msgid "" +" In some cases, you can clone repositories and the working\n" +" directory using full hardlinks with ::" +msgstr "" +" Em alguns casos, você pode clonar repositórios e o diretório de\n" +" trabalho usando hardlinks completos com ::" + +msgid " $ cp -al REPO REPOCLONE" +msgstr " $ cp -al REPO REPOCLONE" + +msgid "" +" This is the fastest way to clone, but it is not always safe. The\n" +" operation is not atomic (making sure REPO is not modified during\n" +" the operation is up to you) and you have to make sure your\n" +" editor breaks hardlinks (Emacs and most Linux Kernel tools do\n" +" so). Also, this is not compatible with certain extensions that\n" +" place their metadata under the .hg directory, such as mq." +msgstr "" +" Este é o jeito mais rápido de clonar, mas não é sempre seguro. A\n" +" operação não é atômica (garantir que REPO não seja modificado\n" +" durante a operação é sua responsabilidade) e você deve ter\n" +" certeza que seu editor quebre hardlinks (o Emacs e muitos\n" +" utilitários do kernel Linux fazem isso). Além disso, esse modo de\n" +" criar um clone não é compatível com certas extensões que colocam\n" +" seus metadados sob o diretório hg, como a mq." + +msgid "" +" Mercurial will update the working directory to the first applicable\n" +" revision from this list:" +msgstr "" +" O Mercurial atualizará o diretório de trabalho para a primeira revisão\n" +" aplicável da seguinte lista:" + +msgid "" +" a) null if -U or the source repository has no changesets\n" +" b) if -u . and the source repository is local, the first parent of\n" +" the source repository's working directory\n" +" c) the changeset specified with -u (if a branch name, this means the\n" +" latest head of that branch)\n" +" d) the changeset specified with -r\n" +" e) the tipmost head specified with -b\n" +" f) the tipmost head specified with the url#branch source syntax\n" +" g) the tipmost head of the default branch\n" +" h) tip" +msgstr "" +" a) null, se for passada a opção -U ou se o repositório de origem não\n" +" tiver revisões\n" +" b) o primeiro pai do diretório de trabalho do repositório de origem,\n" +" se for passada a opção -u e o repositório de origem for local\n" +" c) a revisão especificada por -u (se for um nome de ramo, é a última\n" +" cabeça de tal ramo)\n" +" d) a revisão especificada com -r\n" +" e) a cabeça mais recente especificada com -b\n" +" f) a cabeça mais recente especificada com a sintaxe de origem\n" +" url#ramo\n" +" g) a cabeça mais recente do ramo default\n" +" h) a tip" + +msgid " - clone a remote repository to a new directory named hg/::" +msgstr "" +" - clona um repositório remoto para um novo diretório chamado hg/::" + +msgid " hg clone http://selenic.com/hg" +msgstr " hg clone http://selenic.com/hg" + +msgid " - create a lightweight local clone::" +msgstr " - cria um clone leve local::" + +msgid " hg clone project/ project-feature/" +msgstr " hg clone project/ project-feature/" + +msgid "" +" - clone from an absolute path on an ssh server (note double-slash)::" +msgstr "" +" - clona um caminho absoluto em um servidor ssh (note as barras\n" +" duplicadas)::" + +msgid " hg clone ssh://user@server//home/projects/alpha/" +msgstr " hg clone ssh://user@server//home/projects/alpha/" + +msgid "" +" - do a high-speed clone over a LAN while checking out a\n" +" specified version::" +msgstr "" +" - faz um clone em alta velocidade em uma LAN e obtém uma\n" +" revisão específica::" + +msgid " hg clone --uncompressed http://server/repo -u 1.5" +msgstr " hg clone --uncompressed http://server/repo -u 1.5" + +msgid "" +" - create a repository without changesets after a particular revision::" +msgstr "" +" - cria um repositório sem revisões após uma revisão em particular::" + +msgid " hg clone -r 04e544 experimental/ good/" +msgstr " hg clone -r 04e544 experimental/ good/" + +msgid " - clone (and track) a particular named branch::" +msgstr " - clona (e rastreia) um ramo nomeado em particular::" + +msgid " hg clone http://selenic.com/hg#stable" +msgstr " hg clone http://selenic.com/hg#stable" + +msgid " See :hg:`help urls` for details on specifying URLs." +msgstr " Veja :hg:`help urls` para detalhes sobre a especificação de URLs." msgid "cannot specify both --noupdate and --updaterev" msgstr "não se pode especificar ao mesmo tempo ---noupdate e --updaterev" msgid "mark new/missing files as added/removed before committing" -msgstr "marca arquivos novos/ausentes como adicionados/removidos antes da consolidação" +msgstr "" +"marca arquivos novos/ausentes como adicionados/removidos antes da " +"consolidação" msgid "mark a branch as closed, hiding it from the branch list" msgstr "marca um ramo como fechado, escondendo-o da lista de ramos" @@ -8988,7 +9944,9 @@ msgstr "[OPÇÃO]... [TEXTO]" msgid "builds a repo with a given DAG from scratch in the current empty repo" -msgstr "constrói um repositório do zero com um DAG dado em um repositório vazio existente" +msgstr "" +"constrói um repositório do zero com um DAG dado em um repositório vazio " +"existente" msgid "" " The description of the DAG is read from stdin if not given on the\n" @@ -9119,7 +10077,8 @@ msgstr "[OPÇÃO]... [ARQUIVO [REVISÃO]...]" msgid "format the changelog or an index DAG as a concise textual description" -msgstr "formata o changelog ou um índice DAG como uma representação textual concisa" +msgstr "" +"formata o changelog ou um índice DAG como uma representação textual concisa" msgid "" " If you pass a revlog index, the revlog's DAG is emitted. If you list\n" @@ -9248,8 +10207,9 @@ msgid " (check that you compiled the extensions)\n" msgstr " (verifique se você compilou as extensões)\n" -msgid "Checking templates...\n" -msgstr "Verificando modelos...\n" +#, python-format +msgid "Checking templates (%s)...\n" +msgstr "Verificando modelos (%s)...\n" msgid " (templates seem to have been installed incorrectly)\n" msgstr " (modelos parecem ter sido instalados incorretamente)\n" @@ -9258,10 +10218,13 @@ msgstr "Verificando editor para consolidação...\n" msgid " No commit editor set and can't find vi in PATH\n" -msgstr " Nenhum editor para consolidação configurado, e não foi possível encontrar 'vi' no PATH\n" +msgstr "" +" Nenhum editor para consolidação configurado, e não foi possível encontrar " +"'vi' no PATH\n" msgid " (specify a commit editor in your configuration file)\n" -msgstr " (especifique um editor para consolidação em seu arquivo de configuração)\n" +msgstr "" +" (especifique um editor para consolidação em seu arquivo de configuração)\n" #, python-format msgid " Can't find editor '%s' in PATH\n" @@ -9439,6 +10402,51 @@ " Use a opção -g/--git para gerar diffs no formato estendido\n" " \"git diff\". Leia :hg:`help diffs` para mais informações." +msgid "" +" - compare a file in the current working directory to its parent::" +msgstr "" +" - compara um arquivo no diretório de trabalho atual com seu pai::" + +msgid " hg diff foo.c" +msgstr " hg diff foo.c" + +msgid "" +" - compare two historical versions of a directory, with rename info::" +msgstr "" +" - compara duas versões históricas de um diretório, com\n" +" informações de renomeação::" + +msgid " hg diff --git -r 1.0:1.2 lib/" +msgstr " hg diff --git -r 1.0:1.2 lib/" + +msgid " - get change stats relative to the last change on some date::" +msgstr "" +" - obtém estatísticas de modificações relativas à última\n" +" mudança em alguma data::" + +msgid " hg diff --stat -r \"date('may 2')\"" +msgstr " hg diff --stat -r \"date('may 2')\"" + +msgid " - diff all newly-added files that contain a keyword::" +msgstr "" +" - faz diff de todos os arquivos recém-adicionados que\n" +" contenham uma palavra chave::" + +msgid " hg diff \"set:added() and grep(GNU)\"" +msgstr " hg diff \"set:added() and grep(GNU)\"" + +msgid " - compare a revision and its parents::" +msgstr " - compara uma revisão com seus pais::" + +msgid "" +" hg diff -c 9353 # compare against first parent\n" +" hg diff -r 9353^:9353 # same using revset syntax\n" +" hg diff -r 9353^2:9353 # compare against the second parent" +msgstr "" +" hg diff -c 9353 # compara com o primeiro pai\n" +" hg diff -r 9353^:9353 # o mesmo, usando sintaxe revset\n" +" hg diff -r 9353^2:9353 # compara com o segundo pai" + msgid "diff against the second parent" msgstr "faz o diff com o segundo pai" @@ -9491,6 +10499,7 @@ " :``%R``: changeset revision number\n" " :``%b``: basename of the exporting repository\n" " :``%h``: short-form changeset hash (12 hexadecimal digits)\n" +" :``%m``: first line of the commit message (only alphanumeric characters)\n" " :``%n``: zero-padded sequence number, starting at 1\n" " :``%r``: zero-padded changeset revision number" msgstr "" @@ -9500,6 +10509,7 @@ " :``%R``: número de ordem da revisão\n" " :``%b``: nome base do repositório onde o export é realizado\n" " :``%h``: hash de forma curta da revisão (12 bytes hexadecimais)\n" +" :``%m``: primeira linha da mensagem de consolidação (apenas caracteres alfanuméricos)\n" " :``%n``: número sequencial completado com zeros, começando em 1\n" " :``%r``: número de ordem da revisão completado com zeros" @@ -9526,6 +10536,36 @@ " Com a opção --switch-parent, o diff será feito em relação ao\n" " segundo pai. Isso pode ser útil para avaliar uma mesclagem." +msgid "" +" - use export and import to transplant a bugfix to the current\n" +" branch::" +msgstr "" +" - usa export e import para transplantar uma correção para o ramo\n" +" atual::" + +msgid " hg export -r 9353 | hg import -" +msgstr " hg export -r 9353 | hg import -" + +msgid "" +" - export all the changesets between two revisions to a file with\n" +" rename information::" +msgstr "" +" - exporta todas as revisões entre duas revisões específicas para\n" +" um arquivo com informações de renomeação::" + +msgid " hg export --git -r 123:150 > changes.txt" +msgstr " hg export --git -r 123:150 > changes.txt" + +msgid "" +" - split outgoing changes into a series of patches with\n" +" descriptive names::" +msgstr "" +" - separa mudanças a serem enviadas em uma série de patches com\n" +" nomes descritivos::" + +msgid " hg export -r \"outgoing()\" -o \"%n-%m.patch\"" +msgstr " hg export -r \"outgoing()\" -o \"%n-%m.patch\"" + msgid "export requires at least one changeset" msgstr "export exige ao menos uma revisão" @@ -9554,18 +10594,139 @@ " histórico do projeto, nem os apaga do diretório de trabalho." msgid " To undo a forget before the next commit, see :hg:`add`." -msgstr " Para desfazer um forget antes da próxima consolidação, veja :hg:`add`." - -msgid "no files specified" -msgstr "nenhum arquivo especificado" - -#, python-format -msgid "not removing %s: file is already untracked\n" -msgstr "%s não removido: arquivo já não é rastreado\n" - -#, python-format -msgid "removing %s\n" -msgstr "removendo %s\n" +msgstr "" +" Para desfazer um forget antes da próxima consolidação, veja :hg:`add`." + +msgid " - forget newly-added binary files::" +msgstr " - esquece arquivos binários recém adicionados::" + +msgid " hg forget \"set:added() and binary()\"" +msgstr " hg forget \"set:added() and binary()\"" + +msgid " - forget files that would be excluded by .hgignore::" +msgstr " - esquece arquivos que seriam excluídos por .hgignore::" + +msgid " hg forget \"set:hgignore()\"" +msgstr " hg forget \"set:hgignore()\"" + +msgid "resume interrupted graft" +msgstr "continua um enxerto interrompido" + +msgid "record the current date as commit date" +msgstr "grava a data atual como data da consolidação" + +msgid "record the current user as committer" +msgstr "grava o usuário atual como autor da consolidação" + +msgid "[OPTION]... REVISION..." +msgstr "[OPÇÃO]... REVISÃO..." + +msgid "copy changes from other branches onto the current branch" +msgstr "copia mudanças de outros ramos para o ramo atual" + +msgid "" +" This command uses Mercurial's merge logic to copy individual\n" +" changes from other branches without merging branches in the\n" +" history graph. This is sometimes known as 'backporting' or\n" +" 'cherry-picking'. By default, graft will copy user, date, and\n" +" description from the source changesets." +msgstr "" +" Este comando usa a lógica de mesclagens do Mercurial para\n" +" copiar mudanças individuais de outros ramos sem mesclar\n" +" os ramos no grafo de histórico. Isto é por vezes chamado de\n" +" 'backporting' ou 'cherry-picking'. Por padrão, graft\n" +" copiará o usuário, data e descrição das revisões de\n" +" origem." + +msgid "" +" Changesets that are ancestors of the current revision, that have\n" +" already been grafted, or that are merges will be skipped." +msgstr "" +" Serão omitidas revisões ancestrais da revisão atual, já\n" +" enxertadas ou mesclagens." + +msgid "" +" If a graft merge results in conflicts, the graft process is\n" +" aborted so that the current merge can be manually resolved. Once\n" +" all conflicts are addressed, the graft process can be continued\n" +" with the -c/--continue option." +msgstr "" +" Se a mesclagem de enxerto resultar em conflitos, o processo de\n" +" enxerto será abortado para que a mesclagem atual possa ser\n" +" resolvida manualmente. Uma vez que todos os conflitos estejam\n" +" resolvidos, o processo de enxerto pode ser retomado usando a\n" +" opção -c/--continue." + +msgid "" +" .. note::\n" +" The -c/--continue option does not reapply earlier options." +msgstr "" +" .. note::\n" +" A opção -c/--continue não reaplica opções anteriores." + +msgid "" +" - copy a single change to the stable branch and edit its description::" +msgstr "" +" - copia uma única mudança para o ramo stable e edita sua descrição::" + +msgid "" +" hg update stable\n" +" hg graft --edit 9393" +msgstr "" +" hg update stable\n" +" hg graft --edit 9393" + +msgid "" +" - graft a range of changesets with one exception, updating dates::" +msgstr "" +" - enxerta uma faixa de revisões com uma exceção, atualizando as " +"datas::" + +msgid " hg graft -D \"2085::2093 and not 2091\"" +msgstr " hg graft -D \"2085::2093 and not 2091\"" + +msgid " - continue a graft after resolving conflicts::" +msgstr " - continua um processo de enxerto após resolver conflitos::" + +msgid " hg graft -c" +msgstr " hg graft -c" + +msgid " - show the source of a grafted changeset::" +msgstr " - mostra a origem de uma revisão enxertada::" + +msgid " hg log --debug -r tip" +msgstr " hg log --debug -r tip" + +msgid "" +" Returns 0 on successful completion.\n" +" " +msgstr "" +" Devolve 0 para indicar sucesso.\n" +" " + +msgid "can't specify --continue and revisions" +msgstr "não é possível especificar --continue e revisões" + +msgid "no graft state found, can't continue" +msgstr "estado de graft não encontrado, não é possível continuar" + +#, python-format +msgid "skipping ungraftable merge revision %s\n" +msgstr "omitindo revisão de mesclagem %s que não pode ser enxertada\n" + +#, python-format +msgid "skipping ancestor revision %s\n" +msgstr "omitindo revisão ancestral %s\n" + +#, python-format +msgid "skipping already grafted revision %s\n" +msgstr "omitindo revisão %s já enxertada\n" + +msgid "unresolved conflicts, can't continue" +msgstr "conflitos não resolvidos, não é possível continuar" + +msgid "use hg resolve and hg graft --continue" +msgstr "use hg resolve e hg graft --continue" msgid "end fields with NUL" msgstr "termina campos com NUL" @@ -9574,7 +10735,9 @@ msgstr "imprime todas as revisões que casarem" msgid "follow changeset history, or file history across copies and renames" -msgstr "acompanha histórico de revisões, ou histórico de arquivo através de cópias e renomeações" +msgstr "" +"acompanha histórico de revisões, ou histórico de arquivo através de cópias e" +" renomeações" msgid "ignore case when matching" msgstr "ignora maiúsculas/minúsculas ao casar" @@ -9729,7 +10892,8 @@ msgid "show help for a given topic or a help overview" msgstr "exibe o texto de ajuda geral ou de um tópico pedido" -msgid " With no arguments, print a list of commands with short help messages." +msgid "" +" With no arguments, print a list of commands with short help messages." msgstr "" " Sem argumentos, imprime uma lista de comandos com textos curtos\n" " de ajuda." @@ -9748,6 +10912,19 @@ " Devolve 0 para indicar sucesso.\n" " " +msgid "VALUE" +msgstr "VALOR" + +msgid "DEPRECATED" +msgstr "OBSOLETO" + +msgid "" +"\n" +"[+] marked option can be specified multiple times\n" +msgstr "" +"\n" +"opções marcadas com [+] podem ser especificadas múltiplas vezes\n" + msgid "global options:" msgstr "opções globais:" @@ -9763,14 +10940,13 @@ #, python-format msgid "use \"hg -v help%s\" to show builtin aliases and global options" -msgstr "use \"hg -v help%s\" para mostrar apelidos pré-definidos de comandos e opções globais" - -#, python-format -msgid "use \"hg -v help %s\" to show global options" -msgstr "use \"hg -v help %s\" para mostrar opções globais" - -msgid "list of commands:" -msgstr "lista de comandos:" +msgstr "" +"use \"hg -v help%s\" para mostrar apelidos pré-definidos de comandos e " +"opções globais" + +#, python-format +msgid "use \"hg -v help %s\" to show more info" +msgstr "use \"hg -v help %s\" para mostrar mais informações" #, python-format msgid "" @@ -9800,23 +10976,44 @@ msgstr "%s" #, python-format -msgid "" -"\n" -"use \"hg -v help %s\" to show verbose help\n" -msgstr "" -"\n" -"use \"hg -v help %s\" para mostrar ajuda verbosa\n" - -msgid "options:\n" -msgstr "opções:\n" - -#, python-format msgid "use \"hg help -e %s\" to show help for the %s extension" msgstr "use \"hg help -e %s\" para mostrar a ajuda para a extensão %s" +#, python-format +msgid "" +"\n" +"use \"hg help %s\" to show the full help text\n" +msgstr "" +"\n" +"use \"hg help %s\" para mostrar o texto completo de ajuda\n" + +#, python-format +msgid "" +"\n" +"use \"hg -v help %s\" to show more info\n" +msgstr "" +"\n" +"use \"hg -v help %s\" para mostrar mais informações\n" + +msgid "basic commands:" +msgstr "comandos básicos:" + +msgid "list of commands:" +msgstr "lista de comandos:" + msgid "no commands defined\n" msgstr "nenhum comando definido\n" +msgid "enabled extensions:" +msgstr "extensões habilitadas:" + +msgid "" +"\n" +"additional help topics:" +msgstr "" +"\n" +"tópicos adicionais de ajuda:" + #, python-format msgid "" "\n" @@ -9833,7 +11030,8 @@ msgstr "extensão %s - %s" msgid "use \"hg help extensions\" for information on enabling extensions\n" -msgstr "use \"hg help extensions\" para informações sobre como habilitar extensões\n" +msgstr "" +"use \"hg help extensions\" para informações sobre como habilitar extensões\n" #, python-format msgid "'%s' is provided by the following extension:" @@ -9842,32 +11040,6 @@ msgid "Mercurial Distributed SCM\n" msgstr "Sistema de controle de versão distribuído Mercurial\n" -msgid "basic commands:" -msgstr "comandos básicos:" - -msgid "enabled extensions:" -msgstr "extensões habilitadas:" - -msgid "VALUE" -msgstr "VALOR" - -msgid "DEPRECATED" -msgstr "OBSOLETO" - -msgid "" -"\n" -"[+] marked option can be specified multiple times" -msgstr "" -"\n" -"opções marcadas com [+] podem ser especificadas múltiplas vezes" - -msgid "" -"\n" -"additional help topics:" -msgstr "" -"\n" -"tópicos adicionais de ajuda:" - msgid "identify the specified revision" msgstr "identifica a revisão especificada" @@ -9919,11 +11091,34 @@ " arquivo bundle do Mercurial faz com que a busca opere em tal\n" " repositório ou bundle." +msgid " - generate a build identifier for the working directory::" +msgstr " - gera um identificador de build para o diretório de trabalho::" + +msgid " hg id --id > build-id.dat" +msgstr " hg id --id > build-id.dat" + +msgid " - find the revision corresponding to a tag::" +msgstr " - encontra a revisão que corresponde a uma etiqueta::" + +msgid " hg id -n -r 1.3" +msgstr " hg id -n -r 1.3" + +msgid " - check the most recent revision of a remote repository::" +msgstr " - verifica a revisão mais recente de um repositório remoto::" + +msgid " hg id -r tip http://selenic.com/hg/" +msgstr " hg id -r tip http://selenic.com/hg/" + msgid "can't query remote revision number, branch, or tags" -msgstr "não é possível consultar o número de revisão, ramo ou etiquetas remotos" - -msgid "directory strip option for patch. This has the same meaning as the corresponding patch option" -msgstr "opção de remoção de diretório para o patch. Tem o mesmo significado da opção correspondente do utilitário patch" +msgstr "" +"não é possível consultar o número de revisão, ramo ou etiquetas remotos" + +msgid "" +"directory strip option for patch. This has the same meaning as the " +"corresponding patch option" +msgstr "" +"opção de remoção de diretório para o patch. Tem o mesmo significado da opção" +" correspondente do utilitário patch" msgid "PATH" msgstr "CAMINHO" @@ -10035,6 +11230,39 @@ " para -d/--date.\n" " " +msgid " - import a traditional patch from a website and detect renames::" +msgstr "" +" - importa um patch traditional de um servidor web e detecta\n" +" renomeações::" + +msgid " hg import -s 80 http://example.com/bugfix.patch" +msgstr " hg import -s 80 http://example.com/bugfix.patch" + +msgid " - import a changeset from an hgweb server::" +msgstr " - importa uma revisão de um servidor hgweb::" + +msgid " hg import http://www.selenic.com/hg/rev/5ca8c111e9aa" +msgstr " hg import http://www.selenic.com/hg/rev/5ca8c111e9aa" + +msgid " - import all the patches in an Unix-style mbox::" +msgstr " - importa todos os patches em uma mbox estilo Unix::" + +msgid " hg import incoming-patches.mbox" +msgstr " hg import incoming-patches.mbox" + +msgid "" +" - attempt to exactly restore an exported changeset (not always\n" +" possible)::" +msgstr "" +" - tenta restaurar com exatidão uma revisão exportada (nem sempre\n" +" possível)::" + +msgid " hg import --exact proposed-fix.patch" +msgstr " hg import --exact proposed-fix.patch" + +msgid "need at least one patch to import" +msgstr "é necessário ao menos um nome de patch para importar" + msgid "cannot use --no-commit with --bypass" msgstr "não se pode usar --no-commit com --bypass" @@ -10044,21 +11272,23 @@ msgid "patch is damaged or loses information" msgstr "o patch está danificado ou perde informação" -msgid "to working directory" -msgstr "para o diretório de trabalho" +msgid "applied to working directory" +msgstr "aplicado no diretório de trabalho" msgid "not a Mercurial patch" msgstr "não é um patch do Mercurial" +#. i18n: refers to a short changeset id +#, python-format +msgid "created %s" +msgstr "revisão %s criada" + msgid "applying patch from stdin\n" msgstr "aplicando patch da entrada padrão\n" #, python-format -msgid "applied %s\n" -msgstr "aplicado %s\n" - -msgid "no diffs found" -msgstr "nenhum diff encontrado" +msgid "%s: no diffs found" +msgstr "%s: nenhum diff encontrado" msgid "run even if remote repository is unrelated" msgstr "execute mesmo se o repositório remoto não for relacionado" @@ -10239,30 +11469,25 @@ " projeto como um todo." msgid "" +" If no revision range is specified, the default is ``tip:0`` unless\n" +" --follow is set, in which case the working directory parent is\n" +" used as the starting revision." +msgstr "" +" Se um intervalo de revisões não for pedido, o padrão é ``tip:0``,\n" +" a não ser que --follow seja pedido; nesse caso, o pai do\n" +" diretório de trabalho será usado como revisão inicial." + +msgid "" " File history is shown without following rename or copy history of\n" " files. Use -f/--follow with a filename to follow history across\n" " renames and copies. --follow without a filename will only show\n" -" ancestors or descendants of the starting revision. --follow-first\n" -" only follows the first parent of merge revisions." +" ancestors or descendants of the starting revision." msgstr "" " O histórico de arquivos é mostrado sem que informações de cópia e\n" " renomeação sejam seguidas. Use -f/--follow para seguir o\n" " histórico através de renomeações e cópias. --follow sem um nome\n" " de arquivo irá mostrar apenas ancestrais ou descendentes da\n" -" revisão de início. --follow-first segue apenas o primeiro pai em\n" -" revisões de mesclagem." - -msgid "" -" If no revision range is specified, the default is ``tip:0`` unless\n" -" --follow is set, in which case the working directory parent is\n" -" used as the starting revision. You can specify a revision set for\n" -" log, see :hg:`help revsets` for more information." -msgstr "" -" Se um intervalo de revisões não for pedido, o padrão é ``tip:0``,\n" -" a não ser que --follow seja pedido; nesse caso, o pai do\n" -" diretório de trabalho será usado como revisão inicial. Você\n" -" também pode especificar um conjunto de revisões: veja\n" -" :hg:`help revsets` para mais informações." +" revisão de início." msgid "" " By default this command prints revision number and changeset id,\n" @@ -10289,6 +11514,92 @@ " com seu primeiro pai. Além disso, apenas arquivos diferentes\n" " de AMBOS os pais aparecerão na lista de arquivos." +msgid "" +" .. note::\n" +" for performance reasons, log FILE may omit duplicate changes\n" +" made on branches and will not show deletions. To see all\n" +" changes including duplicates and deletions, use the --removed\n" +" switch." +msgstr "" +" .. note::\n" +" por razões de desempenho, log ARQUIVO pode omitir mudanças\n" +" duplicadas feitas em outros ramos, e não mostra remoções.\n" +" Para ver todas as mudanças incluindo duplicatas e remoções,\n" +" use a opção --removed." + +msgid " - changesets with full descriptions and file lists::" +msgstr " - revisões com descrições completas e lista de arquivos::" + +msgid " hg log -v" +msgstr " hg log -v" + +msgid " - changesets ancestral to the working directory::" +msgstr " - revisões ancestrais do diretório de trabalho::" + +msgid " hg log -f" +msgstr " hg log -f" + +msgid " - last 10 commits on the current branch::" +msgstr " - últimas 10 revisões no ramo atual::" + +msgid " hg log -l 10 -b ." +msgstr " hg log -l 10 -b ." + +msgid "" +" - changesets showing all modifications of a file, including removals::" +msgstr "" +" - revisões mostrando todas as modificações feitas em um\n" +" arquivo, incluindo remoções::" + +msgid " hg log --removed file.c" +msgstr " hg log --removed file.c" + +msgid "" +" - all changesets that touch a directory, with diffs, excluding " +"merges::" +msgstr "" +" - todas as revisões que modificam um diretório, com diffs,\n" +" excluindo mesclagens::" + +msgid " hg log -Mp lib/" +msgstr " hg log -Mp lib/" + +msgid " - all revision numbers that match a keyword::" +msgstr "" +" - todos os números de revisões que combinarem com uma palavra chave::" + +msgid " hg log -k bug --template \"{rev}\\n\"" +msgstr " hg log -k bug --template \"{rev}\\n\"" + +msgid " - check if a given changeset is included is a tagged release::" +msgstr "" +" - verifica se uma revisão dada foi incluída em um\n" +" release etiquetado::" + +msgid " hg log -r \"a21ccf and ancestor(1.9)\"" +msgstr " hg log -r \"a21ccf and ancestor(1.9)\"" + +msgid " - find all changesets by some user in a date range::" +msgstr "" +" - encontra todas as revisões feitas por um usuário em\n" +" uma faixa de datas::" + +msgid " hg log -k alice -d \"may 2008 to jul 2008\"" +msgstr " hg log -k alice -d \"may 2008 to jul 2008\"" + +msgid " - summary of all changesets after the last tag::" +msgstr " - sumário de todas as revisões após a última etiqueta::" + +msgid " hg log -r \"last(tagged())::\" --template \"{desc|firstline}\\n\"" +msgstr " hg log -r \"last(tagged())::\" --template \"{desc|firstline}\\n\"" + +msgid "" +" See :hg:`help revisions` and :hg:`help revsets` for more about\n" +" specifying revisions." +msgstr "" +" Veja :hg:`help revisions` e :hg:`help revsets` para mais\n" +" informações sobre a especificação de revisões." + msgid "revision to display" msgstr "revisão a ser exibida" @@ -10386,7 +11697,8 @@ " explicitamente." msgid " :hg:`resolve` must be used to resolve unresolved files." -msgstr " :hg:`resolve` deve ser usado para resolver arquivos não resolvidos." +msgstr "" +" :hg:`resolve` deve ser usado para resolver arquivos não resolvidos." msgid "" " To undo an uncommitted merge, use :hg:`update --clean .` which\n" @@ -10406,14 +11718,17 @@ #, python-format msgid "branch '%s' has %d heads - please merge with an explicit rev" -msgstr "o ramo '%s' tem %d cabeças - por favor mescle com uma revisão explícita" +msgstr "" +"o ramo '%s' tem %d cabeças - por favor mescle com uma revisão explícita" msgid "run 'hg heads .' to see heads" msgstr "execute 'hg heads .' para ver as cabeças" #, python-format msgid "branch '%s' has one head - please merge with an explicit rev" -msgstr "o ramo '%s' tem apenas uma cabeça - por favor mescle com uma revisão explícita" +msgstr "" +"o ramo '%s' tem apenas uma cabeça - por favor mescle com uma revisão " +"explícita" msgid "run 'hg heads' to see all heads" msgstr "execute 'hg heads' para ver todas as cabeças" @@ -10628,8 +11943,12 @@ msgid "remote bookmark %s not found!" msgstr "marcador remoto %s não encontrado!" -msgid "other repository doesn't support revision lookup, so a rev cannot be specified." -msgstr "o outro repositório não suporta busca por revisão, portanto uma revisão não pode ser especificada." +msgid "" +"other repository doesn't support revision lookup, so a rev cannot be " +"specified." +msgstr "" +"o outro repositório não suporta busca por revisão, portanto uma revisão não " +"pode ser especificada." #, python-format msgid "importing bookmark %s\n" @@ -10765,64 +12084,70 @@ msgid "remove the specified files on the next commit" msgstr "remove os arquivos pedidos na próxima consolidação" -msgid " Schedule the indicated files for removal from the repository." -msgstr " Agenda os arquivos indicados para remoção do repositório." - -msgid "" -" This only removes files from the current branch, not from the\n" -" entire project history. -A/--after can be used to remove only\n" -" files that have already been deleted, -f/--force can be used to\n" -" force deletion, and -Af can be used to remove files from the next\n" -" revision without deleting them from the working directory." -msgstr "" -" Isto apenas remove arquivos do ramo atual, e não de todo o\n" -" histórico do projeto. -A/--after pode ser usado para remover\n" +msgid " Schedule the indicated files for removal from the current branch." +msgstr " Agenda os arquivos indicados para remoção do ramo atual." + +msgid "" +" This command schedules the files to be removed at the next commit.\n" +" To undo a remove before that, see :hg:`revert`. To undo added\n" +" files, see :hg:`forget`." +msgstr "" +" Este comando agenda os arquivos para serem removidos na próxima\n" +" consolidação. Para desfazer uma remoção antes disso, veja\n" +" :hg:`revert`. Para desfazer uma adição de arquivos, veja\n" +" :hg:`forget`." + +msgid "" +" -A/--after can be used to remove only files that have already\n" +" been deleted, -f/--force can be used to force deletion, and -Af\n" +" can be used to remove files from the next revision without\n" +" deleting them from the working directory." +msgstr "" +" -A/--after pode ser usado para remover\n" " apenas arquivos já removidos do diretório de trabalho,\n" " -f/--force pode ser usado para forçar a remoção, e -Af pode ser\n" " usado para remover os arquivos da próxima revisão sem removê-los\n" " do diretório de trabalho." msgid "" -" The following table details the behavior of remove for different\n" -" file states (columns) and option combinations (rows). The file\n" -" states are Added [A], Clean [C], Modified [M] and Missing [!] (as\n" -" reported by :hg:`status`). The actions are Warn, Remove (from\n" -" branch) and Delete (from disk)::" -msgstr "" -" A seguinte tabela detalha o comportamento do comando remove para\n" -" diferentes estados dos arquivos (colunas) e combinações de opções\n" -" (linhas). Os estados dos arquivos são: adicionados [A],\n" -" limpos [C], modificados [M] ou faltando [!] (conforme informado\n" -" por :hg:`status`). As ações são W (aviso), R (remove do ramo) e D\n" -" (remove do diretório de trabalho)::" - -msgid "" -" A C M !\n" -" none W RD W R\n" -" -f R RD RD R\n" -" -A W W W R\n" -" -Af R R R R" -msgstr "" -" A C M !\n" -" none W RD W R\n" -" -f R RD RD R\n" -" -A W W W R\n" -" -Af R R R R" - -msgid "" -" Note that remove never deletes files in Added [A] state from the\n" -" working directory, not even if option --force is specified." -msgstr "" -" Note que remove nunca apaga do diretório de trabalho arquivos no\n" -" estado adicionado [A], nem mesmo se a opção --force for especificada." - -msgid "" -" This command schedules the files to be removed at the next commit.\n" -" To undo a remove before that, see :hg:`revert`." -msgstr "" -" Este comando agenda os arquivos para serem removidos na próxima\n" -" consolidação. Para desfazer uma remoção antes disso, veja\n" -" :hg:`revert`." +" The following table details the behavior of remove for different\n" +" file states (columns) and option combinations (rows). The file\n" +" states are Added [A], Clean [C], Modified [M] and Missing [!]\n" +" (as reported by :hg:`status`). The actions are Warn, Remove\n" +" (from branch) and Delete (from disk):" +msgstr "" +" A seguinte tabela detalha o comportamento do comando remove para\n" +" diferentes estados dos arquivos (colunas) e combinações de opções\n" +" (linhas). Os estados dos arquivos são: adicionados [A],\n" +" limpos [C], modificados [M] ou faltando [!] (conforme informado\n" +" por :hg:`status`). As ações são W (aviso), R (remove do ramo) e D\n" +" (remove do diretório de trabalho):" + +msgid "" +" ======= == == == ==\n" +" A C M !\n" +" ======= == == == ==\n" +" none W RD W R\n" +" -f R RD RD R\n" +" -A W W W R\n" +" -Af R R R R\n" +" ======= == == == ==" +msgstr "" +" ======= == == == ==\n" +" A C M !\n" +" ======= == == == ==\n" +" nenhum W RD W R\n" +" -f R RD RD R\n" +" -A W W W R\n" +" -Af R R R R\n" +" ======= == == == ==" + +msgid "" +" Note that remove never deletes files in Added [A] state from the\n" +" working directory, not even if option --force is specified." +msgstr "" +" Note que remove nunca apaga do diretório de trabalho arquivos no\n" +" estado adicionado [A], nem mesmo se a opção --force for especificada." msgid "" " Returns 0 on success, 1 if any warnings encountered.\n" @@ -10837,15 +12162,19 @@ #, python-format msgid "not removing %s: file still exists (use -f to force removal)\n" -msgstr "%s não removido: o arquivo ainda existe (use -f para forçar a remoção)\n" +msgstr "" +"%s não removido: o arquivo ainda existe (use -f para forçar a remoção)\n" #, python-format msgid "not removing %s: file is modified (use -f to force removal)\n" -msgstr "%s não removido: o arquivo foi modificado (use -f para forçar a remoção)\n" - -#, python-format -msgid "not removing %s: file has been marked for add (use -f to force removal)\n" -msgstr "%s não removido: o arquivo foi marcado para adição (use -f para forçar a remoção)\n" +msgstr "" +"%s não removido: o arquivo foi modificado (use -f para forçar a remoção)\n" + +#, python-format +msgid "not removing %s: file has been marked for add (use forget to undo)\n" +msgstr "" +"%s não removido: o arquivo foi marcado para adição (use forget para " +"desfazer)\n" msgid "record a rename that has already occurred" msgstr "grava uma renomeação que já ocorreu" @@ -10916,7 +12245,8 @@ " performed for files already marked as resolved. Use ``--all/-a``\n" " to select all unresolved files. ``--tool`` can be used to specify\n" " the merge tool used for the given files. It overrides the HGMERGE\n" -" environment variable and your configuration files." +" environment variable and your configuration files. Previous file\n" +" contents are saved with a ``.orig`` suffix." msgstr "" " - :hg:`resolve [--tool] ARQUIVO...`: tenta refazer a mesclagem\n" " dos arquivos especificados, descartando qualquer tentativa de\n" @@ -10925,7 +12255,9 @@ " indicar todos os arquivos não resolvidos. ``--tool`` pode ser\n" " usado para especificar o utilitário de mesclagem usado para os\n" " arquivos pedidos. Esta opção sobrepõe a variável de ambiente\n" -" HGMERGE e os valores especificados nos arquivos de configuração." +" HGMERGE e os valores especificados nos arquivos de configuração.\n" +" Os conteúdos anteriores dos arquivos são gravados usando um\n" +" sufixo ``.orig``." msgid "" " - :hg:`resolve -m [FILE]`: mark a file as having been resolved\n" @@ -10976,7 +12308,9 @@ msgstr "não é possível especificar --all e padrões" msgid "no files or directories specified; use --all to remerge all files" -msgstr "nenhum arquivo ou diretório especificado; use --all para refazer a mesclagem de todos os arquivos" +msgstr "" +"nenhum arquivo ou diretório especificado; use --all para refazer a mesclagem" +" de todos os arquivos" msgid "revert all changes when no arguments given" msgstr "se parâmetros não forem fornecidos, reverte todas as mudanças" @@ -10994,7 +12328,8 @@ msgstr "[OPÇÃO]... [-r REV] [NOME]..." msgid "restore files to their checkout state" -msgstr "restaura arquivos para o estado correspondente a uma cópia de trabalho" +msgstr "" +"restaura arquivos para o estado correspondente a uma cópia de trabalho" msgid "" " .. note::\n" @@ -11055,19 +12390,30 @@ msgid "no files or directories specified" msgstr "nenhum arquivo ou diretório especificados" -msgid "uncommitted merge, use --all to discard all changes, or 'hg update -C .' to abort the merge" -msgstr "mesclagem não consolidada, use --all para descartar todas as mudanças locais, ou 'hg update -C .' para abortar a mesclagem" - -#, python-format -msgid "uncommitted changes, use --all to discard all changes, or 'hg update %s' to update" -msgstr "mudanças não consolidadas, use --all para descartar todas as mudanças locais, ou 'hg update %s' para atualizar" +msgid "" +"uncommitted merge, use --all to discard all changes, or 'hg update -C .' to " +"abort the merge" +msgstr "" +"mesclagem não consolidada, use --all para descartar todas as mudanças " +"locais, ou 'hg update -C .' para abortar a mesclagem" + +#, python-format +msgid "" +"uncommitted changes, use --all to discard all changes, or 'hg update %s' to " +"update" +msgstr "" +"mudanças não consolidadas, use --all para descartar todas as mudanças " +"locais, ou 'hg update %s' para atualizar" #, python-format msgid "use --all to revert all files, or 'hg update %s' to update" -msgstr "use --all para reverter todos os arquivos, ou 'hg update %s' para atualizar a revisão" +msgstr "" +"use --all para reverter todos os arquivos, ou 'hg update %s' para atualizar " +"a revisão" msgid "uncommitted changes, use --all to discard all changes" -msgstr "mudanças não consolidadas, use --all para descartar todas as mudanças locais" +msgstr "" +"mudanças não consolidadas, use --all para descartar todas as mudanças locais" msgid "use --all to revert all files" msgstr "use --all para reverter todos os arquivos" @@ -11096,6 +12442,9 @@ msgid "no changes needed to %s\n" msgstr "nenhuma mudança necessária para %s\n" +msgid "ignore safety measures" +msgstr "ignora medidas de segurança" + msgid "roll back the last transaction (dangerous)" msgstr "desfaz a última transação (perigoso)" @@ -11137,6 +12486,19 @@ " - unbundle" msgid "" +" It's possible to lose data with rollback: commit, update back to\n" +" an older changeset, and then rollback. The update removes the\n" +" changes you committed from the working directory, and rollback\n" +" removes them from history. To avoid data loss, you must pass\n" +" --force in this case." +msgstr "" +" É possível perder dados com o comando rollback: se for feito um\n" +" commit, update para uma revisão antiga, e em seguida rollback.\n" +" O update remove as mudanças recém gravadas na última consolidação,\n" +" e o rollback as remove do histórico. Para evitar perda de dados,\n" +" você deve passar --force neste caso." + +msgid "" " This command is not intended for use on public repositories. Once\n" " changes are visible for pull by other users, rolling a transaction\n" " back locally is ineffective (someone else may already have pulled\n" @@ -11412,6 +12774,28 @@ " I = ignorado\n" " = origem do arquivo anterior listado como A (adicionado)" +msgid " - show changes in the working directory relative to a changeset:" +msgstr "" +" - mostra mudanças no diretório de trabalho relativs a uma revisão:" + +msgid " hg status --rev 9353" +msgstr " hg status --rev 9353" + +msgid " - show all changes including copies in an existing changeset::" +msgstr "" +" - mostra todas as mudanças incluindo cópias em uma revisão existente::" + +msgid " hg status --copies --change 9353" +msgstr " hg status --copies --change 9353" + +msgid " - get a NUL separated list of added files, suitable for xargs::" +msgstr "" +" - gera uma lista separada por NUL de arquivos adicionados,\n" +" adequada para o comando xargs::" + +msgid " hg status -an0" +msgstr " hg status -an0" + msgid "check for push and pull" msgstr "verifica push e pull" @@ -11447,6 +12831,9 @@ msgid "branch: %s\n" msgstr "ramo: %s\n" +msgid "bookmarks:" +msgstr "marcadores:" + #, python-format msgid "%d modified" msgstr "%d modificados" @@ -11689,7 +13076,8 @@ " revisão." msgid "update to new branch head if changesets were unbundled" -msgstr "atualiza para nova cabeça de ramo se revisões forem extraídas do bundle" +msgstr "" +"atualiza para nova cabeça de ramo se revisões forem extraídas do bundle" msgid "[-u] FILE..." msgstr "[-u] ARQUIVO..." @@ -11810,9 +13198,6 @@ msgid "cannot specify both -c/--check and -C/--clean" msgstr "não se pode especificar ao mesmo tempo -c/--check e -C/--clean" -msgid "uncommitted local changes" -msgstr "alterações locais pendentes" - msgid "verify the integrity of the repository" msgstr "verifica a integridade do repositório" @@ -11886,7 +13271,9 @@ #, python-format msgid "%s not added: only files and symlinks supported currently\n" -msgstr "%s não adicionado: apenas arquivos e links simbólicos suportados no momento\n" +msgstr "" +"%s não adicionado: apenas arquivos e links simbólicos suportados no " +"momento\n" #, python-format msgid "%s already tracked!\n" @@ -12001,7 +13388,9 @@ msgstr "hg: erro de análise da entrada: %s\n" msgid "entering debugger - type c to continue starting hg or h for help\n" -msgstr "entrando no depurador - digite c para continuar iniciando o hg ou h para ajuda\n" +msgstr "" +"entrando no depurador - digite c para continuar iniciando o hg ou h para " +"ajuda\n" #, python-format msgid "" @@ -12080,7 +13469,9 @@ msgstr "abortado: sem memória\n" msgid "** unknown exception encountered, please report by visiting\n" -msgstr "** exceção desconhecida encontrada, por favor informe sobre esse erro visitando\n" +msgstr "" +"** exceção desconhecida encontrada, por favor informe sobre esse erro " +"visitando\n" msgid "** http://mercurial.selenic.com/wiki/BugTracker\n" msgstr "** http://mercurial.selenic.com/wiki/BugTracker\n" @@ -12102,8 +13493,12 @@ msgstr "nenhuma definição para o apelido '%s'\n" #, python-format -msgid "error in definition for alias '%s': %s may only be given on the command line\n" -msgstr "erro na definição do apelido '%s': %s pode ser passado apenas na linha de comando\n" +msgid "" +"error in definition for alias '%s': %s may only be given on the command " +"line\n" +msgstr "" +"erro na definição do apelido '%s': %s pode ser passado apenas na linha de " +"comando\n" #, python-format msgid "alias '%s' resolves to unknown command '%s'\n" @@ -12131,8 +13526,12 @@ msgid "option --cwd may not be abbreviated!" msgstr "a opção --cwd não pode ser abreviada!" -msgid "Option -R has to be separated from other options (e.g. not -qR) and --repository may only be abbreviated as --repo!" -msgstr "A opção -R deve ser separada de outras opções (por exemplo, não usar -qR) e --repository pode ser abreviada apenas como --repo!" +msgid "" +"Option -R has to be separated from other options (e.g. not -qR) and " +"--repository may only be abbreviated as --repo!" +msgstr "" +"A opção -R deve ser separada de outras opções (por exemplo, não usar -qR) e " +"--repository pode ser abreviada apenas como --repo!" #, python-format msgid "Time: real %.3f secs (user %.3f+%.3f sys %.3f+%.3f)\n" @@ -12153,8 +13552,12 @@ msgid "unrecognized profiling format '%s' - Ignored\n" msgstr "formato de profiling '%s' não reconhecido - Ignorado\n" -msgid "lsprof not available - install from http://codespeak.net/svn/user/arigo/hack/misc/lsprof/" -msgstr "lsprof não disponível - instale de http://codespeak.net/svn/user/arigo/hack/misc/lsprof/" +msgid "" +"lsprof not available - install from " +"http://codespeak.net/svn/user/arigo/hack/misc/lsprof/" +msgstr "" +"lsprof não disponível - instale de " +"http://codespeak.net/svn/user/arigo/hack/misc/lsprof/" #, python-format msgid "*** failed to import extension %s from %s: %s\n" @@ -12192,20 +13595,6 @@ " nenhuma ferramenta encontrada para mesclar %s\n" "manter (l)ocal ou usar (o)utro?" -msgid "&Local" -msgstr "&Local" - -msgid "&Other" -msgstr "&Outra" - -#, python-format -msgid "merging %s and %s to %s\n" -msgstr "mesclando %s e %s para %s\n" - -#, python-format -msgid "merging %s\n" -msgstr "mesclando %s\n" - #, python-format msgid "%s.premerge not valid ('%s' is neither boolean nor %s)" msgstr "%s.premerge não é válido ('%s' não é nem booleano nem %s)" @@ -12470,6 +13859,33 @@ msgid "unknown bisect kind %s" msgstr "tipo desconhecido de bisect %s" +msgid "invalid bisect state" +msgstr "estado de bisecção inválido" + +#. i18n: bisect changeset status +msgid "good" +msgstr "boa" + +#. i18n: bisect changeset status +msgid "bad" +msgstr "ruim" + +#. i18n: bisect changeset status +msgid "skipped" +msgstr "omitida" + +#. i18n: bisect changeset status +msgid "untested" +msgstr "não testada" + +#. i18n: bisect changeset status +msgid "good (implicit)" +msgstr "boa (implicitamente)" + +#. i18n: bisect changeset status +msgid "bad (implicit)" +msgstr "ruim (implicitamente)" + msgid "disabled extensions:" msgstr "extensões desabilitadas:" @@ -13021,6 +14437,15 @@ "acima, ``$HG_ARGS`` expandiria para ``echo foo``." msgid "" +".. note:: Some global configuration options such as ``-R`` are\n" +" processed before shell aliases and will thus not be passed to\n" +" aliases." +msgstr "" +".. note:: Algumas opções globais de configuração, como ``-R``,\n" +" são procesadas antes de apelidos de shell, e portanto não serão\n" +" passadas para os apelidos." + +msgid "" "``auth``\n" "\"\"\"\"\"\"\"\"" msgstr "" @@ -13601,7 +15026,8 @@ " hg.intevation.org = 38:76:52:7c:87:26:9a:8f:4a:f8:d3:de:08:45:3b:ea:d6:4b:ee:cc" msgid "This feature is only supported when using Python 2.6 or later." -msgstr "Esta funcionalidade só é suportada nas versões do Python 2.6 ou posteriores." +msgstr "" +"Esta funcionalidade só é suportada nas versões do Python 2.6 ou posteriores." msgid "" "\n" @@ -14644,7 +16070,8 @@ "\"\"\"\"\"\"\"\"\"\"\"\"" msgid "Defines subrepositories source locations rewriting rules of the form::" -msgstr "Define regras de reescrita de localização de subrepositórios da forma::" +msgstr "" +"Define regras de reescrita de localização de subrepositórios da forma::" msgid " <pattern> = <replacement>" msgstr " <padrao> = <substituicao>" @@ -14767,14 +16194,14 @@ " Whether to commit modified subrepositories when committing the\n" " parent repository. If False and one subrepository has uncommitted\n" " changes, abort the commit.\n" -" Default is True." +" Default is False." msgstr "" "``commitsubrepos``\n" " Determina se sub-repositórios modificados serão automaticamente\n" " consolidados ao consolidar o repositório pai. Se for False e\n" " algum sub-repositório tiver mudanças não consolidadas, aborta a\n" " consolidação do repositório pai.\n" -" O padrão é True." +" O padrão é False." msgid "" "``debug``\n" @@ -15359,6 +16786,20 @@ " Determina se IPv6 deve ser usado. O padrão é False." msgid "" +"``logoimg``\n" +" File name of the logo image that some templates display on each page.\n" +" The file name is relative to ``staticurl``. That is, the full path to\n" +" the logo image is \"staticurl/logoimg\".\n" +" If unset, ``hglogo.png`` will be used." +msgstr "" +"``logoimg``\n" +" Nome do arquivo contendo a imagem de logotipo que alguns modelos\n" +" exibem em cada página. O nome de arquivo é relativo a ``staticurl``.\n" +" Isto é, o caminho completo para a imagem de logo é\n" +" \"staticurl/logoimg\".\n" +" Se não definido, ``hglogo.png`` será usado." + +msgid "" "``logourl``\n" " Base URL to use for logos. If unset, ``http://mercurial.selenic.com/``\n" " will be used." @@ -15979,7 +17420,8 @@ msgid "Some sample queries:" msgstr "Alguns exemplos de consultas:" -msgid "- Show status of files that appear to be binary in the working directory::" +msgid "" +"- Show status of files that appear to be binary in the working directory::" msgstr "" "- Exibe o status de arquivos que parecem ser binários no diretório\n" "de trabalho::" @@ -17898,31 +19340,39 @@ "- Revisões mencionando \"bug\" ou \"issue\" que não descendem\n" " de revisões etiquetadas::" -msgid " hg log -r \"(keyword(bug) or keyword(issue)) and not ancestors(tagged())\"\n" -msgstr " hg log -r \"(keyword(bug) or keyword(issue)) and not ancestors(tagged())\"\n" +msgid "" +" hg log -r \"(keyword(bug) or keyword(issue)) and not " +"ancestors(tagged())\"\n" +msgstr "" +" hg log -r \"(keyword(bug) or keyword(issue)) and not " +"ancestors(tagged())\"\n" msgid "" "Subrepositories let you nest external repositories or projects into a\n" "parent Mercurial repository, and make commands operate on them as a\n" -"group. External Mercurial and Subversion projects are currently\n" -"supported." +"group." msgstr "" "O suporte a sub-repositórios possibilita o aninhamento de\n" "repositórios externos ou projetos em um repositório pai do\n" "Mercurial, fornecendo suporte para a operação de diversos\n" -"comandos no conjunto como um todo. No momento são suportados\n" -"repositórios externos do Mercurial e do Subversion." +"comandos no conjunto como um todo." + +msgid "" +"Mercurial currently supports Mercurial, Git, and Subversion\n" +"subrepositories." +msgstr "" +"No momento o Mercurial suporta sub-repositórios do próprio\n" +"Mercurial, do Git e do Subversion." msgid "Subrepositories are made of three components:" msgstr "Sub-repositórios são constituídos de três componentes:" msgid "" "1. Nested repository checkouts. They can appear anywhere in the\n" -" parent working directory, and are Mercurial clones or Subversion\n" -" checkouts." -msgstr "" -"1. Cópias locais aninhadas. São clones do Mercurial ou checkouts\n" -" do Subversion, e podem aparecer em qualquer ponto do diretório\n" +" parent working directory." +msgstr "" +"1. Cópias locais aninhadas.\n" +" Podem aparecer em qualquer ponto do diretório\n" " de trabalho pai." msgid "" @@ -17938,21 +19388,27 @@ msgid " path/to/nested = https://example.com/nested/repo/path" msgstr " caminho/aninhado = https://exemplo.com/aninhado/repo/caminho" +msgid " Git and Subversion subrepos are also supported:" +msgstr " Subrepositórios do Git e do Subversion também são suportados:" + +msgid "" +" path/to/nested = [git]git://example.com/nested/repo/path\n" +" path/to/nested = [svn]https://example.com/nested/trunk/path" +msgstr "" +" caminho/aninhado = [git]git://exemplo.com/aninhado/repo/caminho\n" +" caminho/aninhado = [svn]https://exemplo.com/aninhado/trunk/caminho" + msgid "" " where ``path/to/nested`` is the checkout location relatively to the\n" " parent Mercurial root, and ``https://example.com/nested/repo/path``\n" " is the source repository path. The source can also reference a\n" -" filesystem path. Subversion repositories are defined with:" +" filesystem path." msgstr "" " onde ``caminho/aninhado`` é a localização da cópia local relativa\n" " à raiz do repositório pai do Mercurial, e\n" " ``https://exemplo.com/aninhado/repo/caminho`` é o caminho do\n" " repositório de origem. A origem também pode ser um caminho no\n" -" sistema de arquivos. Sub-repositórios do Subversion são definidos\n" -" com:" - -msgid " path/to/nested = [svn]https://example.com/nested/trunk/path" -msgstr " caminho/aninhado = [svn]https://exemplo.com/aninhado/trunk/caminho" +" sistema de arquivos." msgid "" " Note that ``.hgsub`` does not exist by default in Mercurial\n" @@ -18477,8 +19933,12 @@ msgid "destination '%s' is not empty" msgstr "o destino '%s' não está vazio" -msgid "src repository does not support revision lookup and so doesn't support clone by revision" -msgstr "repositório de origem não suporta busca de revisões, portanto não suporta clonar por revisão" +msgid "" +"src repository does not support revision lookup and so doesn't support clone" +" by revision" +msgstr "" +"repositório de origem não suporta busca de revisões, portanto não suporta " +"clonar por revisão" msgid "clone from remote to remote not supported" msgstr "clone de origem remota para destino remoto não suportado" @@ -18488,14 +19948,21 @@ msgstr "atualizando para o ramo %s\n" #, python-format -msgid "%d files updated, %d files merged, %d files removed, %d files unresolved\n" -msgstr "%d arquivos atualizados, %d arquivos mesclados, %d arquivos removidos, %d arquivos não resolvidos\n" +msgid "" +"%d files updated, %d files merged, %d files removed, %d files unresolved\n" +msgstr "" +"%d arquivos atualizados, %d arquivos mesclados, %d arquivos removidos, %d " +"arquivos não resolvidos\n" msgid "use 'hg resolve' to retry unresolved file merges\n" msgstr "use 'hg resolve' para mesclar novamente arquivos não resolvidos\n" -msgid "use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon\n" -msgstr "use 'hg resolve' para mesclar novamente arquivos não resolvidos ou 'hg update -C .' para abandonar\n" +msgid "" +"use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to " +"abandon\n" +msgstr "" +"use 'hg resolve' para mesclar novamente arquivos não resolvidos ou 'hg " +"update -C .' para abandonar\n" msgid "(branch merge, don't forget to commit)\n" msgstr "(mesclagem de ramo, não esqueça de consolidar)\n" @@ -18627,9 +20094,6 @@ msgid "'%s' uses newer protocol %s" msgstr "'%s' usa protocolo mais novo %s" -msgid "unexpected response:" -msgstr "resposta inesperada:" - #, python-format msgid "push failed: %s" msgstr "o push falhou: %s" @@ -18673,7 +20137,9 @@ msgstr "aviso: a etiqueta %s conflita com um nome de ramo existente\n" msgid "working copy of .hgtags is changed (please commit .hgtags manually)" -msgstr "a cópia de trabalho de .hgtags foi modificada (por favor consolide .hgtags manualmente)" +msgstr "" +"a cópia de trabalho de .hgtags foi modificada (por favor consolide .hgtags " +"manualmente)" #, python-format msgid "working directory has unknown parent '%s'!" @@ -18692,20 +20158,34 @@ msgid "no interrupted transaction available\n" msgstr "nenhuma transação interrompida disponível\n" +msgid "no rollback information available\n" +msgstr "nenhuma informação de desfazimento disponível\n" + #, python-format msgid "repository tip rolled back to revision %s (undo %s: %s)\n" -msgstr "executando rollback da tip do repositório para a revisão %s (desfazimento de %s: %s)\n" +msgstr "" +"executando rollback da tip do repositório para a revisão %s (desfazimento de" +" %s: %s)\n" #, python-format msgid "repository tip rolled back to revision %s (undo %s)\n" -msgstr "executando rollback da tip do repositório para a revisão %s (desfazimento de %s)\n" +msgstr "" +"executando rollback da tip do repositório para a revisão %s (desfazimento de" +" %s)\n" msgid "rolling back unknown transaction\n" msgstr "desfazendo transação desconhecida\n" -#, python-format -msgid "named branch could not be reset, current branch is still: %s\n" -msgstr "o ramo nomeado não pôde ser redefinido, o ramo atual ainda é: %s\n" +msgid "rollback of last commit while not checked out may lose data" +msgstr "" +"rollback do último commit pode perder dados se a revisão não for a atual" + +msgid "use -f to force" +msgstr "use -f para forçar" + +#, python-format +msgid "named branch could not be reset: current branch is still '%s'\n" +msgstr "o ramo nomeado não pôde ser redefinido: o ramo atual ainda é %s\n" #, python-format msgid "working directory now based on revisions %d and %d\n" @@ -18715,9 +20195,6 @@ msgid "working directory now based on revision %d\n" msgstr "o diretório de trabalho está agora baseado na revisão %d\n" -msgid "no rollback information available\n" -msgstr "nenhuma informação de desfazimento disponível\n" - #, python-format msgid "waiting for lock on %s held by %r\n" msgstr "esperando pelo bloqueio em %s feito por %r\n" @@ -18732,17 +20209,20 @@ #, python-format msgid "warning: can't find ancestor for '%s' copied from '%s'!\n" -msgstr "aviso: não é possível encontrar o ancestral de '%s' copiado a partir de '%s'!\n" +msgstr "" +"aviso: não é possível encontrar o ancestral de '%s' copiado a partir de " +"'%s'!\n" msgid "cannot partially commit a merge (do not specify files or patterns)" -msgstr "não é possível consolidar parcialmente uma mesclagem (não especifique arquivos ou padrões)" +msgstr "" +"não é possível consolidar parcialmente uma mesclagem (não especifique " +"arquivos ou padrões)" msgid "can't commit subrepos without .hgsub" msgstr "não é possível consolidar sub-repositórios sem o arquivo .hgsub" -#, python-format -msgid "uncommitted changes in subrepo %s" -msgstr "mudanças não consolidadas no sub-repositório %s" +msgid "use --subrepos for recursive commit" +msgstr "use --subrepos para um commit recursivo" msgid "file not found!" msgstr "arquivo não encontrado!" @@ -18771,8 +20251,12 @@ msgid "requesting all changes\n" msgstr "pedindo todas as mudanças\n" -msgid "partial pull cannot be done because other repository doesn't support changegroupsubset." -msgstr "pull parcial não pode ser feito porque o outro repositório não suporta 'changegroupsubset'." +msgid "" +"partial pull cannot be done because other repository doesn't support " +"changegroupsubset." +msgstr "" +"pull parcial não pode ser feito porque o outro repositório não suporta " +"'changegroupsubset'." #, python-format msgid "%d changesets found\n" @@ -18866,11 +20350,14 @@ msgstr "enviando e-mail: %s\n" msgid "smtp specified as email transport, but no smtp host configured" -msgstr "smtp especificado como transporte de e-mail, mas o servidor smtp não foi configurado" +msgstr "" +"smtp especificado como transporte de e-mail, mas o servidor smtp não foi " +"configurado" #, python-format msgid "%r specified as email transport, but not in PATH" -msgstr "%r especificado como um transporte de e-mail, mas não encontrado no PATH" +msgstr "" +"%r especificado como um transporte de e-mail, mas não encontrado no PATH" #, python-format msgid "ignoring invalid sendcharset: %s\n" @@ -18908,8 +20395,12 @@ msgstr "o número de linhas de contexto de diff deve ser um inteiro, e não %r" #, python-format -msgid "untracked file in working directory differs from file in requested revision: '%s'" -msgstr "arquivo não versionado no diretório de trabalho difere do arquivo na revisão pedida: '%s'" +msgid "" +"untracked file in working directory differs from file in requested revision:" +" '%s'" +msgstr "" +"arquivo não versionado no diretório de trabalho difere do arquivo na revisão" +" pedida: '%s'" #, python-format msgid "case-folding collision between %s and %s" @@ -18980,23 +20471,29 @@ msgstr "nota: possível conflito - %s foi renomeado múltiplas vezes para:\n" msgid "merging with a working directory ancestor has no effect" -msgstr "mesclar com um ancestral do diretório de trabalho não tem nenhum efeito" +msgstr "" +"mesclar com um ancestral do diretório de trabalho não tem nenhum efeito" msgid "nothing to merge (use 'hg update' or check 'hg heads')" msgstr "nada para mesclar (use 'hg update' ou verifique 'hg heads')" msgid "outstanding uncommitted changes (use 'hg status' to list changes)" -msgstr "alterações não consolidadas pendentes (use 'hg status' para listar as mudanças)" +msgstr "" +"alterações não consolidadas pendentes (use 'hg status' para listar as " +"mudanças)" #, python-format msgid "outstanding uncommitted changes in subrepository '%s'" msgstr "mudanças não consolidadas pendentes no sub-repositório '%s'" msgid "crosses branches (merge branches or use --clean to discard changes)" -msgstr "atravessa ramos (mescle os ramos ou use --clean para descartar mudanças)" +msgstr "" +"atravessa ramos (mescle os ramos ou use --clean para descartar mudanças)" msgid "crosses branches (merge branches or update --check to force update)" -msgstr "atravessa ramos (mescle os ramos ou use update --check para forçar a atualização)" +msgstr "" +"atravessa ramos (mescle os ramos ou use update --check para forçar a " +"atualização)" msgid "Attention:" msgstr "Atenção:" @@ -19067,7 +20564,9 @@ #, python-format msgid "Hunk #%d succeeded at %d with fuzz %d (offset %d lines).\n" -msgstr "Trecho #%d aplicado com sucesso em %d com indistinção %d (distância %d linhas).\n" +msgstr "" +"Trecho #%d aplicado com sucesso em %d com indistinção %d (distância %d " +"linhas).\n" #, python-format msgid "Hunk #%d succeeded at %d (offset %d lines).\n" @@ -19243,18 +20742,30 @@ msgstr "author requer uma string" msgid "" -"``bisected(string)``\n" -" Changesets marked in the specified bisect state (good, bad, skip)." +"``bisect(string)``\n" +" Changesets marked in the specified bisect status:" msgstr "" "``bisected(string)``\n" -" Revisões marcadas com o estado de bissecção especificado (good, bad, skip)." +" Revisões marcadas com o estado de bissecção especificado:" + +msgid "" +" - ``good``, ``bad``, ``skip``: csets explicitly marked as good/bad/skip\n" +" - ``goods``, ``bads`` : csets topologicaly good/bad\n" +" - ``range`` : csets taking part in the bisection\n" +" - ``pruned`` : csets that are goods, bads or skipped\n" +" - ``untested`` : csets whose fate is yet unknown\n" +" - ``ignored`` : csets ignored due to DAG topology" +msgstr "" +" - ``good``, ``bad``, ``skip``: revs explicitamente marcadas como boas, ruins ou omitidas\n" +" - ``goods``, ``bads`` : revs topologicamente boas ou ruins\n" +" - ``range`` : revs participando da bisecção\n" +" - ``pruned`` : revs goods, bads ou skipped\n" +" - ``untested`` : revs que ainda não foram testadas\n" +" - ``ignored`` : revs ignoradas pela topologia do DAG" msgid "bisect requires a string" msgstr "bisect requer uma string" -msgid "invalid bisect state" -msgstr "estado de bisecção inválido" - msgid "" "``bookmark([name])``\n" " The named bookmark or all bookmarks." @@ -19351,6 +20862,13 @@ msgstr "filelog requer um padrão" msgid "" +"``first(set, [n])``\n" +" An alias for limit()." +msgstr "" +"``first(conjunto, [n])``\n" +" Um apelido para limit()." + +msgid "" "``follow([file])``\n" " An alias for ``::.`` (ancestors of the working copy's first parent).\n" " If a filename is specified, the history of the given file is followed,\n" @@ -19447,15 +20965,15 @@ msgstr "keyword requer uma string" msgid "" -"``limit(set, n)``\n" -" First n members of set." -msgstr "" -"``limit(conjunto, n)``\n" -" Os primeiros n membros do conjunto." +"``limit(set, [n])``\n" +" First n members of set, defaulting to 1." +msgstr "" +"``limit(conjunto, [n])``\n" +" Os primeiros n membros do conjunto. O valor padrão de n é 1." #. i18n: "limit" is a keyword -msgid "limit requires two arguments" -msgstr "limit requer dois argumentos" +msgid "limit requires one or two arguments" +msgstr "limit exige um ou dois argumentos" #. i18n: "limit" is a keyword msgid "limit requires a number" @@ -19466,15 +20984,15 @@ msgstr "limit espera um número" msgid "" -"``last(set, n)``\n" -" Last n members of set." -msgstr "" -"``last(conjunto, n)``\n" -" Os últimos n membros do conjunto." +"``last(set, [n])``\n" +" Last n members of set, defaulting to 1." +msgstr "" +"``last(conjunto, [n])``\n" +" Os últimos n membros do conjunto. O valor padrão de n é 1." #. i18n: "last" is a keyword -msgid "last requires two arguments" -msgstr "last requer dois argumentos" +msgid "last requires one or two arguments" +msgstr "last exige um ou dois argumentos" #. i18n: "last" is a keyword msgid "last requires a number" @@ -19739,14 +21257,18 @@ #, python-format msgid "%s has not been committed yet, so no copy data will be stored for %s.\n" -msgstr "%s ainda não foi consolidado, então dados de cópia não serão guardados para %s.\n" +msgstr "" +"%s ainda não foi consolidado, então dados de cópia não serão guardados para " +"%s.\n" msgid ".hg/requires file is corrupt" msgstr "arquivo .hg/requires corrompido" #, python-format msgid "unknown repository format: requires features '%s' (upgrade Mercurial)" -msgstr "formato de repositório desconhecido: requer as funcionalidades '%s' (atualize o Mercurial)" +msgstr "" +"formato de repositório desconhecido: requer as funcionalidades '%s' " +"(atualize o Mercurial)" msgid "searching for changes\n" msgstr "procurando por mudanças\n" @@ -19799,6 +21321,9 @@ msgid "push refused: %s" msgstr "envio recusado: %s" +msgid "Python SSL support not found" +msgstr "suporte do Python a SSL não instalado" + msgid "certificate checking requires Python 2.6" msgstr "verificação de certificado exige Python 2.6" @@ -19821,23 +21346,33 @@ #, python-format msgid "%s certificate error: %s (use --insecure to connect insecurely)" -msgstr "erro no certificado de %s: %s (use --insecure para conectar de modo inseguro)" +msgstr "" +"erro no certificado de %s: %s (use --insecure para conectar de modo " +"inseguro)" #, python-format msgid "invalid certificate for %s with fingerprint %s" msgstr "certificado inválido para %s com impressão digital %s" #, python-format -msgid "warning: %s certificate with fingerprint %s not verified (check hostfingerprints or web.cacerts config setting)\n" -msgstr "aviso: o certificado %s com impressão digital %s não foi verificado (verifique as opções de configuração hostfingerprints e web.cacerts)\n" +msgid "" +"warning: %s certificate with fingerprint %s not verified (check " +"hostfingerprints or web.cacerts config setting)\n" +msgstr "" +"aviso: o certificado %s com impressão digital %s não foi verificado " +"(verifique as opções de configuração hostfingerprints e web.cacerts)\n" #, python-format msgid "host fingerprint for %s can't be verified (Python too old)" -msgstr "a impressão digital do host para %s não pode ser verificada (versão do Python muito antiga)" +msgstr "" +"a impressão digital do host para %s não pode ser verificada (versão do " +"Python muito antiga)" #, python-format msgid "warning: certificate for %s can't be verified (Python too old)\n" -msgstr "aviso: certificado %s não pode ser verificado (versão do Python muito antiga)\n" +msgstr "" +"aviso: certificado %s não pode ser verificado (versão do Python muito " +"antiga)\n" #, python-format msgid "'%s' does not appear to be an hg repository" @@ -19861,13 +21396,13 @@ msgid "subrepo spec file %s not found" msgstr "arquivo spec de sub-repositório %s não encontrado" -msgid "missing ] in subrepo source" -msgstr "faltando ] na origem do sub-repositório" - #, python-format msgid "bad subrepository pattern in %s: %s" msgstr "padrão ruim de sub-repositório em %s: %s" +msgid "missing ] in subrepo source" +msgstr "faltando ] na origem do sub-repositório" + #, python-format msgid "" " subrepository sources for %s differ\n" @@ -19943,6 +21478,10 @@ msgid "pushing subrepo %s to %s\n" msgstr "enviando sub-repositório %s para %s\n" +#, python-format +msgid "'svn' executable not found for subrepo '%s'" +msgstr "executável 'svn' não encontrado para o sub-repositório '%s'" + msgid "cannot retrieve svn tool version" msgstr "não é possível obter a versão da ferramenta svn" @@ -20142,6 +21681,18 @@ ":short: Hash da revisão. Devolve a forma curta do hash de\n" " uma revisão, ou seja, uma string hexadecimal de 12 dígitos." +msgid "" +":shortbisect: Any text. Treats `text` as a bisection status, and\n" +" returns a single-character representing the status (G: good, B: bad,\n" +" S: skipped, U: untested, I: ignored). Returns single space if `text`\n" +" is not a valid bisection status." +msgstr "" +":shortbisect: Qualquer texto. Trata o texto como um estado de\n" +" bissecção, e devolve um caractere único representando o estado\n" +" (G: boa, B: ruim, S: omitida, U: não testada, I: ignorada).\n" +" Devolve um único espaço se o texto não for um estado de bisecção\n" +" válido." + msgid ":shortdate: Date. Returns a date like \"2006-09-18\"." msgstr ":shortdate: Data. Devolve uma data como \"2006-09-18\"." @@ -20181,11 +21732,15 @@ " \"foo%20bar\"." msgid ":user: Any text. Returns the user portion of an email address." -msgstr ":user: Qualquer texto. Devolve a parte do usuário de um endereço de e-mail." +msgstr "" +":user: Qualquer texto. Devolve a parte do usuário de um endereço de e-mail." msgid ":author: String. The unmodified author of the changeset." msgstr ":author: String. O autor da revisão, sem modificações." +msgid ":bisect: String. The changeset bisection status." +msgstr ":bisect: String. O estado de bissecção da revisão." + msgid "" ":branch: String. The name of the branch on which the changeset was\n" " committed." @@ -20202,7 +21757,8 @@ msgid "" ":bookmarks: List of strings. Any bookmarks associated with the\n" " changeset." -msgstr ":bookmarks: Lista de strings. Quaisquer marcadores associados à revisão." +msgstr "" +":bookmarks: Lista de strings. Quaisquer marcadores associados à revisão." msgid ":children: List of strings. The children of the changeset." msgstr ":children: Lista de strings. As revisões filhas da revisão."
--- a/mercurial/commands.py Wed Oct 26 22:35:15 2011 +0200 +++ b/mercurial/commands.py Thu Oct 27 18:35:07 2011 -0500 @@ -344,7 +344,7 @@ raise util.Abort(_('no working directory: please specify a revision')) node = ctx.node() dest = cmdutil.makefilename(repo, dest, node) - if os.path.realpath(dest) == repo.root: + if util.realpath(dest) == repo.root: raise util.Abort(_('repository root cannot be destination')) kind = opts.get('type') or archival.guesskind(dest) or 'files' @@ -1143,7 +1143,7 @@ _('mark new/missing files as added/removed before committing')), ('', 'close-branch', None, _('mark a branch as closed, hiding it from the branch list')), - ] + walkopts + commitopts + commitopts2, + ] + walkopts + commitopts + commitopts2 + subrepoopts, _('[OPTION]... [FILE]...')) def commit(ui, repo, *pats, **opts): """commit the specified files or all outstanding changes @@ -1167,6 +1167,10 @@ Returns 0 on success, 1 if nothing changed. """ + if opts.get('subrepos'): + # Let --subrepos on the command line overide config setting. + ui.setconfig('ui', 'commitsubrepos', True) + extra = {} if opts.get('close_branch'): if repo['.'].node() not in repo.branchheads(): @@ -2544,19 +2548,20 @@ return -1 # check ancestors for earlier grafts - ui.debug('scanning for existing transplants') + ui.debug('scanning for duplicate grafts\n') for ctx in repo.set("::. - ::%ld", revs): n = ctx.extra().get('source') if n and n in repo: r = repo[n].rev() - ui.warn(_('skipping already grafted revision %s\n') % r) - revs.remove(r) + if r in revs: + ui.warn(_('skipping already grafted revision %s\n') % r) + revs.remove(r) if not revs: return -1 for pos, ctx in enumerate(repo.set("%ld", revs)): current = repo['.'] - ui.status('grafting revision %s', ctx.rev()) + ui.status('grafting revision %s\n' % ctx.rev()) # we don't merge the first commit when continuing if not cont: @@ -2660,7 +2665,7 @@ mstart, mend = match.span() linenum += body.count('\n', begin, mstart) + 1 lstart = body.rfind('\n', begin, mstart) + 1 or begin - begin = body.find('\n', mend) + 1 or len(body) + begin = body.find('\n', mend) + 1 or len(body) + 1 lend = begin - 1 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend] @@ -3352,7 +3357,7 @@ _('use any branch information in patch (implied by --exact)'))] + commitopts + commitopts2 + similarityopts, _('[OPTION]... PATCH...')) -def import_(ui, repo, patch1, *patches, **opts): +def import_(ui, repo, patch1=None, *patches, **opts): """import an ordered set of patches Import a list of patches and commit them individually (unless @@ -3414,6 +3419,10 @@ Returns 0 on success. """ + + if not patch1: + raise util.Abort(_('need at least one patch to import')) + patches = (patch1,) + patches date = opts.get('date') @@ -3537,49 +3546,51 @@ finally: store.close() if n: + # i18n: refers to a short changeset id msg = _('created %s') % short(n) return (msg, n) finally: os.unlink(tmpname) try: - wlock = repo.wlock() - lock = repo.lock() - tr = repo.transaction('import') - parents = repo.parents() - for patchurl in patches: - if patchurl == '-': - ui.status(_('applying patch from stdin\n')) - patchfile = ui.fin - patchurl = 'stdin' # for error message - else: - patchurl = os.path.join(base, patchurl) - ui.status(_('applying %s\n') % patchurl) - patchfile = url.open(ui, patchurl) - - haspatch = False - for hunk in patch.split(patchfile): - (msg, node) = tryone(ui, hunk, parents) - if msg: - haspatch = True - ui.note(msg + '\n') - if update or opts.get('exact'): - parents = repo.parents() + try: + wlock = repo.wlock() + lock = repo.lock() + tr = repo.transaction('import') + parents = repo.parents() + for patchurl in patches: + if patchurl == '-': + ui.status(_('applying patch from stdin\n')) + patchfile = ui.fin + patchurl = 'stdin' # for error message else: - parents = [repo[node]] - - if not haspatch: - raise util.Abort(_('%s: no diffs found') % patchurl) - - tr.close() - if msgs: - repo.savecommitmessage('\n* * *\n'.join(msgs)) - except: - # wlock.release() indirectly calls dirstate.write(): since - # we're crashing, we do not want to change the working dir - # parent after all, so make sure it writes nothing - repo.dirstate.invalidate() - raise + patchurl = os.path.join(base, patchurl) + ui.status(_('applying %s\n') % patchurl) + patchfile = url.open(ui, patchurl) + + haspatch = False + for hunk in patch.split(patchfile): + (msg, node) = tryone(ui, hunk, parents) + if msg: + haspatch = True + ui.note(msg + '\n') + if update or opts.get('exact'): + parents = repo.parents() + else: + parents = [repo[node]] + + if not haspatch: + raise util.Abort(_('%s: no diffs found') % patchurl) + + tr.close() + if msgs: + repo.savecommitmessage('\n* * *\n'.join(msgs)) + except: + # wlock.release() indirectly calls dirstate.write(): since + # we're crashing, we do not want to change the working dir + # parent after all, so make sure it writes nothing + repo.dirstate.invalidate() + raise finally: if tr: tr.release() @@ -4745,15 +4756,14 @@ # only need parent manifest in this unlikely case, # so do not read by default pmf = repo[parent].manifest() - if abs in pmf: - if mfentry: - # if version of file is same in parent and target - # manifests, do nothing - if (pmf[abs] != mfentry or - pmf.flags(abs) != mf.flags(abs)): - handle(revert, False) - else: - handle(remove, False) + if abs in pmf and mfentry: + # if version of file is same in parent and target + # manifests, do nothing + if (pmf[abs] != mfentry or + pmf.flags(abs) != mf.flags(abs)): + handle(revert, False) + else: + handle(remove, False) if not opts.get('dry_run'): def checkout(f):
--- a/mercurial/context.py Wed Oct 26 22:35:15 2011 +0200 +++ b/mercurial/context.py Thu Oct 27 18:35:07 2011 -0500 @@ -632,6 +632,42 @@ def __contains__(self, key): return self._repo.dirstate[key] not in "?r" + def _buildflagfunc(self): + # Create a fallback function for getting file flags when the + # filesystem doesn't support them + + copiesget = self._repo.dirstate.copies().get + + if len(self._parents) < 2: + # when we have one parent, it's easy: copy from parent + man = self._parents[0].manifest() + def func(f): + f = copiesget(f, f) + return man.flags(f) + else: + # merges are tricky: we try to reconstruct the unstored + # result from the merge (issue1802) + p1, p2 = self._parents + pa = p1.ancestor(p2) + m1, m2, ma = p1.manifest(), p2.manifest(), pa.manifest() + + def func(f): + f = copiesget(f, f) # may be wrong for merges with copies + fl1, fl2, fla = m1.flags(f), m2.flags(f), ma.flags(f) + if fl1 == fl2: + return fl1 + if fl1 == fla: + return fl2 + if fl2 == fla: + return fl1 + return '' # punt for conflicts + + return func + + @propertycache + def _flagfunc(self): + return self._repo.dirstate.flagfunc(self._buildflagfunc) + @propertycache def _manifest(self): """generate a manifest corresponding to the working directory""" @@ -640,7 +676,6 @@ self.status(unknown=True) man = self._parents[0].manifest().copy() - copied = self._repo.dirstate.copies() if len(self._parents) > 1: man2 = self.p2().manifest() def getman(f): @@ -649,10 +684,9 @@ return man2 else: getman = lambda f: man - def cf(f): - f = copied.get(f, f) - return getman(f).flags(f) - ff = self._repo.dirstate.flagfunc(cf) + + copied = self._repo.dirstate.copies() + ff = self._flagfunc modified, added, removed, deleted = self._status unknown = self._unknown for i, l in (("a", added), ("m", modified), ("u", unknown)): @@ -767,23 +801,10 @@ except KeyError: return '' - orig = self._repo.dirstate.copies().get(path, path) - - def findflag(ctx): - mnode = ctx.changeset()[0] - node, flag = self._repo.manifest.find(mnode, orig) - ff = self._repo.dirstate.flagfunc(lambda x: flag or '') - try: - return ff(path) - except OSError: - pass - - flag = findflag(self._parents[0]) - if flag is None and len(self.parents()) > 1: - flag = findflag(self._parents[1]) - if flag is None or self._repo.dirstate[path] == 'r': + try: + return self._flagfunc(path) + except OSError: return '' - return flag def filectx(self, path, filelog=None): """get a file context from the working directory"""
--- a/mercurial/dirstate.py Wed Oct 26 22:35:15 2011 +0200 +++ b/mercurial/dirstate.py Thu Oct 27 18:35:07 2011 -0500 @@ -131,17 +131,19 @@ # it's safe because f is always a relative path return self._rootdir + f - def flagfunc(self, fallback): + def flagfunc(self, buildfallback): + if self._checklink and self._checkexec: + def f(x): + p = self._join(x) + if os.path.islink(p): + return 'l' + if util.isexec(p): + return 'x' + return '' + return f + + fallback = buildfallback() if self._checklink: - if self._checkexec: - def f(x): - p = self._join(x) - if os.path.islink(p): - return 'l' - if util.isexec(p): - return 'x' - return '' - return f def f(x): if os.path.islink(self._join(x)): return 'l' @@ -157,7 +159,8 @@ return 'x' return '' return f - return fallback + else: + return fallback def getcwd(self): cwd = os.getcwd()
--- a/mercurial/discovery.py Wed Oct 26 22:35:15 2011 +0200 +++ b/mercurial/discovery.py Thu Oct 27 18:35:07 2011 -0500 @@ -161,7 +161,7 @@ if len(newhs) > len(oldhs): dhs = list(newhs - oldhs) if error is None: - if branch != 'default': + if branch not in ('default', None): error = _("push creates new remote head %s " "on branch '%s'!") % (short(dhs[0]), branch) else: @@ -173,7 +173,8 @@ else: hint = _("did you forget to merge? " "use push -f to force") - repo.ui.note("new remote heads on branch '%s'\n" % branch) + if branch is not None: + repo.ui.note("new remote heads on branch '%s'\n" % branch) for h in dhs: repo.ui.note("new remote head %s\n" % short(h)) if error:
--- a/mercurial/hbisect.py Wed Oct 26 22:35:15 2011 +0200 +++ b/mercurial/hbisect.py Thu Oct 27 18:35:07 2011 -0500 @@ -226,20 +226,27 @@ # Try explicit sets if rev in get(repo, 'good'): + # i18n: bisect changeset status return _('good') if rev in get(repo, 'bad'): + # i18n: bisect changeset status return _('bad') if rev in get(repo, 'skip'): + # i18n: bisect changeset status return _('skipped') if rev in get(repo, 'untested'): + # i18n: bisect changeset status return _('untested') if rev in get(repo, 'ignored'): + # i18n: bisect changeset status return _('ignored') # Try implicit sets if rev in get(repo, 'goods'): + # i18n: bisect changeset status return _('good (implicit)') if rev in get(repo, 'bads'): + # i18n: bisect changeset status return _('bad (implicit)') return None
--- a/mercurial/help/config.txt Wed Oct 26 22:35:15 2011 +0200 +++ b/mercurial/help/config.txt Thu Oct 27 18:35:07 2011 -0500 @@ -1010,7 +1010,7 @@ Whether to commit modified subrepositories when committing the parent repository. If False and one subrepository has uncommitted changes, abort the commit. - Default is True. + Default is False. ``debug`` Print debugging information. True or False. Default is False.
--- a/mercurial/hg.py Wed Oct 26 22:35:15 2011 +0200 +++ b/mercurial/hg.py Thu Oct 27 18:35:07 2011 -0500 @@ -130,7 +130,7 @@ sharedpath = srcrepo.sharedpath # if our source is already sharing - root = os.path.realpath(dest) + root = util.realpath(dest) roothg = os.path.join(root, '.hg') if os.path.exists(roothg): @@ -301,7 +301,7 @@ if copy: srcrepo.hook('preoutgoing', throw=True, source='clone') - hgdir = os.path.realpath(os.path.join(dest, ".hg")) + hgdir = util.realpath(os.path.join(dest, ".hg")) if not os.path.exists(dest): os.mkdir(dest) else:
--- a/mercurial/httpconnection.py Wed Oct 26 22:35:15 2011 +0200 +++ b/mercurial/httpconnection.py Thu Oct 27 18:35:07 2011 -0500 @@ -70,7 +70,11 @@ gdict[setting] = val # Find the best match - scheme, hostpath = uri.split('://', 1) + if '://' in uri: + scheme, hostpath = uri.split('://', 1) + else: + # py2.4.1 doesn't provide the full URI + scheme, hostpath = 'http', uri bestuser = None bestlen = 0 bestauth = None
--- a/mercurial/localrepo.py Wed Oct 26 22:35:15 2011 +0200 +++ b/mercurial/localrepo.py Thu Oct 27 18:35:07 2011 -0500 @@ -28,7 +28,7 @@ def __init__(self, baseui, path=None, create=False): repo.repository.__init__(self) - self.root = os.path.realpath(util.expandpath(path)) + self.root = util.realpath(util.expandpath(path)) self.path = os.path.join(self.root, ".hg") self.origroot = path self.auditor = scmutil.pathauditor(self.root, self._checknested) @@ -79,7 +79,7 @@ self.sharedpath = self.path try: - s = os.path.realpath(self.opener.read("sharedpath").rstrip('\n')) + s = util.realpath(self.opener.read("sharedpath").rstrip('\n')) if not os.path.exists(s): raise error.RepoError( _('.hg/sharedpath points to nonexistent directory %s') % s) @@ -1062,11 +1062,12 @@ '.hgsubstate' not in changes[0] + changes[1] + changes[2]): changes[2].insert(0, '.hgsubstate') - if subs and not self.ui.configbool('ui', 'commitsubrepos', True): + if subs and not self.ui.configbool('ui', 'commitsubrepos', False): changedsubs = [s for s in subs if wctx.sub(s).dirty(True)] if changedsubs: raise util.Abort(_("uncommitted changes in subrepo %s") - % changedsubs[0]) + % changedsubs[0], + hint=_("use --subrepos for recursive commit")) # make sure all explicit patterns are matched if not force and match.files(): @@ -1353,6 +1354,22 @@ added.append(fn) removed = mf1.keys() + if working and modified and not self.dirstate._checklink: + # Symlink placeholders may get non-symlink-like contents + # via user error or dereferencing by NFS or Samba servers, + # so we filter out any placeholders that don't look like a + # symlink + sane = [] + for f in modified: + if ctx2.flags(f) == 'l': + d = ctx2[f].data() + if len(d) >= 1024 or '\n' in d or util.binary(d): + self.ui.debug('ignoring suspect symlink placeholder' + ' "%s"\n' % f) + continue + sane.append(f) + modified = sane + r = modified, added, removed, deleted, unknown, ignored, clean if listsubrepos:
--- a/mercurial/patch.py Wed Oct 26 22:35:15 2011 +0200 +++ b/mercurial/patch.py Thu Oct 27 18:35:07 2011 -0500 @@ -1787,18 +1787,17 @@ diffre = re.compile('^diff .*-r [a-z0-9]+\s(.*)$') results = [] - filename, adds, removes = None, 0, 0 + filename, adds, removes, isbinary = None, 0, 0, False def addresult(): if filename: - isbinary = adds == 0 and removes == 0 results.append((filename, adds, removes, isbinary)) for line in lines: if line.startswith('diff'): addresult() # set numbers to 0 anyway when starting new file - adds, removes = 0, 0 + adds, removes, isbinary = 0, 0, False if line.startswith('diff --git'): filename = gitre.search(line).group(1) elif line.startswith('diff -r'): @@ -1808,6 +1807,9 @@ adds += 1 elif line.startswith('-') and not line.startswith('---'): removes += 1 + elif (line.startswith('GIT binary patch') or + line.startswith('Binary file')): + isbinary = True addresult() return results @@ -1832,7 +1834,7 @@ return max(i * graphwidth // maxtotal, int(bool(i))) for filename, adds, removes, isbinary in stats: - if git and isbinary: + if isbinary: count = 'Bin' else: count = adds + removes
--- a/mercurial/posix.py Wed Oct 26 22:35:15 2011 +0200 +++ b/mercurial/posix.py Thu Oct 27 18:35:07 2011 -0500 @@ -199,6 +199,14 @@ return fcntl.fcntl(fd, F_GETPATH, '\0' * 1024).rstrip('\0') finally: os.close(fd) +elif sys.version_info < (2, 4, 2, 'final'): + # Workaround for http://bugs.python.org/issue1213894 (os.path.realpath + # didn't resolve symlinks that were the first component of the path.) + def realpath(path): + if os.path.isabs(path): + return os.path.realpath(path) + else: + return os.path.realpath('./' + path) else: # Fallback to the likely inadequate Python builtin function. realpath = os.path.realpath
--- a/mercurial/revset.py Wed Oct 26 22:35:15 2011 +0200 +++ b/mercurial/revset.py Thu Oct 27 18:35:07 2011 -0500 @@ -6,7 +6,8 @@ # GNU General Public License version 2 or any later version. import re -import parser, util, error, discovery, hbisect, node +import parser, util, error, discovery, hbisect +import node as nodemod import bookmarks as bookmarksmod import match as matchmod from i18n import _ @@ -1068,6 +1069,8 @@ '(10 or 11):: and ((this()) or (that()))' >>> formatspec('%d:: and not %d::', 10, 20) '10:: and not 20::' + >>> formatspec('%ld or %ld', [], [1]) + '(0-0) or (1)' >>> formatspec('keyword(%s)', 'foo\\xe9') "keyword('foo\\\\xe9')" >>> b = lambda: 'default' @@ -1090,7 +1093,7 @@ parse(arg) # make sure syntax errors are confined return '(%s)' % arg elif c == 'n': - return quote(node.hex(arg)) + return quote(nodemod.hex(arg)) elif c == 'b': return quote(arg.branch()) @@ -1111,7 +1114,10 @@ # a list of some type pos += 1 d = expr[pos] - lv = ' or '.join(argtype(d, e) for e in args[arg]) + if args[arg]: + lv = ' or '.join(argtype(d, e) for e in args[arg]) + else: + lv = '0-0' # a minimal way to represent an empty set ret += '(%s)' % lv arg += 1 else:
--- a/mercurial/simplemerge.py Wed Oct 26 22:35:15 2011 +0200 +++ b/mercurial/simplemerge.py Thu Oct 27 18:35:07 2011 -0500 @@ -430,7 +430,7 @@ except util.Abort: return 1 - local = os.path.realpath(local) + local = util.realpath(local) if not opts.get('print'): opener = scmutil.opener(os.path.dirname(local)) out = opener(os.path.basename(local), "w", atomictemp=True)
--- a/mercurial/subrepo.py Wed Oct 26 22:35:15 2011 +0200 +++ b/mercurial/subrepo.py Thu Oct 27 18:35:07 2011 -0500 @@ -418,6 +418,7 @@ % (inst, subrelpath(self))) def archive(self, ui, archiver, prefix): + self._get(self._state + ('hg',)) abstractsubrepo.archive(self, ui, archiver, prefix) rev = self._state[1] @@ -466,7 +467,7 @@ self._repo.ui.status(_('cloning subrepo %s from %s\n') % (subrelpath(self), srcurl)) parentrepo = self._repo._subparent - shutil.rmtree(self._repo.root) + shutil.rmtree(self._repo.path) other, self._repo = hg.clone(self._repo._subparent.ui, {}, other, self._repo.root, update=False) self._initrepo(parentrepo, source, create=True)
--- a/mercurial/templates/coal/map Wed Oct 26 22:35:15 2011 +0200 +++ b/mercurial/templates/coal/map Thu Oct 27 18:35:07 2011 -0500 @@ -199,7 +199,7 @@ <td><a href="{url}{sessionvars%urlparameter}">{name|escape}</a></td> <td>{description}</td> <td>{contact|obfuscate}</td> - <td class="age">{lastchange|date}</td> + <td class="age">{lastchange|rfc822date}</td> <td class="indexlinks">{archives%indexarchiveentry}</td> </tr>\n' indexarchiveentry = '<a href="{url}archive/{node|short}{extension|urlescape}"> ↓{type|escape}</a>'
--- a/mercurial/templates/gitweb/changelogentry.tmpl Wed Oct 26 22:35:15 2011 +0200 +++ b/mercurial/templates/gitweb/changelogentry.tmpl Thu Oct 27 18:35:07 2011 -0500 @@ -1,5 +1,5 @@ <div> -<a class="title" href="{url}rev/{node|short}{sessionvars%urlparameter}"><span class="age">{date|date}</span>{desc|strip|firstline|escape|nonempty}<span class="logtags"> {inbranch%inbranchtag}{branches%branchtag}{tags%tagtag}{bookmarks%bookmarktag}</span></a> +<a class="title" href="{url}rev/{node|short}{sessionvars%urlparameter}"><span class="age">{date|rfc822date}</span>{desc|strip|firstline|escape|nonempty}<span class="logtags"> {inbranch%inbranchtag}{branches%branchtag}{tags%tagtag}{bookmarks%bookmarktag}</span></a> </div> <div class="title_text"> <div class="log_link">
--- a/mercurial/templates/gitweb/changeset.tmpl Wed Oct 26 22:35:15 2011 +0200 +++ b/mercurial/templates/gitweb/changeset.tmpl Thu Oct 27 18:35:07 2011 -0500 @@ -32,7 +32,7 @@ <div class="title_text"> <table cellspacing="0"> <tr><td>author</td><td>{author|obfuscate}</td></tr> -<tr><td></td><td class="date age">{date|date}</td></tr> +<tr><td></td><td class="date age">{date|rfc822date}</td></tr> {branch%changesetbranch} <tr><td>changeset {rev}</td><td style="font-family:monospace">{node|short}</td></tr> {parent%changesetparent}
--- a/mercurial/templates/gitweb/fileannotate.tmpl Wed Oct 26 22:35:15 2011 +0200 +++ b/mercurial/templates/gitweb/fileannotate.tmpl Thu Oct 27 18:35:07 2011 -0500 @@ -40,7 +40,7 @@ <td>{author|obfuscate}</td></tr> <tr> <td></td> - <td class="date age">{date|date}</td></tr> + <td class="date age">{date|rfc822date}</td></tr> {branch%filerevbranch} <tr> <td>changeset {rev}</td>
--- a/mercurial/templates/gitweb/filerevision.tmpl Wed Oct 26 22:35:15 2011 +0200 +++ b/mercurial/templates/gitweb/filerevision.tmpl Thu Oct 27 18:35:07 2011 -0500 @@ -40,7 +40,7 @@ <td>{author|obfuscate}</td></tr> <tr> <td></td> - <td class="date age">{date|date}</td></tr> + <td class="date age">{date|rfc822date}</td></tr> {branch%filerevbranch} <tr> <td>changeset {rev}</td>
--- a/mercurial/templates/gitweb/map Wed Oct 26 22:35:15 2011 +0200 +++ b/mercurial/templates/gitweb/map Thu Oct 27 18:35:07 2011 -0500 @@ -162,7 +162,7 @@ tags = tags.tmpl tagentry = ' <tr class="parity{parity}"> - <td class="age"><i class="age">{date|date}</i></td> + <td class="age"><i class="age">{date|rfc822date}</i></td> <td><a class="list" href="{url}rev/{node|short}{sessionvars%urlparameter}"><b>{tag|escape}</b></a></td> <td class="link"> <a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a> | @@ -173,7 +173,7 @@ bookmarks = bookmarks.tmpl bookmarkentry = ' <tr class="parity{parity}"> - <td class="age"><i class="age">{date|date}</i></td> + <td class="age"><i class="age">{date|rfc822date}</i></td> <td><a class="list" href="{url}rev/{node|short}{sessionvars%urlparameter}"><b>{bookmark|escape}</b></a></td> <td class="link"> <a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a> | @@ -184,7 +184,7 @@ branches = branches.tmpl branchentry = ' <tr class="parity{parity}"> - <td class="age"><i class="age">{date|date}</i></td> + <td class="age"><i class="age">{date|rfc822date}</i></td> <td><a class="list" href="{url}shortlog/{node|short}{sessionvars%urlparameter}"><b>{node|short}</b></a></td> <td class="{status}">{branch|escape}</td> <td class="link"> @@ -228,7 +228,7 @@ bookmarktag = '<span class="bookmarktag" title="{name}">{name}</span> ' shortlogentry = ' <tr class="parity{parity}"> - <td class="age"><i class="age">{date|date}</i></td> + <td class="age"><i class="age">{date|rfc822date}</i></td> <td><i>{author|person}</i></td> <td> <a class="list" href="{url}rev/{node|short}{sessionvars%urlparameter}"> @@ -243,7 +243,7 @@ </tr>' filelogentry = ' <tr class="parity{parity}"> - <td class="age"><i class="age">{date|date}</i></td> + <td class="age"><i class="age">{date|rfc822date}</i></td> <td> <a class="list" href="{url}rev/{node|short}{sessionvars%urlparameter}"> <b>{desc|strip|firstline|escape|nonempty}</b> @@ -262,7 +262,7 @@ </td> <td>{description}</td> <td>{contact|obfuscate}</td> - <td class="age">{lastchange|date}</td> + <td class="age">{lastchange|rfc822date}</td> <td class="indexlinks">{archives%indexarchiveentry}</td> <td><div class="rss_logo"><a href="{url}rss-log">RSS</a> <a href="{url}atom-log">Atom</a></div></td> </tr>\n'
--- a/mercurial/templates/monoblue/changelogentry.tmpl Wed Oct 26 22:35:15 2011 +0200 +++ b/mercurial/templates/monoblue/changelogentry.tmpl Thu Oct 27 18:35:07 2011 -0500 @@ -1,6 +1,6 @@ <h3 class="changelog"><a class="title" href="{url}rev/{node|short}{sessionvars%urlparameter}">{desc|strip|firstline|escape|nonempty}<span class="logtags"> {inbranch%inbranchtag}{branches%branchtag}{tags%tagtag}{bookmarks%bookmarktag}</span></a></h3> <ul class="changelog-entry"> - <li class="age">{date|date}</li> + <li class="age">{date|rfc822date}</li> <li>by <span class="name">{author|obfuscate}</span> <span class="revdate">[{date|rfc822date}] rev {rev}</span></li> <li class="description">{desc|strip|escape|addbreaks|nonempty}</li> </ul>
--- a/mercurial/templates/monoblue/changeset.tmpl Wed Oct 26 22:35:15 2011 +0200 +++ b/mercurial/templates/monoblue/changeset.tmpl Thu Oct 27 18:35:07 2011 -0500 @@ -38,13 +38,13 @@ <h2 class="no-link no-border">changeset</h2> <h3 class="changeset"><a href="{url}raw-rev/{node|short}">{desc|strip|escape|firstline|nonempty} <span class="logtags">{inbranch%inbranchtag}{branches%branchtag}{tags%tagtag}{bookmarks%bookmarktag}</span></a></h3> - <p class="changeset-age age">{date|date}</p> + <p class="changeset-age age">{date|rfc822date}</p> <dl class="overview"> <dt>author</dt> <dd>{author|obfuscate}</dd> <dt>date</dt> - <dd>{date|date}</dd> + <dd>{date|rfc822date}</dd> {branch%changesetbranch} <dt>changeset {rev}</dt> <dd>{node|short}</dd>
--- a/mercurial/templates/monoblue/fileannotate.tmpl Wed Oct 26 22:35:15 2011 +0200 +++ b/mercurial/templates/monoblue/fileannotate.tmpl Thu Oct 27 18:35:07 2011 -0500 @@ -40,13 +40,13 @@ <h2 class="no-link no-border">{file|escape}@{node|short} (annotated)</h2> <h3 class="changeset">{file|escape}</h3> - <p class="changeset-age age">{date|date}</p> + <p class="changeset-age age">{date|rfc822date}</p> <dl class="overview"> <dt>author</dt> <dd>{author|obfuscate}</dd> <dt>date</dt> - <dd>{date|date}</dd> + <dd>{date|rfc822date}</dd> {branch%filerevbranch} <dt>changeset {rev}</dt> <dd><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></dd>
--- a/mercurial/templates/monoblue/filerevision.tmpl Wed Oct 26 22:35:15 2011 +0200 +++ b/mercurial/templates/monoblue/filerevision.tmpl Thu Oct 27 18:35:07 2011 -0500 @@ -40,13 +40,13 @@ <h2 class="no-link no-border">{file|escape}@{node|short}</h2> <h3 class="changeset">{file|escape}</h3> - <p class="changeset-age age">{date|date}</p> + <p class="changeset-age age">{date|rfc822date}</p> <dl class="overview"> <dt>author</dt> <dd>{author|obfuscate}</dd> <dt>date</dt> - <dd>{date|date}</dd> + <dd>{date|rfc822date}</dd> {branch%filerevbranch} <dt>changeset {rev}</dt> <dd><a class="list" href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></dd>
--- a/mercurial/templates/monoblue/map Wed Oct 26 22:35:15 2011 +0200 +++ b/mercurial/templates/monoblue/map Thu Oct 27 18:35:07 2011 -0500 @@ -141,7 +141,7 @@ tags = tags.tmpl tagentry = ' <tr class="parity{parity}"> - <td class="nowrap age">{date|date}</td> + <td class="nowrap age">{date|rfc822date}</td> <td><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{tag|escape}</a></td> <td class="nowrap"> <a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a> | @@ -152,7 +152,7 @@ bookmarks = bookmarks.tmpl bookmarkentry = ' <tr class="parity{parity}"> - <td class="nowrap date">{date|date}</td> + <td class="nowrap date">{date|rfc822date}</td> <td><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{bookmark|escape}</a></td> <td class="nowrap"> <a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a> | @@ -163,7 +163,7 @@ branches = branches.tmpl branchentry = ' <tr class="parity{parity}"> - <td class="nowrap age">{date|date}</td> + <td class="nowrap age">{date|rfc822date}</td> <td><a href="{url}shortlog/{node|short}{sessionvars%urlparameter}">{node|short}</a></td> <td class="{status}">{branch|escape}</td> <td class="nowrap"> @@ -196,7 +196,7 @@ bookmarktag = '<span class="bookmarktag" title="{name}">{name}</span> ' shortlogentry = ' <tr class="parity{parity}"> - <td class="nowrap age">{date|date}</td> + <td class="nowrap age">{date|rfc822date}</td> <td>{author|person}</td> <td> <a href="{url}rev/{node|short}{sessionvars%urlparameter}"> @@ -211,7 +211,7 @@ </tr>' filelogentry = ' <tr class="parity{parity}"> - <td class="nowrap age">{date|date}</td> + <td class="nowrap age">{date|rfc822date}</td> <td><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{desc|strip|firstline|escape|nonempty}</a></td> <td class="nowrap"> <a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file</a> | <a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a> | <a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">annotate</a> @@ -224,7 +224,7 @@ <td><a href="{url}{sessionvars%urlparameter}">{name|escape}</a></td> <td>{description}</td> <td>{contact|obfuscate}</td> - <td class="age">{lastchange|date}</td> + <td class="age">{lastchange|rfc822date}</td> <td class="indexlinks">{archives%indexarchiveentry}</td> <td> <div class="rss_logo">
--- a/mercurial/templates/paper/changeset.tmpl Wed Oct 26 22:35:15 2011 +0200 +++ b/mercurial/templates/paper/changeset.tmpl Thu Oct 27 18:35:07 2011 -0500 @@ -49,7 +49,7 @@ </tr> <tr> <th class="date">date</th> - <td class="date age">{date|date}</td></tr> + <td class="date age">{date|rfc822date}</td></tr> <tr> <th class="author">parents</th> <td class="author">{parent%changesetparent}</td>
--- a/mercurial/templates/paper/fileannotate.tmpl Wed Oct 26 22:35:15 2011 +0200 +++ b/mercurial/templates/paper/fileannotate.tmpl Thu Oct 27 18:35:07 2011 -0500 @@ -54,7 +54,7 @@ </tr> <tr> <th class="date">date</th> - <td class="date age">{date|date}</td> + <td class="date age">{date|rfc822date}</td> </tr> <tr> <th class="author">parents</th>
--- a/mercurial/templates/paper/filediff.tmpl Wed Oct 26 22:35:15 2011 +0200 +++ b/mercurial/templates/paper/filediff.tmpl Thu Oct 27 18:35:07 2011 -0500 @@ -53,7 +53,7 @@ </tr> <tr> <th>date</th> - <td class="date age">{date|date}</td> + <td class="date age">{date|rfc822date}</td> </tr> <tr> <th>parents</th>
--- a/mercurial/templates/paper/filelogentry.tmpl Wed Oct 26 22:35:15 2011 +0200 +++ b/mercurial/templates/paper/filelogentry.tmpl Thu Oct 27 18:35:07 2011 -0500 @@ -1,5 +1,5 @@ <tr class="parity{parity}"> - <td class="age">{date|date}</td> + <td class="age">{date|rfc822date}</td> <td class="author">{author|person}</td> <td class="description"><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{desc|strip|firstline|escape|nonempty}</a>{inbranch%changelogbranchname}{branches%changelogbranchhead}{tags%changelogtag}{rename%filelogrename}</td> </tr>
--- a/mercurial/templates/paper/filerevision.tmpl Wed Oct 26 22:35:15 2011 +0200 +++ b/mercurial/templates/paper/filerevision.tmpl Thu Oct 27 18:35:07 2011 -0500 @@ -52,7 +52,7 @@ </tr> <tr> <th class="date">date</th> - <td class="date age">{date|date}</td> + <td class="date age">{date|rfc822date}</td> </tr> <tr> <th class="author">parents</th>
--- a/mercurial/templates/paper/map Wed Oct 26 22:35:15 2011 +0200 +++ b/mercurial/templates/paper/map Thu Oct 27 18:35:07 2011 -0500 @@ -198,7 +198,7 @@ <td><a href="{url}{sessionvars%urlparameter}">{name|escape}</a></td> <td>{description}</td> <td>{contact|obfuscate}</td> - <td class="age">{lastchange|date}</td> + <td class="age">{lastchange|rfc822date}</td> <td class="indexlinks">{archives%indexarchiveentry}</td> </tr>\n' indexarchiveentry = '<a href="{url}archive/{node|short}{extension|urlescape}"> ↓{type|escape}</a>'
--- a/mercurial/templates/paper/shortlogentry.tmpl Wed Oct 26 22:35:15 2011 +0200 +++ b/mercurial/templates/paper/shortlogentry.tmpl Thu Oct 27 18:35:07 2011 -0500 @@ -1,5 +1,5 @@ <tr class="parity{parity}"> - <td class="age">{date|date}</td> + <td class="age">{date|rfc822date}</td> <td class="author">{author|person}</td> <td class="description"><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{desc|strip|firstline|escape|nonempty}</a>{inbranch%changelogbranchname}{branches%changelogbranchhead}{tags % '<span class="tag">{name|escape}</span> '}{bookmarks % '<span class="tag">{name|escape}</span> '}</td> </tr>
--- a/mercurial/templates/spartan/changelogentry.tmpl Wed Oct 26 22:35:15 2011 +0200 +++ b/mercurial/templates/spartan/changelogentry.tmpl Thu Oct 27 18:35:07 2011 -0500 @@ -1,6 +1,6 @@ <table class="logEntry parity{parity}"> <tr> - <th><span class="age">{date|date}</span>:</th> + <th><span class="age">{date|rfc822date}</span>:</th> <th class="firstline">{desc|strip|firstline|escape|nonempty}</th> </tr> <tr> @@ -16,7 +16,7 @@ </tr> <tr> <th class="date">date:</th> - <td class="date">{date|date}</td> + <td class="date">{date|rfc822date}</td> </tr> <tr> <th class="files"><a href="{url}file/{node|short}{sessionvars%urlparameter}">files</a>:</th>
--- a/mercurial/templates/spartan/changeset.tmpl Wed Oct 26 22:35:15 2011 +0200 +++ b/mercurial/templates/spartan/changeset.tmpl Thu Oct 27 18:35:07 2011 -0500 @@ -31,7 +31,7 @@ </tr> <tr> <th class="date">date:</th> - <td class="date age">{date|date}</td> + <td class="date age">{date|rfc822date}</td> </tr> <tr> <th class="files">files:</th>
--- a/mercurial/templates/spartan/fileannotate.tmpl Wed Oct 26 22:35:15 2011 +0200 +++ b/mercurial/templates/spartan/fileannotate.tmpl Thu Oct 27 18:35:07 2011 -0500 @@ -30,7 +30,7 @@ <td>{author|obfuscate}</td></tr> <tr> <td class="metatag">date:</td> - <td class="date age">{date|date}</td> + <td class="date age">{date|rfc822date}</td> </tr> <tr> <td class="metatag">permissions:</td>
--- a/mercurial/templates/spartan/filelogentry.tmpl Wed Oct 26 22:35:15 2011 +0200 +++ b/mercurial/templates/spartan/filelogentry.tmpl Thu Oct 27 18:35:07 2011 -0500 @@ -1,6 +1,6 @@ <table class="logEntry parity{parity}"> <tr> - <th><span class="age">{date|date}</span>:</th> + <th><span class="age">{date|rfc822date}</span>:</th> <th class="firstline"><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{desc|strip|firstline|escape|nonempty}</a></th> </tr> <tr> @@ -18,7 +18,7 @@ </tr> <tr> <th class="date">date:</th> - <td class="date">{date|date}</td> + <td class="date">{date|rfc822date}</td> </tr> </table>
--- a/mercurial/templates/spartan/filerevision.tmpl Wed Oct 26 22:35:15 2011 +0200 +++ b/mercurial/templates/spartan/filerevision.tmpl Thu Oct 27 18:35:07 2011 -0500 @@ -30,7 +30,7 @@ <td>{author|obfuscate}</td></tr> <tr> <td class="metatag">date:</td> - <td class="date age">{date|date}</td></tr> + <td class="date age">{date|rfc822date}</td></tr> <tr> <td class="metatag">permissions:</td> <td>{permissions|permissions}</td></tr>
--- a/mercurial/templates/spartan/map Wed Oct 26 22:35:15 2011 +0200 +++ b/mercurial/templates/spartan/map Thu Oct 27 18:35:07 2011 -0500 @@ -168,7 +168,7 @@ <td><a href="{url}{sessionvars%urlparameter}">{name|escape}</a></td> <td>{description}</td> <td>{contact|obfuscate}</td> - <td class="age">{lastchange|date}</td> + <td class="age">{lastchange|rfc822date}</td> <td class="indexlinks"> <a href="{url}rss-log">RSS</a> <a href="{url}atom-log">Atom</a>
--- a/mercurial/templates/spartan/shortlogentry.tmpl Wed Oct 26 22:35:15 2011 +0200 +++ b/mercurial/templates/spartan/shortlogentry.tmpl Thu Oct 27 18:35:07 2011 -0500 @@ -1,6 +1,6 @@ <table class="slogEntry parity{parity}"> <tr> - <td class="age">{date|date}</td> + <td class="age">{date|rfc822date}</td> <td class="author">{author|person}</td> <td class="node"><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{desc|strip|firstline|escape|nonempty}</a></td> </tr>
--- a/mercurial/util.py Wed Oct 26 22:35:15 2011 +0200 +++ b/mercurial/util.py Thu Oct 27 18:35:07 2011 -0500 @@ -514,6 +514,7 @@ "filename contains '\\\\x07', which is invalid on Windows" >>> checkwinfilename("foo/bar/bla ") "filename ends with ' ', which is not allowed on Windows" + >>> checkwinfilename("../bar") ''' for n in path.replace('\\', '/').split('/'): if not n: @@ -530,7 +531,7 @@ return _("filename contains '%s', which is reserved " "on Windows") % base t = n[-1] - if t in '. ': + if t in '. ' and n not in '..': return _("filename ends with '%s', which is not allowed " "on Windows") % t
--- a/setup.py Wed Oct 26 22:35:15 2011 +0200 +++ b/setup.py Thu Oct 27 18:35:07 2011 -0500 @@ -133,14 +133,14 @@ version = '' +env = {'HGRCPATH': '', 'LANGUAGE': 'C'} + if os.path.isdir('.hg'): # Execute hg out of this directory with a custom environment which # includes the pure Python modules in mercurial/pure. We also take # care to not use any hgrc files and do no localization. pypath = ['mercurial', os.path.join('mercurial', 'pure')] - env = {'PYTHONPATH': os.pathsep.join(pypath), - 'HGRCPATH': '', - 'LANGUAGE': 'C'} + env['PYTHONPATH'] = os.pathsep.join(pypath) if 'LD_LIBRARY_PATH' in os.environ: env['LD_LIBRARY_PATH'] = os.environ['LD_LIBRARY_PATH'] if 'SystemRoot' in os.environ:
--- a/tests/hghave Wed Oct 26 22:35:15 2011 +0200 +++ b/tests/hghave Thu Oct 27 18:35:07 2011 -0500 @@ -140,6 +140,9 @@ def has_svn15(): return getsvnversion() >= (1, 5) +def has_svn13(): + return getsvnversion() >= (1, 3) + def has_svn(): return matchoutput('svn --version 2>&1', r'^svn, version') and \ matchoutput('svnadmin --version 2>&1', r'^svnadmin, version') @@ -230,6 +233,7 @@ "pygments": (has_pygments, "Pygments source highlighting library"), "ssl": (has_ssl, "python >= 2.6 ssl module and python OpenSSL"), "svn": (has_svn, "subversion client and admin tools"), + "svn13": (has_svn13, "subversion client and admin tools >= 1.3"), "svn15": (has_svn15, "subversion client and admin tools >= 1.5"), "svn-bindings": (has_svn_bindings, "subversion python bindings"), "symlink": (has_symlink, "symbolic links"),
--- a/tests/run-tests.py Wed Oct 26 22:35:15 2011 +0200 +++ b/tests/run-tests.py Thu Oct 27 18:35:07 2011 -0500 @@ -1129,6 +1129,8 @@ os.environ['COLUMNS'] = '80' os.environ['GREP_OPTIONS'] = '' os.environ['http_proxy'] = '' + os.environ['no_proxy'] = '' + os.environ['NO_PROXY'] = '' # unset env related to hooks for k in os.environ.keys():
--- a/tests/test-check-code.t Wed Oct 26 22:35:15 2011 +0200 +++ b/tests/test-check-code.t Thu Oct 27 18:35:07 2011 -0500 @@ -26,6 +26,23 @@ > # Do not complain about our own definition > def any(x): > pass + > + > # try/except/finally block does not exist in Python 2.4 + > try: + > pass + > except StandardError, inst: + > pass + > finally: + > pass + > + > # nested try/finally+try/except is allowed + > try: + > try: + > pass + > except StandardError, inst: + > pass + > finally: + > pass > EOF $ cat > classstyle.py <<EOF > class newstyle_class(object): @@ -50,8 +67,8 @@ Python keyword is not a function ./wrong.py:3: > return ( 5+6, 9) + gratuitous whitespace in () or [] missing whitespace in expression - gratuitous whitespace in () or [] ./quote.py:5: > '"""', 42+1, """and missing whitespace in expression @@ -64,6 +81,9 @@ ./non-py24.py:4: > y = format(x) any/all/format not available in Python 2.4 + ./non-py24.py:11: + > try: + no try/except/finally in Py2.4 ./classstyle.py:4: > class oldstyle_class: old-style class, use class foo(object)
--- a/tests/test-check-pyflakes.t Wed Oct 26 22:35:15 2011 +0200 +++ b/tests/test-check-pyflakes.t Thu Oct 27 18:35:07 2011 -0500 @@ -1,5 +1,5 @@ $ "$TESTDIR/hghave" pyflakes || exit 80 - $ cd $(dirname $TESTDIR) + $ cd `dirname $TESTDIR` $ pyflakes mercurial hgext 2>&1 | $TESTDIR/filterpyflakes.py hgext/inotify/linux/__init__.py:*: 'from _inotify import *' used; unable to detect undefined names (glob)
--- a/tests/test-convert-darcs.t Wed Oct 26 22:35:15 2011 +0200 +++ b/tests/test-convert-darcs.t Thu Oct 27 18:35:07 2011 -0500 @@ -48,7 +48,7 @@ $ darcs record -a -l -m p1.2 Finished recording patch 'p1.2' - $ darcs pull -a ../darcs-clone + $ darcs pull -a --no-set-default ../darcs-clone Backing up ./a(-darcs-backup0) We have conflicts in the following files: ./a @@ -74,41 +74,6 @@ $ darcs record -a -l -m p3 Finished recording patch 'p3' -test utf-8 commit message and author - - $ echo g > g - -darcs is encoding agnostic, so it takes whatever bytes it's given - - $ darcs record -a -l -m 'p4: desc ñ' -A 'author ñ' - Finished recording patch 'p4: desc \xc3\xb1' (esc) - -Test latin-1 commit message - - $ echo h > h - $ printf "p5: desc " > ../p5 - $ python -c 'print "".join([chr(i) for i in range(128, 256)])' >> ../p5 - $ darcs record -a -l --logfile ../p5 - Finished recording patch 'p5: desc \x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff' (esc) - - $ glog() - > { - > HGENCODING=utf-8 hg glog --template '{rev} "{desc|firstline}" ({author}) files: {files}\n' "$@" - > } - $ cd .. - $ hg convert darcs-repo darcs-repo-hg - initializing destination darcs-repo-hg repository - scanning source... - sorting... - converting... - 6 p0 - 5 p1.2 - 4 p1.1 - 3 p2 - 2 p3 - 1 p4: desc ? - 0 p5: desc ???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? - The converter does not currently handle patch conflicts very well. When they occur, it reverts *all* changes and moves forward, letting the conflict resolving patch fix collisions. @@ -116,22 +81,23 @@ "c" file in p1.1 patch are reverted too. Just to say that manifest not listing "c" here is a bug. - $ HGENCODING=latin-1 glog -R darcs-repo-hg -r 6 - o 6 "p5: desc \xc2\x80\xc2\x81\xc2\x82\xc2\x83\xc2\x84\xc2\x85\xc2\x86\xc2\x87\xc2\x88\xc2\x89\xc2\x8a\xc2\x8b\xc2\x8c\xc2\x8d\xc2\x8e\xc2\x8f\xc2\x90\xc2\x91\xc2\x92\xc2\x93\xc2\x94\xc2\x95\xc2\x96\xc2\x97\xc2\x98\xc2\x99\xc2\x9a\xc2\x9b\xc2\x9c\xc2\x9d\xc2\x9e\xc2\x9f\xc2\xa0\xc2\xa1\xc2\xa2\xc2\xa3\xc2\xa4\xc2\xa5\xc2\xa6\xc2\xa7\xc2\xa8\xc2\xa9\xc2\xaa\xc2\xab\xc2\xac\xc2\xad\xc2\xae\xc2\xaf\xc2\xb0\xc2\xb1\xc2\xb2\xc2\xb3\xc2\xb4\xc2\xb5\xc2\xb6\xc2\xb7\xc2\xb8\xc2\xb9\xc2\xba\xc2\xbb\xc2\xbc\xc2\xbd\xc2\xbe\xc2\xbf\xc3\x80\xc3\x81\xc3\x82\xc3\x83\xc3\x84\xc3\x85\xc3\x86\xc3\x87\xc3\x88\xc3\x89\xc3\x8a\xc3\x8b\xc3\x8c\xc3\x8d\xc3\x8e\xc3\x8f\xc3\x90\xc3\x91\xc3\x92\xc3\x93\xc3\x94\xc3\x95\xc3\x96\xc3\x97\xc3\x98\xc3\x99\xc3\x9a\xc3\x9b\xc3\x9c\xc3\x9d\xc3\x9e\xc3\x9f\xc3\xa0\xc3\xa1\xc3\xa2\xc3\xa3\xc3\xa4\xc3\xa5\xc3\xa6\xc3\xa7\xc3\xa8\xc3\xa9\xc3\xaa\xc3\xab\xc3\xac\xc3\xad\xc3\xae\xc3\xaf\xc3\xb0\xc3\xb1\xc3\xb2\xc3\xb3\xc3\xb4\xc3\xb5\xc3\xb6\xc3\xb7\xc3\xb8\xc3\xb9\xc3\xba\xc3\xbb\xc3\xbc\xc3\xbd\xc3\xbe\xc3\xbf" (test@example.org) files: h (esc) - | - $ HGENCODING=utf-8 glog -R darcs-repo-hg -r 0:5 - o 5 "p4: desc \xc3\xb1" (author \xc3\xb1) files: g (esc) - | - o 4 "p3" (test@example.org) files: dir/d dir/d2 dir2/d f ff - | - o 3 "p2" (test@example.org) files: a dir/d dir/d2 f - | - o 2 "p1.1" (test@example.org) files: - | - o 1 "p1.2" (test@example.org) files: a b - | - o 0 "p0" (test@example.org) files: a - + $ cd .. + $ hg convert darcs-repo darcs-repo-hg + initializing destination darcs-repo-hg repository + scanning source... + sorting... + converting... + 4 p0 + 3 p1.2 + 2 p1.1 + 1 p2 + 0 p3 + $ hg log -R darcs-repo-hg -g --template '{rev} "{desc|firstline}" ({author}) files: {files}\n' "$@" + 4 "p3" (test@example.org) files: dir/d dir/d2 dir2/d f ff + 3 "p2" (test@example.org) files: a dir/d dir/d2 f + 2 "p1.1" (test@example.org) files: + 1 "p1.2" (test@example.org) files: a b + 0 "p0" (test@example.org) files: a $ hg up -q -R darcs-repo-hg $ hg -R darcs-repo-hg manifest --debug @@ -139,5 +105,3 @@ 1e88685f5ddec574a34c70af492f95b6debc8741 644 b 37406831adc447ec2385014019599dfec953c806 644 dir2/d b783a337463792a5c7d548ad85a7d3253c16ba8c 644 ff - 0973eb1b2ecc4de7fafe7447ce1b7462108b4848 644 g - fe6f8b4f507fe3eb524c527192a84920a4288dac 644 h
--- a/tests/test-convert-svn-sink.t Wed Oct 26 22:35:15 2011 +0200 +++ b/tests/test-convert-svn-sink.t Thu Oct 27 18:35:07 2011 -0500 @@ -1,5 +1,5 @@ - $ "$TESTDIR/hghave" svn no-outer-repo || exit 80 + $ "$TESTDIR/hghave" svn13 no-outer-repo || exit 80 $ fixpath() > {
--- a/tests/test-convert.t Wed Oct 26 22:35:15 2011 +0200 +++ b/tests/test-convert.t Thu Oct 27 18:35:07 2011 -0500 @@ -132,7 +132,7 @@ 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. + change). It takes a 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.
--- a/tests/test-debugcomplete.t Wed Oct 26 22:35:15 2011 +0200 +++ b/tests/test-debugcomplete.t Thu Oct 27 18:35:07 2011 -0500 @@ -191,7 +191,7 @@ add: include, exclude, subrepos, dry-run annotate: rev, follow, no-follow, text, user, file, date, number, changeset, line-number, include, exclude clone: noupdate, updaterev, rev, branch, pull, uncompressed, ssh, remotecmd, insecure - commit: addremove, close-branch, include, exclude, message, logfile, date, user + commit: addremove, close-branch, include, exclude, message, logfile, date, user, subrepos diff: rev, change, text, git, nodates, show-function, reverse, ignore-all-space, ignore-space-change, ignore-blank-lines, unified, stat, include, exclude, subrepos export: output, switch-parent, rev, text, git, nodates forget: include, exclude
--- a/tests/test-diffstat.t Wed Oct 26 22:35:15 2011 +0200 +++ b/tests/test-diffstat.t Thu Oct 27 18:35:07 2011 -0500 @@ -36,19 +36,21 @@ $ hg ci -m appenda $ printf '\0' > c - $ hg add c + $ touch d + $ hg add c d Binary diffstat: $ hg diff --stat - c | 0 + c | Bin 1 files changed, 0 insertions(+), 0 deletions(-) Binary git diffstat: $ hg diff --stat --git c | Bin - 1 files changed, 0 insertions(+), 0 deletions(-) + d | 0 + 2 files changed, 0 insertions(+), 0 deletions(-) $ hg ci -m createb @@ -58,7 +60,7 @@ Filename with spaces diffstat: $ hg diff --stat - file with spaces | 0 + file with spaces | Bin 1 files changed, 0 insertions(+), 0 deletions(-) Filename with spaces git diffstat:
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-graft.t Thu Oct 27 18:35:07 2011 -0500 @@ -0,0 +1,227 @@ +Create a repo with some stuff in it: + + $ hg init a + $ cd a + $ echo a > a + $ echo a > d + $ echo a > e + $ hg ci -qAm0 + $ echo b > a + $ hg ci -m1 -u bar + $ hg mv a b + $ hg ci -m2 + $ hg cp b c + $ hg ci -m3 -u baz + $ echo b > d + $ echo f > e + $ hg ci -m4 + $ hg up -q 3 + $ echo b > e + $ hg branch -q stable + $ hg ci -m5 + $ hg merge -q default --tool internal:local + $ hg branch -q default + $ hg ci -m6 + +Need to specify a rev: + + $ hg graft + abort: no revisions specified + [255] + +Can't graft ancestor: + + $ hg graft 1 2 + skipping ancestor revision 1 + skipping ancestor revision 2 + [255] + +Can't graft with dirty wd: + + $ hg up -q 0 + $ echo foo > a + $ hg graft 1 + abort: outstanding uncommitted changes + [255] + $ hg revert a + +Graft a rename: + + $ hg graft 2 -u foo + grafting revision 2 + merging a and b to b + $ hg export tip --git + # HG changeset patch + # User foo + # Date 0 0 + # Node ID d2e44c99fd3f31c176ea4efb9eca9f6306c81756 + # Parent 68795b066622ca79a25816a662041d8f78f3cd9e + 2 + + diff --git a/a b/b + rename from a + rename to b + --- a/a + +++ b/b + @@ -1,1 +1,1 @@ + -a + +b + +Look for extra:source + + $ hg log --debug -r tip + changeset: 7:d2e44c99fd3f31c176ea4efb9eca9f6306c81756 + tag: tip + parent: 0:68795b066622ca79a25816a662041d8f78f3cd9e + parent: -1:0000000000000000000000000000000000000000 + manifest: 7:5d59766436fd8fbcd38e7bebef0f6eaf3eebe637 + user: foo + date: Thu Jan 01 00:00:00 1970 +0000 + files+: b + files-: a + extra: branch=default + extra: source=5c095ad7e90f871700f02dd1fa5012cb4498a2d4 + description: + 2 + + + +Graft out of order, skipping a merge and a duplicate + + $ hg graft 1 5 4 3 'merge()' 2 --debug + skipping ungraftable merge revision 6 + scanning for duplicate grafts + skipping already grafted revision 2 + grafting revision 1 + searching for copies back to rev 1 + unmatched files in local: + a.orig + b + all copies found (* = to merge, ! = divergent): + b -> a * + checking for directory renames + resolving manifests + overwrite False partial False + ancestor 68795b066622 local d2e44c99fd3f+ remote 5d205f8b35b6 + b: local copied/moved to a -> m + preserving b for resolve of b + updating: b 1/1 files (100.00%) + searching for copies back to rev 1 + unmatched files in local: + a + unmatched files in other: + b + all copies found (* = to merge, ! = divergent): + b -> a * + checking for directory renames + b + b: searching for copy revision for a + b: copy a:b789fdd96dc2f3bd229c1dd8eedf0fc60e2b68e3 + grafting revision 5 + searching for copies back to rev 1 + unmatched files in local: + a.orig + resolving manifests + overwrite False partial False + ancestor 4c60f11aa304 local 6f5ea6ac8b70+ remote 97f8bfe72746 + e: remote is newer -> g + updating: e 1/1 files (100.00%) + getting e + searching for copies back to rev 1 + unmatched files in local: + c + all copies found (* = to merge, ! = divergent): + c -> b * + checking for directory renames + e + grafting revision 4 + searching for copies back to rev 1 + unmatched files in local: + a.orig + resolving manifests + overwrite False partial False + ancestor 4c60f11aa304 local 77eb504366ab+ remote 9c233e8e184d + e: versions differ -> m + d: remote is newer -> g + preserving e for resolve of e + updating: d 1/2 files (50.00%) + getting d + updating: e 2/2 files (100.00%) + picked tool 'internal:merge' for e (binary False symlink False) + merging e + my e@77eb504366ab+ other e@9c233e8e184d ancestor e@68795b066622 + warning: conflicts during merge. + merging e failed! + searching for copies back to rev 1 + unmatched files in local: + c + all copies found (* = to merge, ! = divergent): + c -> b * + checking for directory renames + abort: unresolved conflicts, can't continue + (use hg resolve and hg graft --continue) + [255] + +Continue without resolve should fail: + + $ hg graft -c + grafting revision 4 + abort: unresolved merge conflicts (see hg help resolve) + [255] + +Fix up: + + $ echo b > e + $ hg resolve -m e + +Continue with a revision should fail: + + $ hg graft -c 6 + abort: can't specify --continue and revisions + [255] + +Continue for real, clobber usernames + + $ hg graft -c -U + grafting revision 4 + grafting revision 3 + +Compare with original: + + $ hg diff -r 6 + $ hg status --rev 0:. -C + M d + M e + A b + a + A c + a + R a + +View graph: + + $ hg --config extensions.graphlog= log -G --template '{author}@rev: {desc}\n' + @ test@rev: 3 + | + o test@rev: 4 + | + o test@rev: 5 + | + o bar@rev: 1 + | + o foo@rev: 2 + | + | o test@rev: 6 + | |\ + | | o test@rev: 5 + | | | + | o | test@rev: 4 + | |/ + | o baz@rev: 3 + | | + | o test@rev: 2 + | | + | o bar@rev: 1 + |/ + o test@rev: 0 +
--- a/tests/test-grep.t Wed Oct 26 22:35:15 2011 +0200 +++ b/tests/test-grep.t Thu Oct 27 18:35:07 2011 -0500 @@ -106,12 +106,8 @@ $ python -c 'fp = open("noeol", "wb"); fp.write("no infinite loop"); fp.close();' $ hg ci -Amnoeol adding noeol - -last character omitted in output to avoid infinite loop - $ hg grep loop - noeol:4:no infinite loo - + noeol:4:no infinite loop $ cd ..
--- a/tests/test-hgrc.t Wed Oct 26 22:35:15 2011 +0200 +++ b/tests/test-hgrc.t Thu Oct 27 18:35:07 2011 -0500 @@ -3,13 +3,19 @@ $ HGRCPATH=`pwd`/hgrc $ export HGRCPATH +Use an alternate var for scribbling on hgrc to keep check-code from +complaining about the important settings we may be overwriting: + + $ HGRC=`pwd`/hgrc + $ export HGRC + Basic syntax error - $ echo "invalid" > $HGRCPATH + $ echo "invalid" > $HGRC $ hg version hg: parse error at $TESTTMP/hgrc:1: invalid [255] - $ echo "" > $HGRCPATH + $ echo "" > $HGRC Issue1199: Can't use '%' in hgrc (eg url encoded username) @@ -30,21 +36,21 @@ issue1829: wrong indentation - $ echo '[foo]' > $HGRCPATH - $ echo ' x = y' >> $HGRCPATH + $ echo '[foo]' > $HGRC + $ echo ' x = y' >> $HGRC $ hg version hg: parse error at $TESTTMP/hgrc:2: x = y [255] $ python -c "print '[foo]\nbar = a\n b\n c \n de\n fg \nbaz = bif cb \n'" \ - > > $HGRCPATH + > > $HGRC $ hg showconfig foo foo.bar=a\nb\nc\nde\nfg foo.baz=bif cb $ FAKEPATH=/path/to/nowhere $ export FAKEPATH - $ echo '%include $FAKEPATH/no-such-file' > $HGRCPATH + $ echo '%include $FAKEPATH/no-such-file' > $HGRC $ hg version Mercurial Distributed SCM (version *) (glob) (see http://mercurial.selenic.com for more information) @@ -75,8 +81,8 @@ $ FAKEUSER='John Doe' $ export FAKEUSER - $ echo '[ui]' > $HGRCPATH - $ echo 'username = $FAKEUSER' >> $HGRCPATH + $ echo '[ui]' > $HGRC + $ echo 'username = $FAKEUSER' >> $HGRC $ hg init usertest $ cd usertest @@ -95,10 +101,10 @@ showconfig with multiple arguments - $ echo "[alias]" > $HGRCPATH - $ echo "log = log -g" >> $HGRCPATH - $ echo "[defaults]" >> $HGRCPATH - $ echo "identify = -n" >> $HGRCPATH + $ echo "[alias]" > $HGRC + $ echo "log = log -g" >> $HGRC + $ echo "[defaults]" >> $HGRC + $ echo "identify = -n" >> $HGRC $ hg showconfig alias defaults alias.log=log -g defaults.identify=-n @@ -113,19 +119,19 @@ $ cd .. $ p=`pwd` - $ echo "[ui]" > $HGRCPATH - $ echo "debug=true" >> $HGRCPATH - $ echo "fallbackencoding=ASCII" >> $HGRCPATH - $ echo "quiet=true" >> $HGRCPATH - $ echo "slash=true" >> $HGRCPATH - $ echo "traceback=true" >> $HGRCPATH - $ echo "verbose=true" >> $HGRCPATH - $ echo "style=~/.hgstyle" >> $HGRCPATH - $ echo "logtemplate={node}" >> $HGRCPATH - $ echo "[defaults]" >> $HGRCPATH - $ echo "identify=-n" >> $HGRCPATH - $ echo "[alias]" >> $HGRCPATH - $ echo "log=log -g" >> $HGRCPATH + $ echo "[ui]" > $HGRC + $ echo "debug=true" >> $HGRC + $ echo "fallbackencoding=ASCII" >> $HGRC + $ echo "quiet=true" >> $HGRC + $ echo "slash=true" >> $HGRC + $ echo "traceback=true" >> $HGRC + $ echo "verbose=true" >> $HGRC + $ echo "style=~/.hgstyle" >> $HGRC + $ echo "logtemplate={node}" >> $HGRC + $ echo "[defaults]" >> $HGRC + $ echo "identify=-n" >> $HGRC + $ echo "[alias]" >> $HGRC + $ echo "log=log -g" >> $HGRC customized hgrc @@ -158,8 +164,8 @@ > def uisetup(ui): > ui.write('plain: %r\n' % ui.plain()) > EOF - $ echo "[extensions]" >> $HGRCPATH - $ echo "plain=./plain.py" >> $HGRCPATH + $ echo "[extensions]" >> $HGRC + $ echo "plain=./plain.py" >> $HGRC $ HGPLAINEXCEPT=; export HGPLAINEXCEPT $ hg showconfig --config ui.traceback=True --debug plain: True
--- a/tests/test-hgweb-commands.t Wed Oct 26 22:35:15 2011 +0200 +++ b/tests/test-hgweb-commands.t Thu Oct 27 18:35:07 2011 -0500 @@ -246,17 +246,17 @@ <th class="description">description</th> </tr> <tr class="parity0"> - <td class="age">Thu Jan 01 00:00:00 1970 +0000</td> + <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td> <td class="author">test</td> <td class="description"><a href="/rev/1d22e65f027e">branch</a><span class="branchhead">stable</span> <span class="tag">tip</span> <span class="tag">something</span> </td> </tr> <tr class="parity1"> - <td class="age">Thu Jan 01 00:00:00 1970 +0000</td> + <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td> <td class="author">test</td> <td class="description"><a href="/rev/a4f92ed23982">Added tag 1.0 for changeset 2ef0ac749a14</a><span class="branchhead">default</span> </td> </tr> <tr class="parity0"> - <td class="age">Thu Jan 01 00:00:00 1970 +0000</td> + <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td> <td class="author">test</td> <td class="description"><a href="/rev/2ef0ac749a14">base</a><span class="tag">1.0</span> <span class="tag">anotherthing</span> </td> </tr> @@ -339,7 +339,7 @@ </tr> <tr> <th class="date">date</th> - <td class="date age">Thu Jan 01 00:00:00 1970 +0000</td></tr> + <td class="date age">Thu, 01 Jan 1970 00:00:00 +0000</td></tr> <tr> <th class="author">parents</th> <td class="author"></td> @@ -476,7 +476,7 @@ <th class="description">description</th> </tr> <tr class="parity0"> - <td class="age">Thu Jan 01 00:00:00 1970 +0000</td> + <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td> <td class="author">test</td> <td class="description"><a href="/rev/2ef0ac749a14">base</a><span class="tag">1.0</span> <span class="tag">anotherthing</span> </td> </tr> @@ -586,7 +586,7 @@ </tr> <tr> <th class="date">date</th> - <td class="date age">Thu Jan 01 00:00:00 1970 +0000</td> + <td class="date age">Thu, 01 Jan 1970 00:00:00 +0000</td> </tr> <tr> <th class="author">parents</th> @@ -701,7 +701,7 @@ <table cellspacing="0"> <tr class="parity0"> - <td class="age"><i class="age">Thu Jan 01 00:00:00 1970 +0000</i></td> + <td class="age"><i class="age">Thu, 01 Jan 1970 00:00:00 +0000</i></td> <td><i>test</i></td> <td> <a class="list" href="/rev/1d22e65f027e?style=gitweb"> @@ -715,7 +715,7 @@ </td> </tr> <tr class="parity1"> - <td class="age"><i class="age">Thu Jan 01 00:00:00 1970 +0000</i></td> + <td class="age"><i class="age">Thu, 01 Jan 1970 00:00:00 +0000</i></td> <td><i>test</i></td> <td> <a class="list" href="/rev/a4f92ed23982?style=gitweb"> @@ -729,7 +729,7 @@ </td> </tr> <tr class="parity0"> - <td class="age"><i class="age">Thu Jan 01 00:00:00 1970 +0000</i></td> + <td class="age"><i class="age">Thu, 01 Jan 1970 00:00:00 +0000</i></td> <td><i>test</i></td> <td> <a class="list" href="/rev/2ef0ac749a14?style=gitweb"> @@ -749,7 +749,7 @@ <table cellspacing="0"> <tr class="parity0"> - <td class="age"><i class="age">Thu Jan 01 00:00:00 1970 +0000</i></td> + <td class="age"><i class="age">Thu, 01 Jan 1970 00:00:00 +0000</i></td> <td><a class="list" href="/rev/2ef0ac749a14?style=gitweb"><b>1.0</b></a></td> <td class="link"> <a href="/rev/2ef0ac749a14?style=gitweb">changeset</a> | @@ -764,7 +764,7 @@ <table cellspacing="0"> <tr class="parity0"> - <td class="age"><i class="age">Thu Jan 01 00:00:00 1970 +0000</i></td> + <td class="age"><i class="age">Thu, 01 Jan 1970 00:00:00 +0000</i></td> <td><a class="list" href="/rev/2ef0ac749a14?style=gitweb"><b>anotherthing</b></a></td> <td class="link"> <a href="/rev/2ef0ac749a14?style=gitweb">changeset</a> | @@ -773,7 +773,7 @@ </td> </tr> <tr class="parity1"> - <td class="age"><i class="age">Thu Jan 01 00:00:00 1970 +0000</i></td> + <td class="age"><i class="age">Thu, 01 Jan 1970 00:00:00 +0000</i></td> <td><a class="list" href="/rev/1d22e65f027e?style=gitweb"><b>something</b></a></td> <td class="link"> <a href="/rev/1d22e65f027e?style=gitweb">changeset</a> | @@ -788,7 +788,7 @@ <table cellspacing="0"> <tr class="parity0"> - <td class="age"><i class="age">Thu Jan 01 00:00:00 1970 +0000</i></td> + <td class="age"><i class="age">Thu, 01 Jan 1970 00:00:00 +0000</i></td> <td><a class="list" href="/shortlog/1d22e65f027e?style=gitweb"><b>1d22e65f027e</b></a></td> <td class="">stable</td> <td class="link"> @@ -798,7 +798,7 @@ </td> </tr> <tr class="parity1"> - <td class="age"><i class="age">Thu Jan 01 00:00:00 1970 +0000</i></td> + <td class="age"><i class="age">Thu, 01 Jan 1970 00:00:00 +0000</i></td> <td><a class="list" href="/shortlog/a4f92ed23982?style=gitweb"><b>a4f92ed23982</b></a></td> <td class="">default</td> <td class="link">
--- a/tests/test-hgweb-diffs.t Wed Oct 26 22:35:15 2011 +0200 +++ b/tests/test-hgweb-diffs.t Thu Oct 27 18:35:07 2011 -0500 @@ -81,7 +81,7 @@ </tr> <tr> <th class="date">date</th> - <td class="date age">Thu Jan 01 00:00:00 1970 +0000</td></tr> + <td class="date age">Thu, 01 Jan 1970 00:00:00 +0000</td></tr> <tr> <th class="author">parents</th> <td class="author"></td> @@ -240,7 +240,7 @@ </tr> <tr> <th>date</th> - <td class="date age">Thu Jan 01 00:00:00 1970 +0000</td> + <td class="date age">Thu, 01 Jan 1970 00:00:00 +0000</td> </tr> <tr> <th>parents</th> @@ -341,7 +341,7 @@ </tr> <tr> <th class="date">date</th> - <td class="date age">Thu Jan 01 00:00:00 1970 +0000</td></tr> + <td class="date age">Thu, 01 Jan 1970 00:00:00 +0000</td></tr> <tr> <th class="author">parents</th> <td class="author"></td> @@ -504,7 +504,7 @@ </tr> <tr> <th>date</th> - <td class="date age">Thu Jan 01 00:00:00 1970 +0000</td> + <td class="date age">Thu, 01 Jan 1970 00:00:00 +0000</td> </tr> <tr> <th>parents</th>
--- a/tests/test-hgweb-filelog.t Wed Oct 26 22:35:15 2011 +0200 +++ b/tests/test-hgweb-filelog.t Thu Oct 27 18:35:07 2011 -0500 @@ -179,12 +179,12 @@ <th class="description">description</th> </tr> <tr class="parity0"> - <td class="age">Thu Jan 01 00:00:00 1970 +0000</td> + <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td> <td class="author">test</td> <td class="description"><a href="/rev/01de2d66a28d">second a</a></td> </tr> <tr class="parity1"> - <td class="age">Thu Jan 01 00:00:00 1970 +0000</td> + <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td> <td class="author">test</td> <td class="description"><a href="/rev/5ed941583260">first a</a></td> </tr> @@ -280,12 +280,12 @@ <th class="description">description</th> </tr> <tr class="parity0"> - <td class="age">Thu Jan 01 00:00:00 1970 +0000</td> + <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td> <td class="author">test</td> <td class="description"><a href="/rev/01de2d66a28d">second a</a></td> </tr> <tr class="parity1"> - <td class="age">Thu Jan 01 00:00:00 1970 +0000</td> + <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td> <td class="author">test</td> <td class="description"><a href="/rev/5ed941583260">first a</a></td> </tr> @@ -381,7 +381,7 @@ <th class="description">description</th> </tr> <tr class="parity0"> - <td class="age">Thu Jan 01 00:00:00 1970 +0000</td> + <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td> <td class="author">test</td> <td class="description"><a href="/rev/5ed941583260">first a</a></td> </tr> @@ -477,7 +477,7 @@ <th class="description">description</th> </tr> <tr class="parity0"> - <td class="age">Thu Jan 01 00:00:00 1970 +0000</td> + <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td> <td class="author">test</td> <td class="description"><a href="/rev/5ed941583260">first a</a></td> </tr> @@ -604,7 +604,7 @@ <table class="logEntry parity0"> <tr> - <th><span class="age">Thu Jan 01 00:00:00 1970 +0000</span>:</th> + <th><span class="age">Thu, 01 Jan 1970 00:00:00 +0000</span>:</th> <th class="firstline"><a href="/rev/b7682196df1c?style=spartan">change c</a></th> </tr> <tr> @@ -622,14 +622,14 @@ </tr> <tr> <th class="date">date:</th> - <td class="date">Thu Jan 01 00:00:00 1970 +0000</td> + <td class="date">Thu, 01 Jan 1970 00:00:00 +0000</td> </tr> </table> <table class="logEntry parity1"> <tr> - <th><span class="age">Thu Jan 01 00:00:00 1970 +0000</span>:</th> + <th><span class="age">Thu, 01 Jan 1970 00:00:00 +0000</span>:</th> <th class="firstline"><a href="/rev/1a6696706df2?style=spartan">mv b</a></th> </tr> <tr> @@ -655,7 +655,7 @@ </tr> <tr> <th class="date">date:</th> - <td class="date">Thu Jan 01 00:00:00 1970 +0000</td> + <td class="date">Thu, 01 Jan 1970 00:00:00 +0000</td> </tr> </table>
--- a/tests/test-hgweb-removed.t Wed Oct 26 22:35:15 2011 +0200 +++ b/tests/test-hgweb-removed.t Thu Oct 27 18:35:07 2011 -0500 @@ -76,7 +76,7 @@ </tr> <tr> <th class="date">date</th> - <td class="date age">Thu Jan 01 00:00:00 1970 +0000</td></tr> + <td class="date age">Thu, 01 Jan 1970 00:00:00 +0000</td></tr> <tr> <th class="author">parents</th> <td class="author"><a href="/rev/cb9a9f314b8b">cb9a9f314b8b</a> </td> @@ -198,7 +198,7 @@ </tr> <tr> <th>date</th> - <td class="date age">Thu Jan 01 00:00:00 1970 +0000</td> + <td class="date age">Thu, 01 Jan 1970 00:00:00 +0000</td> </tr> <tr> <th>parents</th>
--- a/tests/test-hgwebdir-paths.py Wed Oct 26 22:35:15 2011 +0200 +++ b/tests/test-hgwebdir-paths.py Thu Oct 27 18:35:07 2011 -0500 @@ -1,11 +1,11 @@ import os -from mercurial import hg, ui +from mercurial import hg, ui, util from mercurial.hgweb.hgwebdir_mod import hgwebdir os.mkdir('webdir') os.chdir('webdir') -webdir = os.path.realpath('.') +webdir = util.realpath('.') u = ui.ui() hg.repository(u, 'a', create=1)
--- a/tests/test-highlight.t Wed Oct 26 22:35:15 2011 +0200 +++ b/tests/test-highlight.t Thu Oct 27 18:35:07 2011 -0500 @@ -121,7 +121,7 @@ </tr> <tr> <th class="date">date</th> - <td class="date age">Thu Jan 01 00:00:00 1970 +0000</td> + <td class="date age">Thu, 01 Jan 1970 00:00:00 +0000</td> </tr> <tr> <th class="author">parents</th> @@ -251,7 +251,7 @@ </tr> <tr> <th class="date">date</th> - <td class="date age">Thu Jan 01 00:00:00 1970 +0000</td> + <td class="date age">Thu, 01 Jan 1970 00:00:00 +0000</td> </tr> <tr> <th class="author">parents</th>
--- a/tests/test-import.t Wed Oct 26 22:35:15 2011 +0200 +++ b/tests/test-import.t Thu Oct 27 18:35:07 2011 -0500 @@ -10,6 +10,11 @@ $ echo line 2 >> a/a $ hg --cwd a ci -u someone -d '1 0' -m'second change' +import with no args: + + $ hg --cwd a import + abort: need at least one patch to import + [255] generate patches for the test
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-issue1802.t Thu Oct 27 18:35:07 2011 -0500 @@ -0,0 +1,69 @@ +Create extension that can disable exec checks: + + $ cat > noexec.py <<EOF + > from mercurial import extensions, util + > def setflags(orig, f, l, x): + > pass + > def checkexec(orig, path): + > return False + > def extsetup(ui): + > extensions.wrapfunction(util, 'setflags', setflags) + > extensions.wrapfunction(util, 'checkexec', checkexec) + > EOF + + $ hg init unix-repo + $ cd unix-repo + $ touch a + $ hg add a + $ hg commit -m 'unix: add a' + $ hg clone . ../win-repo + updating to branch default + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ chmod +x a + $ hg commit -m 'unix: chmod a' + $ hg manifest -v + 755 * a + + $ cd ../win-repo + + $ touch b + $ hg add b + $ hg commit -m 'win: add b' + + $ hg manifest -v + 644 a + 644 b + + $ hg pull + pulling from $TESTTMP/unix-repo + searching for changes + adding changesets + adding manifests + adding file changes + added 1 changesets with 0 changes to 0 files (+1 heads) + (run 'hg heads' to see heads, 'hg merge' to merge) + + $ hg manifest -v -r tip + 755 * a + +Simulate a Windows merge: + + $ hg --config extensions.n=$TESTTMP/noexec.py merge --debug + searching for copies back to rev 1 + unmatched files in local: + b + resolving manifests + overwrite None partial False + ancestor a03b0deabf2b local d6fa54f68ae1+ remote 2d8bcf2dda39 + a: update permissions -> e + updating: a 1/1 files (100.00%) + 0 files updated, 0 files merged, 0 files removed, 0 files unresolved + (branch merge, don't forget to commit) + +Simulate a Windows commit: + + $ hg --config extensions.n=$TESTTMP/noexec.py commit -m 'win: merge' + + $ hg manifest -v + 755 * a + 644 b
--- a/tests/test-largefiles.t Wed Oct 26 22:35:15 2011 +0200 +++ b/tests/test-largefiles.t Thu Oct 27 18:35:07 2011 -0500 @@ -4,12 +4,12 @@ > purge= > rebase= > [largefiles] - > size=2 + > minsize=2 > patterns=glob:**.dat > EOF Create the repo with a couple of revisions of both large and normal -files (testing that status correctly shows largefiles. +files, testing that status correctly shows largefiles. $ hg init a $ cd a @@ -32,9 +32,7 @@ M sub/normal2 $ hg commit -m "edit files" -Verify that committing new versions of largefiles results in correct -largefile contents, and also that non-largefiles are not affected -badly. +Commit preserved largefile contents. $ cat normal1 normal11 @@ -45,14 +43,14 @@ $ cat sub/large2 large22 -Verify removing largefiles and normal files works on largefile repos. +Remove both largefiles and normal files. $ hg remove normal1 large1 $ hg commit -m "remove files" $ ls sub -Test copying largefiles. +Copy both largefiles and normal files. $ hg cp sub/normal2 normal1 $ hg cp sub/large2 large1 @@ -130,8 +128,7 @@ $ cat sub/large4 large22 -Test a separate commit corner case (specifying files to commit) and check -that the commited files have the right value. +Commit corner case: specify files to commit. $ cd ../a $ echo normal3 > normal3 @@ -148,8 +145,7 @@ $ cat sub/large4 large4 -Test one more commit corner case that has been known to break (comitting from -a sub-directory of the repo). +One more commit corner case: commit from a subdirectory. $ cd ../a $ echo normal33 > normal3 @@ -167,7 +163,7 @@ $ cat large4 large44 -Check that committing standins is not allowed. +Committing standins is not allowed. $ cd .. $ echo large3 > large3 @@ -176,7 +172,7 @@ (commit the largefile itself instead) [255] -Test some cornercases for adding largefiles. +Corner cases for adding largefiles. $ echo large5 > large5 $ hg add --large large5 @@ -194,41 +190,56 @@ A sub2/large6 A sub2/large7 -Test that files get added as largefiles based on .hgrc settings +Config settings (pattern **.dat, minsize 2 MB) are respected. $ echo testdata > test.dat - $ dd bs=3145728 count=1 if=/dev/zero of=reallylarge > /dev/null 2> /dev/null + $ dd bs=1k count=2k if=/dev/zero of=reallylarge > /dev/null 2> /dev/null $ hg add adding reallylarge as a largefile adding test.dat as a largefile - $ dd bs=1048576 count=1 if=/dev/zero of=reallylarge2 > /dev/null 2> /dev/null + +Test that minsize and --lfsize handle float values; +also tests that --lfsize overrides largefiles.minsize. +(0.250 MB = 256 kB = 262144 B) -Test that specifying the --lsize command on the comand-line works - - $ hg add --lfsize 1 - adding reallylarge2 as a largefile + $ dd if=/dev/zero of=ratherlarge bs=1024 count=256 > /dev/null 2> /dev/null + $ dd if=/dev/zero of=medium bs=1024 count=128 > /dev/null 2> /dev/null + $ hg --config largefiles.minsize=.25 add + adding ratherlarge as a largefile + adding medium + $ hg forget medium + $ hg --config largefiles.minsize=.25 add --lfsize=.125 + adding medium as a largefile + $ dd if=/dev/zero of=notlarge bs=1024 count=127 > /dev/null 2> /dev/null + $ hg --config largefiles.minsize=.25 add --lfsize=.125 + adding notlarge + $ hg forget notlarge Test forget on largefiles. - $ hg forget large3 large5 test.dat reallylarge reallylarge2 + $ hg forget large3 large5 test.dat reallylarge ratherlarge medium $ hg st A sub2/large6 A sub2/large7 R large3 ? large5 + ? medium + ? notlarge + ? ratherlarge ? reallylarge - ? reallylarge2 ? test.dat $ hg commit -m "add/edit more largefiles" $ hg st ? large3 ? large5 + ? medium + ? notlarge + ? ratherlarge ? reallylarge - ? reallylarge2 ? test.dat -Test purge with largefiles (verify that largefiles get populated in the -working copy correctly after a purge) +Purge with largefiles: verify that largefiles are still in the working +dir after a purge. $ hg purge --all $ cat sub/large4 @@ -238,7 +249,7 @@ $ cat sub2/large7 large7 -Test cloning a largefiles repo. +Clone a largefiles repo. $ cd .. $ hg clone a b @@ -341,8 +352,8 @@ $ cat sub/large2 large22 -Test that old revisions of a clone have correct largefiles content. This also -tsts update. +Old revisions of a clone have correct largefiles content (this also +tests update). $ hg update -r 1 2 files updated, 0 files merged, 0 files removed, 0 files unresolved @@ -353,7 +364,7 @@ $ cat sub/large2 large22 -Test that rebasing between two repositories does not revert largefiles to old +Rebasing between two repositories does not revert largefiles to old revisions (this was a very bad bug that took a lot of work to fix). $ cd .. @@ -370,6 +381,13 @@ $ echo large6-modified > sub2/large6 $ echo normal4-modified > sub/normal4 $ hg commit -m "modify normal file largefile in repo d" + $ cd .. + $ hg clone d e + updating to branch default + 5 files updated, 0 files merged, 0 files removed, 0 files unresolved + getting changed largefiles + 3 largefiles updated, 0 removed + $ cd d $ hg pull --rebase ../b pulling from ../b searching for changes @@ -443,3 +461,417 @@ large6-modified $ cat sub2/large7 large7 + $ cd ../e + $ hg pull ../b + pulling from ../b + searching for changes + adding changesets + adding manifests + adding file changes + added 1 changesets with 2 changes to 2 files (+1 heads) + (run 'hg heads' to see heads, 'hg merge' to merge) + $ hg rebase + getting changed largefiles + 1 largefiles updated, 0 removed + saved backup bundle to $TESTTMP/e/.hg/strip-backup/f574fb32bb45-backup.hg + $ hg log + changeset: 9:598410d3eb9a + tag: tip + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: modify normal file largefile in repo d + + changeset: 8:a381d2c8c80e + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: modify normal file and largefile in repo b + + changeset: 7:daea875e9014 + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: add/edit more largefiles + + changeset: 6:4355d653f84f + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: edit files yet again + + changeset: 5:9d5af5072dbd + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: edit files again + + changeset: 4:74c02385b94c + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: move files + + changeset: 3:9e8fbc4bce62 + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: copy files + + changeset: 2:51a0ae4d5864 + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: remove files + + changeset: 1:ce8896473775 + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: edit files + + changeset: 0:30d30fe6a5be + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: add files + + $ cat normal3 + normal3-modified + $ cat sub/normal4 + normal4-modified + $ cat sub/large4 + large4-modified + $ cat sub2/large6 + large6-modified + $ cat sub2/large7 + large7 + +Rollback on largefiles. + + $ echo large4-modified-again > sub/large4 + $ hg commit -m "Modify large4 again" + $ hg rollback + repository tip rolled back to revision 9 (undo commit) + working directory now based on revision 9 + $ hg st + M sub/large4 + $ hg log + changeset: 9:598410d3eb9a + tag: tip + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: modify normal file largefile in repo d + + changeset: 8:a381d2c8c80e + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: modify normal file and largefile in repo b + + changeset: 7:daea875e9014 + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: add/edit more largefiles + + changeset: 6:4355d653f84f + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: edit files yet again + + changeset: 5:9d5af5072dbd + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: edit files again + + changeset: 4:74c02385b94c + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: move files + + changeset: 3:9e8fbc4bce62 + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: copy files + + changeset: 2:51a0ae4d5864 + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: remove files + + changeset: 1:ce8896473775 + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: edit files + + changeset: 0:30d30fe6a5be + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: add files + + $ cat sub/large4 + large4-modified-again + +"update --check" refuses to update with uncommitted changes. + $ hg update --check 8 + abort: uncommitted local changes + [255] + +"update --clean" leaves correct largefiles in working copy. + + $ hg update --clean + 0 files updated, 0 files merged, 0 files removed, 0 files unresolved + getting changed largefiles + 1 largefiles updated, 0 removed + $ cat normal3 + normal3-modified + $ cat sub/normal4 + normal4-modified + $ cat sub/large4 + large4-modified + $ cat sub2/large6 + large6-modified + $ cat sub2/large7 + large7 + +Now "update check" is happy. + $ hg update --check 8 + 2 files updated, 0 files merged, 0 files removed, 0 files unresolved + getting changed largefiles + 1 largefiles updated, 0 removed + $ hg update --check + 2 files updated, 0 files merged, 0 files removed, 0 files unresolved + getting changed largefiles + 1 largefiles updated, 0 removed + +"revert" works on largefiles (and normal files too). + $ echo hack3 >> normal3 + $ echo hack4 >> sub/normal4 + $ echo hack4 >> sub/large4 + $ hg rm sub2/large6 + $ echo new >> sub2/large8 + $ hg add --large sub2/large8 +# XXX we don't really want to report that we're reverting the standin; +# that's just an implementation detail. But I don't see an obvious fix. ;-( + $ hg revert sub + reverting .hglf/sub/large4 + reverting sub/normal4 + $ hg status + M normal3 + A sub2/large8 + R sub2/large6 + ? sub/large4.orig + ? sub/normal4.orig + $ cat sub/normal4 + normal4-modified + $ cat sub/large4 + large4-modified + $ hg revert -a --no-backup + undeleting .hglf/sub2/large6 + forgetting .hglf/sub2/large8 + reverting normal3 + $ hg status + ? sub/large4.orig + ? sub/normal4.orig + ? sub2/large8 + $ cat normal3 + normal3-modified + $ cat sub2/large6 + large6-modified + $ rm sub/*.orig sub2/large8 + +revert some files to an older revision + $ hg revert --no-backup -r 8 sub2 + reverting .hglf/sub2/large6 + $ cat sub2/large6 + large6 + $ hg revert --no-backup sub2 + reverting .hglf/sub2/large6 + $ hg status + +"verify --large" actually verifies largefiles + + $ hg verify --large + checking changesets + checking manifests + crosschecking files in changesets and manifests + checking files + 10 files, 10 changesets, 28 total revisions + searching 1 changesets for largefiles + verified existence of 3 revisions of 3 largefiles + +Merging does not revert to old versions of largefiles (this has also +been very problematic). + + $ cd .. + $ hg clone -r 7 e f + adding changesets + adding manifests + adding file changes + added 8 changesets with 24 changes to 10 files + updating to branch default + 5 files updated, 0 files merged, 0 files removed, 0 files unresolved + getting changed largefiles + 3 largefiles updated, 0 removed + $ cd f + $ echo "large4-merge-test" > sub/large4 + $ hg commit -m "Modify large4 to test merge" + $ hg pull ../e + pulling from ../e + searching for changes + adding changesets + adding manifests + adding file changes + added 2 changesets with 4 changes to 4 files (+1 heads) + (run 'hg heads' to see heads, 'hg merge' to merge) + $ hg merge + merging sub/large4 + largefile sub/large4 has a merge conflict + keep (l)ocal or take (o)ther? l + 3 files updated, 1 files merged, 0 files removed, 0 files unresolved + (branch merge, don't forget to commit) + getting changed largefiles + 1 largefiles updated, 0 removed + $ hg commit -m "Merge repos e and f" + $ cat normal3 + normal3-modified + $ cat sub/normal4 + normal4-modified + $ cat sub/large4 + large4-merge-test + $ cat sub2/large6 + large6-modified + $ cat sub2/large7 + large7 + $ cd .. + +vanilla clients not locked out from largefiles servers on vanilla repos + $ mkdir r1 + $ cd r1 + $ hg init + $ echo c1 > f1 + $ hg add f1 + $ hg com -m "m1" + $ cd .. + $ hg serve -R r1 -d -p 8001 --pid-file serve.pid + $ hg --config extensions.largefiles=! clone http://localhost:8001 r2 + requesting all changes + adding changesets + adding manifests + adding file changes + added 1 changesets with 1 changes to 1 files + updating to branch default + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ kill `cat serve.pid` + +largefiles clients still work with vanilla servers + $ hg --config extensions.largefiles=! serve -R r1 -d -p 8001 --pid-file serve.pid + $ hg clone http://localhost:8001 r3 + requesting all changes + adding changesets + adding manifests + adding file changes + added 1 changesets with 1 changes to 1 files + updating to branch default + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ kill `cat serve.pid` + +vanilla clients locked out from largefiles http repos + $ mkdir r4 + $ cd r4 + $ hg init + $ echo c1 > f1 + $ hg add --large f1 + $ hg com -m "m1" + $ cd .. + $ hg serve -R r4 -d -p 8001 --pid-file serve.pid + $ hg --config extensions.largefiles=! clone http://localhost:8001 r5 + abort: remote error: + + This repository uses the largefiles extension. + + Please enable it in your Mercurial config file. + [255] + $ kill `cat serve.pid` + +vanilla clients locked out from largefiles ssh repos + $ hg --config extensions.largefiles=! clone -e "python $TESTDIR/dummyssh" ssh://user@dummy/r4 r5 + abort: remote error: + + This repository uses the largefiles extension. + + Please enable it in your Mercurial config file. + [255] + +largefiles clients refuse to push largefiles repos to vanilla servers + $ mkdir r6 + $ cd r6 + $ hg init + $ echo c1 > f1 + $ hg add f1 + $ hg com -m "m1" + $ cat >> .hg/hgrc <<! + > [web] + > push_ssl = false + > allow_push = * + > ! + $ cd .. + $ hg clone r6 r7 + updating to branch default + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ cd r7 + $ echo c2 > f2 + $ hg add --large f2 + $ hg com -m "m2" + $ hg --config extensions.largefiles=! -R ../r6 serve -d -p 8001 --pid-file ../serve.pid + $ hg push http://localhost:8001 + pushing to http://localhost:8001/ + searching for changes + abort: http://localhost:8001/ does not appear to be a largefile store + [255] + $ cd .. + $ kill `cat serve.pid` + + $ cd .. + +Clone a local repository owned by another user +We have to simulate that here by setting $HOME and removing write permissions + $ ORIGHOME="$HOME" + $ mkdir alice + $ HOME="`pwd`/alice" + $ cd alice + $ hg init pubrepo + $ cd pubrepo + $ dd if=/dev/urandom bs=1k count=11k > a-large-file 2> /dev/null + $ hg add --large a-large-file + $ hg commit -m "Add a large file" + $ cd .. + $ chmod -R a-w pubrepo + $ cd .. + $ mkdir bob + $ HOME="`pwd`/bob" + $ cd bob + $ hg clone --pull ../alice/pubrepo pubrepo + requesting all changes + adding changesets + adding manifests + adding file changes + added 1 changesets with 1 changes to 1 files + updating to branch default + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + getting changed largefiles + 1 largefiles updated, 0 removed + $ cd .. + $ HOME="$ORIGHOME" + +Symlink to a large largefile should behave the same as a symlink to a normal file + $ hg init largesymlink + $ cd largesymlink + $ dd if=/dev/zero bs=1k count=10k of=largefile 2>/dev/null + $ hg add --large largefile + $ hg commit -m "commit a large file" + $ ln -s largefile largelink + $ hg add largelink + $ hg commit -m "commit a large symlink" + $ rm -f largelink + $ hg up >/dev/null + $ test -f largelink + [1] + $ test -L largelink + [1] + $ rm -f largelink # make next part of the test independent of the previous + $ hg up -C >/dev/null + $ test -f largelink + $ test -L largelink + $ cd .. + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-lfconvert.t Thu Oct 27 18:35:07 2011 -0500 @@ -0,0 +1,232 @@ + $ cat >> $HGRCPATH <<EOF + > [extensions] + > largefiles = + > share = + > graphlog = + > [largefiles] + > minsize = 0.5 + > patterns = **.dat + > EOF + +"lfconvert" works + $ hg init bigfile-repo + $ cd bigfile-repo + $ cat >> .hg/hgrc <<EOF + > [extensions] + > largefiles = ! + > EOF + $ mkdir sub + $ dd if=/dev/zero bs=1k count=256 > large 2> /dev/null + $ echo normal > normal1 + $ echo alsonormal > sub/normal2 + $ dd if=/dev/zero bs=1k count=10 > sub/maybelarge.dat 2> /dev/null + $ hg addremove + adding large + adding normal1 + adding sub/maybelarge.dat + adding sub/normal2 + $ hg commit -m"add large, normal1" large normal1 + $ hg commit -m"add sub/*" sub + $ [ -d .hg/largefiles ] && echo fail || echo pass + pass + $ cd .. + $ hg lfconvert --size 0.2 bigfile-repo largefiles-repo + initializing destination largefiles-repo + +"lfconvert" converts content correctly + $ cd largefiles-repo + $ hg up + 4 files updated, 0 files merged, 0 files removed, 0 files unresolved + getting changed largefiles + 2 largefiles updated, 0 removed + $ hg locate + .hglf/large + .hglf/sub/maybelarge.dat + normal1 + sub/normal2 + $ cat normal1 + normal + $ cat sub/normal2 + alsonormal + $ sha1sum large sub/maybelarge.dat + 2e000fa7e85759c7f4c254d4d9c33ef481e459a7 large + 34e163be8e43c5631d8b92e9c43ab0bf0fa62b9c sub/maybelarge.dat + +"lfconvert" adds 'largefiles' to .hg/requires. + $ cat .hg/requires + largefiles + revlogv1 + fncache + store + dotencode + +"lfconvert" includes a newline at the end of the standin files. + $ cat .hglf/large .hglf/sub/maybelarge.dat + 2e000fa7e85759c7f4c254d4d9c33ef481e459a7 + 34e163be8e43c5631d8b92e9c43ab0bf0fa62b9c + $ cd .. + +add some changesets to rename/remove/merge + $ cd bigfile-repo + $ hg mv -q sub stuff + $ hg commit -m"rename sub/ to stuff/" + $ hg update -q 1 + $ echo blah >> normal3 + $ echo blah >> sub/normal2 + $ echo blah >> sub/maybelarge.dat + $ sha1sum sub/maybelarge.dat + 76236b6a2c6102826c61af4297dd738fb3b1de38 sub/maybelarge.dat + $ hg commit -A -m"add normal3, modify sub/*" + adding normal3 + created new head + $ hg rm large normal3 + $ hg commit -q -m"remove large, normal3" + $ hg merge + merging sub/maybelarge.dat and stuff/maybelarge.dat to stuff/maybelarge.dat + warning: $TESTTMP/bigfile-repo/stuff/maybelarge.dat looks like a binary file. + merging stuff/maybelarge.dat failed! + merging sub/normal2 and stuff/normal2 to stuff/normal2 + 0 files updated, 1 files merged, 0 files removed, 1 files unresolved + use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon + [1] + $ hg cat -r . sub/maybelarge.dat > stuff/maybelarge.dat + $ hg resolve -m stuff/maybelarge.dat + $ hg commit -m"merge" + $ hg glog --template "{rev}:{node|short} {desc|firstline}\n" + @ 5:4884f215abda merge + |\ + | o 4:7285f817b77e remove large, normal3 + | | + | o 3:67e3892e3534 add normal3, modify sub/* + | | + o | 2:c96c8beb5d56 rename sub/ to stuff/ + |/ + o 1:020c65d24e11 add sub/* + | + o 0:117b8328f97a add large, normal1 + + $ cd .. + +lfconvert with rename, merge, and remove + $ rm -rf largefiles-repo + $ hg lfconvert --size 0.2 bigfile-repo largefiles-repo + initializing destination largefiles-repo + $ cd largefiles-repo + $ hg glog --template "{rev}:{node|short} {desc|firstline}\n" + o 5:8e05f5f2b77e merge + |\ + | o 4:a5a02de7a8e4 remove large, normal3 + | | + | o 3:55759520c76f add normal3, modify sub/* + | | + o | 2:261ad3f3f037 rename sub/ to stuff/ + |/ + o 1:334e5237836d add sub/* + | + o 0:d4892ec57ce2 add large, normal1 + + $ hg locate -r 2 + .hglf/large + .hglf/stuff/maybelarge.dat + normal1 + stuff/normal2 + $ hg locate -r 3 + .hglf/large + .hglf/sub/maybelarge.dat + normal1 + normal3 + sub/normal2 + $ hg locate -r 4 + .hglf/sub/maybelarge.dat + normal1 + sub/normal2 + $ hg locate -r 5 + .hglf/stuff/maybelarge.dat + normal1 + stuff/normal2 + $ hg update + 3 files updated, 0 files merged, 0 files removed, 0 files unresolved + getting changed largefiles + 1 largefiles updated, 0 removed + $ cat stuff/normal2 + alsonormal + blah + $ sha1sum stuff/maybelarge.dat + 76236b6a2c6102826c61af4297dd738fb3b1de38 stuff/maybelarge.dat + $ cat .hglf/stuff/maybelarge.dat + 76236b6a2c6102826c61af4297dd738fb3b1de38 + $ cd .. + +"lfconvert" error cases + $ hg lfconvert http://localhost/foo foo + abort: http://localhost/foo is not a local Mercurial repo + [255] + $ hg lfconvert foo ssh://localhost/foo + abort: ssh://localhost/foo is not a local Mercurial repo + [255] + $ hg lfconvert nosuchrepo foo + abort: repository nosuchrepo not found! + [255] + $ hg share -q -U bigfile-repo shared + $ printf 'bogus' > shared/.hg/sharedpath + $ hg lfconvert shared foo + abort: .hg/sharedpath points to nonexistent directory $TESTTMP/bogus! + [255] + $ hg lfconvert bigfile-repo largefiles-repo + initializing destination largefiles-repo + abort: repository largefiles-repo already exists! + [255] + +add another largefile to the new largefiles repo + $ cd largefiles-repo + $ dd if=/dev/zero bs=1k count=1k > anotherlarge 2> /dev/null + $ hg add --lfsize=1 anotherlarge + $ hg commit -m "add anotherlarge (should be a largefile)" + $ cat .hglf/anotherlarge + 3b71f43ff30f4b15b5cd85dd9e95ebc7e84eb5a3 + $ cd .. + +round-trip: converting back to a normal (non-largefiles) repo with +"lfconvert --to-normal" should give the same as ../bigfile-repo + $ cd largefiles-repo + $ hg lfconvert --to-normal . ../normal-repo + initializing destination ../normal-repo + $ cd ../normal-repo + $ cat >> .hg/hgrc <<EOF + > [extensions] + > largefiles = ! + > EOF + +# Hmmm: the changeset ID for rev 5 is different from the original +# normal repo (../bigfile-repo), because the changelog filelist +# differs between the two incarnations of rev 5: this repo includes +# 'large' in the list, but ../bigfile-repo does not. Since rev 5 +# removes 'large' relative to the first parent in both repos, it seems +# to me that lfconvert is doing a *better* job than +# "hg remove" + "hg merge" + "hg commit". +# $ hg -R ../bigfile-repo debugdata -c 5 +# $ hg debugdata -c 5 + $ hg glog --template "{rev}:{node|short} {desc|firstline}\n" + o 6:1635824e6f59 add anotherlarge (should be a largefile) + | + o 5:7215f8deeaaf merge + |\ + | o 4:7285f817b77e remove large, normal3 + | | + | o 3:67e3892e3534 add normal3, modify sub/* + | | + o | 2:c96c8beb5d56 rename sub/ to stuff/ + |/ + o 1:020c65d24e11 add sub/* + | + o 0:117b8328f97a add large, normal1 + + $ hg update + 4 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ hg locate + anotherlarge + normal1 + stuff/maybelarge.dat + stuff/normal2 + $ [ -d .hg/largefiles ] && echo fail || echo pass + pass
--- a/tests/test-mq-qrename.t Wed Oct 26 22:35:15 2011 +0200 +++ b/tests/test-mq-qrename.t Thu Oct 27 18:35:07 2011 -0500 @@ -76,8 +76,8 @@ $ hg qrename patchb patchc $ hg qrename patcha patchb $ hg st --mq - M patchb M series + A patchb A patchc R patcha $ cd .. @@ -94,3 +94,32 @@ nothing changed [1] $ cd .. + +Test renaming to a folded patch (issue3058) + + $ hg init issue3058 + $ cd issue3058 + $ hg init --mq + $ echo a > a + $ hg add a + $ hg qnew adda + $ echo b >> a + $ hg qnew addb + $ hg qpop + popping addb + now at: adda + $ hg ci --mq -m "save mq" + $ hg qfold addb + $ hg qmv addb + $ cat .hg/patches/addb + # HG changeset patch + # Parent 0000000000000000000000000000000000000000 + + diff -r 000000000000 a + --- /dev/null * (glob) + +++ b/a * (glob) + @@ -0,0 +1,2 @@ + +a + +b + $ cd .. +
--- a/tests/test-mq-subrepo-svn.t Wed Oct 26 22:35:15 2011 +0200 +++ b/tests/test-mq-subrepo-svn.t Thu Oct 27 18:35:07 2011 -0500 @@ -1,4 +1,4 @@ - $ "$TESTDIR/hghave" svn || exit 80 + $ "$TESTDIR/hghave" svn13 || exit 80 $ echo "[extensions]" >> $HGRCPATH $ echo "mq=" >> $HGRCPATH
--- a/tests/test-mq-subrepo.t Wed Oct 26 22:35:15 2011 +0200 +++ b/tests/test-mq-subrepo.t Thu Oct 27 18:35:07 2011 -0500 @@ -1,3 +1,5 @@ + $ echo "[ui]" >> $HGRCPATH + $ echo "commitsubrepos = Yes" >> $HGRCPATH $ echo "[extensions]" >> $HGRCPATH $ echo "mq=" >> $HGRCPATH $ echo "record=" >> $HGRCPATH
--- a/tests/test-progress.t Wed Oct 26 22:35:15 2011 +0200 +++ b/tests/test-progress.t Thu Oct 27 18:35:07 2011 -0500 @@ -35,6 +35,7 @@ > } > EOF + $ cp $HGRCPATH $HGRCPATH.orig $ echo "[extensions]" >> $HGRCPATH $ echo "progress=" >> $HGRCPATH $ echo "loop=`pwd`/loop.py" >> $HGRCPATH @@ -162,7 +163,8 @@ > time.time = mocktime(int(os.environ.get('MOCKTIME', '11'))) > EOF - $ echo "[extensions]" > $HGRCPATH + $ cp $HGRCPATH.orig $HGRCPATH + $ echo "[extensions]" >> $HGRCPATH $ echo "mocktime=`pwd`/mocktime.py" >> $HGRCPATH $ echo "progress=" >> $HGRCPATH $ echo "loop=`pwd`/loop.py" >> $HGRCPATH
--- a/tests/test-qrecord.t Wed Oct 26 22:35:15 2011 +0200 +++ b/tests/test-qrecord.t Thu Oct 27 18:35:07 2011 -0500 @@ -64,6 +64,7 @@ -l --logfile FILE read commit message from file -d --date DATE record the specified date as commit date -u --user USER record the specified user as committer + -S --subrepos recurse into subrepositories -w --ignore-all-space ignore white space when comparing lines -b --ignore-space-change ignore changes in the amount of white space -B --ignore-blank-lines ignore changes whose lines are all blank
--- a/tests/test-subrepo-deep-nested-change.t Wed Oct 26 22:35:15 2011 +0200 +++ b/tests/test-subrepo-deep-nested-change.t Thu Oct 27 18:35:07 2011 -0500 @@ -77,7 +77,7 @@ Modifying deeply nested 'sub2' $ echo modified > cloned/sub1/sub2/sub2 - $ hg commit -m "deep nested modif should trigger a commit" -R cloned + $ hg commit --subrepos -m "deep nested modif should trigger a commit" -R cloned committing subrepository sub1 committing subrepository sub1/sub2
--- a/tests/test-subrepo-git.t Wed Oct 26 22:35:15 2011 +0200 +++ b/tests/test-subrepo-git.t Thu Oct 27 18:35:07 2011 -0500 @@ -103,7 +103,7 @@ $ echo ggg >> s/g $ hg status --subrepos M s/g - $ hg commit -m ggg + $ hg commit --subrepos -m ggg committing subrepository s $ hg debugsub path s @@ -125,7 +125,7 @@ $ hg status --subrepos A s/f - $ hg commit -m f + $ hg commit --subrepos -m f committing subrepository s $ hg debugsub path s @@ -164,7 +164,7 @@ g gg ggg - $ hg commit -m 'merge' + $ hg commit --subrepos -m 'merge' committing subrepository s $ hg status --subrepos --rev 1:5 M .hgsubstate @@ -294,7 +294,7 @@ $ echo ffff >> inner/s/f $ hg status --subrepos M inner/s/f - $ hg commit -m nested + $ hg commit --subrepos -m nested committing subrepository inner committing subrepository inner/s @@ -325,7 +325,7 @@ $ hg push -q abort: subrepo s is missing [255] - $ hg commit -qm missing + $ hg commit --subrepos -qm missing abort: subrepo s is missing [255] $ hg update -C
--- a/tests/test-subrepo-recursion.t Wed Oct 26 22:35:15 2011 +0200 +++ b/tests/test-subrepo-recursion.t Thu Oct 27 18:35:07 2011 -0500 @@ -58,7 +58,14 @@ Commits: - $ hg commit -m 0-0-0 + $ hg commit -m fails + abort: uncommitted changes in subrepo foo + (use --subrepos for recursive commit) + [255] + +The --subrepos flag overwrite the config setting: + + $ hg commit -m 0-0-0 --config ui.commitsubrepos=No --subrepos committing subrepository foo committing subrepository foo/bar @@ -177,7 +184,7 @@ Cleanup and final commit: $ rm -r dir - $ hg commit -m 2-3-2 + $ hg commit --subrepos -m 2-3-2 committing subrepository foo committing subrepository foo/bar @@ -304,10 +311,63 @@ archiving (foo/bar) [================================>] 1/1 \r (esc) +Test archiving a revision that references a subrepo that is not yet +cloned: + + $ hg clone -U . ../empty + $ cd ../empty + $ hg archive --subrepos -r tip ../archive.tar.gz 2>&1 | $TESTDIR/filtercr.py + + archiving [ ] 0/3 + archiving [ ] 0/3 + archiving [=============> ] 1/3 + archiving [=============> ] 1/3 + archiving [===========================> ] 2/3 + archiving [===========================> ] 2/3 + archiving [==========================================>] 3/3 + archiving [==========================================>] 3/3 + + archiving (foo) [ ] 0/3 + archiving (foo) [ ] 0/3 + archiving (foo) [===========> ] 1/3 + archiving (foo) [===========> ] 1/3 + archiving (foo) [=======================> ] 2/3 + archiving (foo) [=======================> ] 2/3 + archiving (foo) [====================================>] 3/3 + archiving (foo) [====================================>] 3/3 + + archiving (foo/bar) [ ] 0/1 + archiving (foo/bar) [ ] 0/1 + archiving (foo/bar) [================================>] 1/1 + archiving (foo/bar) [================================>] 1/1 + + cloning subrepo foo from $TESTTMP/repo/foo + cloning subrepo foo/bar from $TESTTMP/repo/foo/bar + +The newly cloned subrepos contain no working copy: + + $ hg -R foo summary + parent: -1:000000000000 (no revision checked out) + branch: default + commit: (clean) + update: 4 new changesets (update) + Disable progress extension and cleanup: $ mv $HGRCPATH.no-progress $HGRCPATH +Test archiving when there is a directory in the way for a subrepo +created by archive: + + $ hg clone -U . ../almost-empty + $ cd ../almost-empty + $ mkdir foo + $ echo f > foo/f + $ hg archive --subrepos -r tip archive + cloning subrepo foo from $TESTTMP/empty/foo + abort: destination '$TESTTMP/almost-empty/foo' is not empty + [255] + Clone and test outgoing: $ cd .. @@ -341,7 +401,7 @@ y2 y3 +y4 - $ hg commit -m 3-4-2 + $ hg commit --subrepos -m 3-4-2 committing subrepository foo $ hg outgoing -S comparing with $TESTTMP/repo
--- a/tests/test-subrepo-svn.t Wed Oct 26 22:35:15 2011 +0200 +++ b/tests/test-subrepo-svn.t Thu Oct 27 18:35:07 2011 -0500 @@ -1,4 +1,4 @@ - $ "$TESTDIR/hghave" svn || exit 80 + $ "$TESTDIR/hghave" svn15 || exit 80 $ fix_path() > { @@ -105,7 +105,7 @@ branch: default commit: 1 modified, 1 subrepos update: (current) - $ hg commit -m 'Message!' + $ hg commit --subrepos -m 'Message!' committing subrepository s Sending*s/alpha (glob) Transmitting file data . @@ -171,7 +171,7 @@ this commit from hg will fail $ echo zzz >> s/alpha - $ hg ci -m 'amend alpha from hg' + $ hg ci --subrepos -m 'amend alpha from hg' committing subrepository s abort: svn: Commit failed (details follow): svn: (Out of date)?.*/src/alpha.*(is out of date)? (re) @@ -182,7 +182,7 @@ $ svn propset svn:mime-type 'text/html' s/alpha property 'svn:mime-type' set on 's/alpha' - $ hg ci -m 'amend alpha from hg' + $ hg ci --subrepos -m 'amend alpha from hg' committing subrepository s abort: svn: Commit failed (details follow): svn: (Out of date)?.*/src/alpha.*(is out of date)? (re) @@ -192,7 +192,7 @@ this commit fails because of externals changes $ echo zzz > s/externals/other - $ hg ci -m 'amend externals from hg' + $ hg ci --subrepos -m 'amend externals from hg' committing subrepository s abort: cannot commit svn externals [255] @@ -214,7 +214,7 @@ $ svn propset svn:mime-type 'text/html' s/externals/other property 'svn:mime-type' set on 's/externals/other' - $ hg ci -m 'amend externals from hg' + $ hg ci --subrepos -m 'amend externals from hg' committing subrepository s abort: cannot commit svn externals [255] @@ -496,7 +496,7 @@ 0 files updated, 0 files merged, 0 files removed, 0 files unresolved $ echo "obstruct = [svn] $SVNREPO/externals" >> .hgsub $ svn co -r5 --quiet "$SVNREPO"/externals obstruct - $ hg commit -m 'Start making obstructed wc' + $ hg commit -m 'Start making obstructed working copy' committing subrepository obstruct $ hg book other $ hg co -r 'p1(tip)' @@ -523,7 +523,7 @@ Point to a Subversion branch which has since been deleted and recreated First, create that condition in the repository. - $ hg ci -m cleanup + $ hg ci --subrepos -m cleanup committing subrepository obstruct Sending obstruct/other Transmitting file data .
--- a/tests/test-subrepo.t Wed Oct 26 22:35:15 2011 +0200 +++ b/tests/test-subrepo.t Thu Oct 27 18:35:07 2011 -0500 @@ -1,3 +1,8 @@ +Let commit recurse into subrepos by default to match pre-2.0 behavior: + + $ echo "[ui]" >> $HGRCPATH + $ echo "commitsubrepos = Yes" >> $HGRCPATH + $ rm -rf sub $ mkdir sub $ cd sub @@ -107,6 +112,7 @@ $ echo c > s/a $ hg --config ui.commitsubrepos=no ci -m4 abort: uncommitted changes in subrepo s + (use --subrepos for recursive commit) [255] $ hg ci -m4 committing subrepository s
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-symlink-placeholder.t Thu Oct 27 18:35:07 2011 -0500 @@ -0,0 +1,68 @@ +Create extension that can disable symlink support: + + $ cat > nolink.py <<EOF + > from mercurial import extensions, util + > def setflags(orig, f, l, x): + > pass + > def checklink(orig, path): + > return False + > def extsetup(ui): + > extensions.wrapfunction(util, 'setflags', setflags) + > extensions.wrapfunction(util, 'checklink', checklink) + > EOF + + $ hg init unix-repo + $ cd unix-repo + $ echo foo > a + $ ln -s a b + $ hg ci -Am0 + adding a + adding b + $ cd .. + +Simulate a checkout shared on NFS/Samba: + + $ hg clone -q unix-repo shared + $ cd shared + $ rm b + $ echo foo > b + $ hg --config extensions.n=$TESTTMP/nolink.py status --debug + ignoring suspect symlink placeholder "b" + +Make a clone using placeholders: + + $ hg --config extensions.n=$TESTTMP/nolink.py clone . ../win-repo + updating to branch default + 2 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ cd ../win-repo + $ cat b + a (no-eol) + $ hg --config extensions.n=$TESTTMP/nolink.py st --debug + +Write binary data to the placeholder: + + >>> open('b', 'w').write('this is a binary\0') + $ hg --config extensions.n=$TESTTMP/nolink.py st --debug + ignoring suspect symlink placeholder "b" + +Write a long string to the placeholder: + + >>> open('b', 'w').write('this' * 1000) + $ hg --config extensions.n=$TESTTMP/nolink.py st --debug + ignoring suspect symlink placeholder "b" + +Commit shouldn't succeed: + + $ hg --config extensions.n=$TESTTMP/nolink.py ci -m1 + nothing changed + [1] + +Write a valid string to the placeholder: + + >>> open('b', 'w').write('this') + $ hg --config extensions.n=$TESTTMP/nolink.py st --debug + M b + $ hg --config extensions.n=$TESTTMP/nolink.py ci -m1 + $ hg manifest tip --verbose + 644 a + 644 @ b