Mercurial > hg
changeset 20153:35bfe5405fb4 stable
merge with i18n
author | Matt Mackall <mpm@selenic.com> |
---|---|
date | Sun, 01 Dec 2013 13:45:00 -0600 |
parents | 84939b728749 (diff) 65bc57780406 (current diff) |
children | 970394b6bd97 |
files | |
diffstat | 13 files changed, 271 insertions(+), 43 deletions(-) [+] |
line wrap: on
line diff
--- a/contrib/sample.hgrc Sat Nov 30 21:50:40 2013 -0200 +++ b/contrib/sample.hgrc Sun Dec 01 13:45:00 2013 -0600 @@ -43,20 +43,15 @@ # hgext.gpg = -### graphlog - ASCII graph log -### hg help glog - -# hgext.graphlog = - ### hgk - GUI repository browser ### hg help view # hgext.hgk = -### mq - Mercurial patch queues -### hg help mq +### strip - Remove changesets and their descendents from history +### hg help strip -# hgext.mq = +# hgext.strip = ### notify - Template driven e-mail notifications ### hg help notify
--- a/contrib/win32/mercurial.ini Sat Nov 30 21:50:40 2013 -0200 +++ b/contrib/win32/mercurial.ini Sun Dec 01 13:45:00 2013 -0600 @@ -46,7 +46,6 @@ ;extdiff = ;fetch = ;gpg = -;graphlog = ;hgcia = ;hgk = ;highlight =
--- a/hgext/largefiles/overrides.py Sat Nov 30 21:50:40 2013 -0200 +++ b/hgext/largefiles/overrides.py Sun Dec 01 13:45:00 2013 -0600 @@ -380,7 +380,7 @@ for action in actions: f, m, args, msg = action - splitstandin = lfutil.splitstandin(f) + splitstandin = f and lfutil.splitstandin(f) if (m == "g" and splitstandin is not None and splitstandin in p1 and splitstandin not in removes): # Case 1: normal file in the working copy, largefile in
--- a/hgext/shelve.py Sat Nov 30 21:50:40 2013 -0200 +++ b/hgext/shelve.py Sun Dec 01 13:45:00 2013 -0600 @@ -91,7 +91,6 @@ pendingctx = fp.readline().strip() parents = [bin(h) for h in fp.readline().split()] stripnodes = [bin(h) for h in fp.readline().split()] - unknownfiles = fp.readline()[:-1].split('\0') finally: fp.close() @@ -101,13 +100,11 @@ obj.pendingctx = repo[bin(pendingctx)] obj.parents = parents obj.stripnodes = stripnodes - obj.unknownfiles = unknownfiles return obj @classmethod - def save(cls, repo, name, originalwctx, pendingctx, stripnodes, - unknownfiles): + def save(cls, repo, name, originalwctx, pendingctx, stripnodes): fp = repo.opener(cls._filename, 'wb') fp.write('%i\n' % cls._version) fp.write('%s\n' % name) @@ -115,7 +112,6 @@ fp.write('%s\n' % hex(pendingctx.node())) fp.write('%s\n' % ' '.join([hex(p) for p in repo.dirstate.parents()])) fp.write('%s\n' % ' '.join([hex(n) for n in stripnodes])) - fp.write('%s\n' % '\0'.join(unknownfiles)) fp.close() @classmethod @@ -379,7 +375,7 @@ lock = repo.lock() - mergefiles(ui, repo, state.wctx, state.pendingctx, state.unknownfiles) + mergefiles(ui, repo, state.wctx, state.pendingctx) repair.strip(ui, repo, state.stripnodes, backup='none', topic='shelve') shelvedstate.clear(repo) @@ -387,9 +383,9 @@ finally: lockmod.release(lock, wlock) -def mergefiles(ui, repo, wctx, shelvectx, unknownfiles): +def mergefiles(ui, repo, wctx, shelvectx): """updates to wctx and merges the changes from shelvectx into the - dirstate. drops any files in unknownfiles from the dirstate.""" + dirstate.""" oldquiet = ui.quiet try: ui.quiet = True @@ -397,17 +393,18 @@ files = [] files.extend(shelvectx.files()) files.extend(shelvectx.parents()[0].files()) + + # revert will overwrite unknown files, so move them out of the way + m, a, r, d, u = repo.status(unknown=True)[:5] + for file in u: + if file in files: + util.rename(file, file + ".orig") cmdutil.revert(ui, repo, shelvectx, repo.dirstate.parents(), *pathtofiles(repo, files), **{'no_backup': True}) finally: ui.quiet = oldquiet - # Send untracked files back to being untracked - dirstate = repo.dirstate - for f in unknownfiles: - dirstate.drop(f) - def unshelvecleanup(ui, repo, name, opts): """remove related files after an unshelve""" if not opts['keep']: @@ -446,7 +443,7 @@ # rebase was a no-op, so it produced no child commit shelvectx = state.pendingctx - mergefiles(ui, repo, state.wctx, shelvectx, state.unknownfiles) + mergefiles(ui, repo, state.wctx, shelvectx) state.stripnodes.append(shelvectx.node()) repair.strip(ui, repo, state.stripnodes, backup='none', topic='shelve') @@ -538,8 +535,8 @@ # to the original wctx. # Store pending changes in a commit - m, a, r, d, u = repo.status(unknown=True)[:5] - if m or a or r or d or u: + m, a, r, d = repo.status()[:4] + if m or a or r or d: def commitfunc(ui, repo, message, match, opts): hasmq = util.safehasattr(repo, 'mq') if hasmq: @@ -554,7 +551,6 @@ tempopts = {} tempopts['message'] = "pending changes temporary commit" - tempopts['addremove'] = True oldquiet = ui.quiet try: ui.quiet = True @@ -588,7 +584,7 @@ stripnodes = [repo.changelog.node(rev) for rev in xrange(oldtiprev, len(repo))] - shelvedstate.save(repo, basename, wctx, tmpwctx, stripnodes, u) + shelvedstate.save(repo, basename, wctx, tmpwctx, stripnodes) util.rename(repo.join('rebasestate'), repo.join('unshelverebasestate')) @@ -603,7 +599,7 @@ # rebase was a no-op, so it produced no child commit shelvectx = tmpwctx - mergefiles(ui, repo, wctx, shelvectx, u) + mergefiles(ui, repo, wctx, shelvectx) shelvedstate.clear(repo) # The transaction aborting will strip all the commits for us,
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/i18n/check-translation.py Sun Dec 01 13:45:00 2013 -0600 @@ -0,0 +1,148 @@ +#!/usr/bin/env python +# +# check-translation.py - check Mercurial specific translation problems + +import polib +import re + +checkers = [] + +def checker(level, msgidpat): + def decorator(func): + if msgidpat: + match = re.compile(msgidpat).search + else: + match = lambda msgid: True + checkers.append((func, level)) + func.match = match + return func + return decorator + +def match(checker, pe): + """Examine whether POEntry "pe" is target of specified checker or not + """ + if not checker.match(pe.msgid): + return + # examine suppression by translator comment + nochecker = 'no-%s-check' % checker.__name__ + for tc in pe.tcomment.split(): + if nochecker == tc: + return + return True + +#################### + +def fatalchecker(msgidpat=None): + return checker('fatal', msgidpat) + +@fatalchecker(r'\$\$') +def promptchoice(pe): + """Check translation of the string given to "ui.promptchoice()" + + >>> pe = polib.POEntry( + ... msgid ='prompt$$missing &sep$$missing &$$followed by &none', + ... msgstr='prompt missing &sep$$missing amp$$followed by none&') + >>> match(promptchoice, pe) + True + >>> for e in promptchoice(pe): print e + number of choices differs between msgid and msgstr + msgstr has invalid choice missing '&' + msgstr has invalid '&' followed by none + """ + idchoices = [c.rstrip(' ') for c in pe.msgid.split('$$')[1:]] + strchoices = [c.rstrip(' ') for c in pe.msgstr.split('$$')[1:]] + + if len(idchoices) != len(strchoices): + yield "number of choices differs between msgid and msgstr" + + indices = [(c, c.find('&')) for c in strchoices] + if [c for c, i in indices if i == -1]: + yield "msgstr has invalid choice missing '&'" + if [c for c, i in indices if len(c) == i + 1]: + yield "msgstr has invalid '&' followed by none" + +#################### + +def warningchecker(msgidpat=None): + return checker('warning', msgidpat) + +#################### + +def check(pofile, fatal=True, warning=False): + targetlevel = { 'fatal': fatal, 'warning': warning } + targetcheckers = [(checker, level) + for checker, level in checkers + if targetlevel[level]] + if not targetcheckers: + return [] + + detected = [] + for pe in pofile.translated_entries(): + errors = [] + for checker, level in targetcheckers: + if match(checker, pe): + errors.extend((level, checker.__name__, error) + for error in checker(pe)) + if errors: + detected.append((pe, errors)) + return detected + +######################################## + +if __name__ == "__main__": + import sys + import optparse + + optparser = optparse.OptionParser("""%prog [options] pofile ... + +This checks Mercurial specific translation problems in specified +'*.po' files. + +Each detected problems are shown in the format below:: + + filename:linenum:type(checker): problem detail ..... + +"type" is "fatal" or "warning". "checker" is the name of the function +detecting corresponded error. + +Checking by checker "foo" on the specific msgstr can be suppressed by +the "translator comment" like below. Multiple "no-xxxx-check" should +be separated by whitespaces:: + + # no-foo-check + msgid = "....." + msgstr = "....." +""") + optparser.add_option("", "--warning", + help="show also warning level problems", + action="store_true") + optparser.add_option("", "--doctest", + help="run doctest of this tool, instead of check", + action="store_true") + (options, args) = optparser.parse_args() + + if options.doctest: + import doctest + failures, tests = doctest.testmod() + sys.exit(failures and 1 or 0) + + # replace polib._POFileParser to show linenum of problematic msgstr + class ExtPOFileParser(polib._POFileParser): + def process(self, symbol, linenum): + super(ExtPOFileParser, self).process(symbol, linenum) + if symbol == 'MS': # msgstr + self.current_entry.linenum = linenum + polib._POFileParser = ExtPOFileParser + + detected = [] + warning = options.warning + for f in args: + detected.extend((f, pe, errors) + for pe, errors in check(polib.pofile(f), + warning=warning)) + if detected: + for f, pe, errors in detected: + for level, checker, error in errors: + sys.stderr.write('%s:%d:%s(%s): %s\n' + % (f, pe.linenum, level, checker, error)) + sys.exit(1)
--- a/mercurial/commands.py Sat Nov 30 21:50:40 2013 -0200 +++ b/mercurial/commands.py Sun Dec 01 13:45:00 2013 -0600 @@ -538,7 +538,7 @@ Some examples: - - start a bisection with known bad revision 12, and good revision 34:: + - start a bisection with known bad revision 34, and good revision 12:: hg bisect --bad 34 hg bisect --good 12 @@ -585,7 +585,7 @@ hg log -r "bisect(range)" - - with the graphlog extension, you can even get a nice graph:: + - you can even get a nice graph:: hg log --graph -r "bisect(range)"
--- a/mercurial/help/config.txt Sat Nov 30 21:50:40 2013 -0200 +++ b/mercurial/help/config.txt Sun Dec 01 13:45:00 2013 -0600 @@ -495,8 +495,8 @@ Example for ``~/.hgrc``:: [extensions] - # (the mq extension will get loaded from Mercurial's path) - mq = + # (the progress extension will get loaded from Mercurial's path) + progress = # (this extension will get loaded from the file specified) myfeature = ~/.hgext/myfeature.py
--- a/mercurial/help/glossary.txt Sat Nov 30 21:50:40 2013 -0200 +++ b/mercurial/help/glossary.txt Sun Dec 01 13:45:00 2013 -0600 @@ -173,9 +173,9 @@ system (DVCS) can be described as a directed acyclic graph (DAG), consisting of nodes and edges, where nodes correspond to changesets and edges imply a parent -> child relation. This graph - can be visualized by graphical tools such as :hg:`glog` - (graphlog). In Mercurial, the DAG is limited by the requirement - for children to have at most two parents. + can be visualized by graphical tools such as :hg:`log --graph`. In + Mercurial, the DAG is limited by the requirement for children to + have at most two parents. Default branch See 'Branch, default'. @@ -218,7 +218,7 @@ extensions. See :hg:`help phases`. Graph - See DAG and :hg:`help graphlog`. + See DAG and :hg:`log --graph`. Head The term 'head' may be used to refer to both a branch head or a
--- a/mercurial/parsers.c Sat Nov 30 21:50:40 2013 -0200 +++ b/mercurial/parsers.c Sun Dec 01 13:45:00 2013 -0600 @@ -1713,6 +1713,15 @@ PyObject *data_obj, *inlined_obj; Py_ssize_t size; + /* Initialize before argument-checking to avoid index_dealloc() crash. */ + self->raw_length = 0; + self->added = NULL; + self->cache = NULL; + self->data = NULL; + self->headrevs = NULL; + self->nt = NULL; + self->offsets = NULL; + if (!PyArg_ParseTuple(args, "OO", &data_obj, &inlined_obj)) return -1; if (!PyString_Check(data_obj)) { @@ -1723,12 +1732,7 @@ self->inlined = inlined_obj && PyObject_IsTrue(inlined_obj); self->data = data_obj; - self->cache = NULL; - self->added = NULL; - self->headrevs = NULL; - self->offsets = NULL; - self->nt = NULL; self->ntlength = self->ntcapacity = 0; self->ntdepth = self->ntsplits = 0; self->ntlookups = self->ntmisses = 0; @@ -1764,7 +1768,7 @@ static void index_dealloc(indexObject *self) { _index_clearcaches(self); - Py_DECREF(self->data); + Py_XDECREF(self->data); Py_XDECREF(self->added); PyObject_Del(self); }
--- a/tests/test-i18n.t Sat Nov 30 21:50:40 2013 -0200 +++ b/tests/test-i18n.t Sun Dec 01 13:45:00 2013 -0600 @@ -38,3 +38,10 @@ pager Verwendet einen externen Pager zum Bl\xc3\xa4ttern in der Ausgabe von Befehlen (esc) +Check Mercurial specific translation problems in each *.po files, and +tool itself by doctest + + $ cd "$TESTDIR"/../i18n + $ python check-translation.py *.po + $ python check-translation.py --doctest + $ cd $TESTTMP
--- a/tests/test-largefiles.t Sat Nov 30 21:50:40 2013 -0200 +++ b/tests/test-largefiles.t Sun Dec 01 13:45:00 2013 -0600 @@ -2192,6 +2192,39 @@ $ cd .. +merge action 'd' for 'local renamed directory to d2/g' which has no filename + + $ hg init merge-action + $ cd merge-action + $ touch l + $ hg add --large l + $ mkdir d1 + $ touch d1/f + $ hg ci -Aqm0 + Invoking status precommit hook + A d1/f + A l + $ echo > d1/f + $ touch d1/g + $ hg ci -Aqm1 + Invoking status precommit hook + M d1/f + A d1/g + $ hg up -qr0 + $ hg mv d1 d2 + moving d1/f to d2/f (glob) + $ hg ci -qm2 + Invoking status precommit hook + A d2/f + R d1/f + $ hg merge + merging d2/f and d1/f to d2/f + 1 files updated, 1 files merged, 0 files removed, 0 files unresolved + (branch merge, don't forget to commit) + getting changed largefiles + 0 largefiles updated, 0 removed + $ cd .. + Check whether "largefiles" feature is supported only in repositories enabling largefiles extension.
--- a/tests/test-parseindex2.py Sat Nov 30 21:50:40 2013 -0200 +++ b/tests/test-parseindex2.py Sun Dec 01 13:45:00 2013 -0600 @@ -98,6 +98,14 @@ return list(index), chunkcache def runtest() : + # Check that parse_index2() raises TypeError on bad arguments. + try: + parse_index2(0, True) + except TypeError: + pass + else: + print "Expected to get TypeError." + py_res_1 = py_parseindex(data_inlined, True) c_res_1 = parse_index2(data_inlined, True)
--- a/tests/test-shelve.t Sat Nov 30 21:50:40 2013 -0200 +++ b/tests/test-shelve.t Sun Dec 01 13:45:00 2013 -0600 @@ -539,4 +539,42 @@ adding file changes added 1 changesets with 1 changes to 2 files (+1 heads) +unshelve should leave unknown files alone (issue4113) + + $ echo e > e + $ hg shelve + shelved as default + 0 files updated, 0 files merged, 1 files removed, 0 files unresolved + $ hg status + ? e + $ hg unshelve + unshelving change 'default' + adding changesets + adding manifests + adding file changes + added 1 changesets with 1 changes to 2 files (+1 heads) + $ hg status + A d + ? e + $ cat e + e + +unshelve should keep a copy of unknown files + + $ hg add e + $ hg shelve + shelved as default + 0 files updated, 0 files merged, 2 files removed, 0 files unresolved + $ echo z > e + $ hg unshelve + unshelving change 'default' + adding changesets + adding manifests + adding file changes + added 1 changesets with 2 changes to 3 files (+1 heads) + $ cat e + e + $ cat e.orig + z + $ cd ..