# HG changeset patch # User Matt Mackall # Date 1345570067 18000 # Node ID 02e2308b61f7ce2b5eef66d0246b0f24700fd986 # Parent a10f7eeb2588ae469b996288b0d2554ccbe409da# Parent 635d4807e9c692a8abe3a5de10b85d24ecce4906 merge with i18n diff -r 635d4807e9c6 -r 02e2308b61f7 mercurial/commands.py --- a/mercurial/commands.py Mon Aug 13 16:09:35 2012 +0400 +++ b/mercurial/commands.py Tue Aug 21 12:27:47 2012 -0500 @@ -1847,14 +1847,17 @@ localrevs = opts.get('local_head') doit(localrevs, remoterevs) -@command('debugfileset', [], ('REVSPEC')) -def debugfileset(ui, repo, expr): +@command('debugfileset', + [('r', 'rev', '', _('apply the filespec on this revision'), _('REV'))], + _('[-r REV] FILESPEC')) +def debugfileset(ui, repo, expr, **opts): '''parse and apply a fileset specification''' + ctx = scmutil.revsingle(repo, opts.get('rev'), None) if ui.verbose: tree = fileset.parse(expr)[0] ui.note(tree, "\n") - for f in fileset.getfileset(repo[None], expr): + for f in fileset.getfileset(ctx, expr): ui.write("%s\n" % f) @command('debugfsinfo', [], _('[PATH]')) @@ -4174,7 +4177,7 @@ res.append(fn[plen:-slen]) finally: lock.release() - for f in sorted(res): + for f in res: ui.write("%s\n" % f) return diff -r 635d4807e9c6 -r 02e2308b61f7 mercurial/fileset.py --- a/mercurial/fileset.py Mon Aug 13 16:09:35 2012 +0400 +++ b/mercurial/fileset.py Tue Aug 21 12:27:47 2012 -0500 @@ -107,6 +107,11 @@ s = set(getset(mctx, x)) return [r for r in mctx.subset if r not in s] +def minusset(mctx, x, y): + xl = getset(mctx, x) + yl = set(getset(mctx, y)) + return [f for f in xl if f not in yl] + def listset(mctx, a, b): raise error.ParseError(_("can't use a list in this context")) @@ -251,8 +256,11 @@ """``grep(regex)`` File contains the given regular expression. """ - pat = getstring(x, _("grep requires a pattern")) - r = re.compile(pat) + try: + # i18n: "grep" is a keyword + r = re.compile(getstring(x, _("grep requires a pattern"))) + except re.error, e: + raise error.ParseError(_('invalid match pattern: %s') % e) return [f for f in mctx.existing() if r.search(mctx.ctx[f].data())] _units = dict(k=2**10, K=2**10, kB=2**10, KB=2**10, @@ -406,6 +414,7 @@ 'symbol': stringset, 'and': andset, 'or': orset, + 'minus': minusset, 'list': listset, 'group': getset, 'not': notset, @@ -424,7 +433,14 @@ def filter(self, files): return [f for f in files if f in self.subset] def existing(self): - return (f for f in self.subset if f in self.ctx) + if self._status is not None: + removed = set(self._status[3]) + unknown = set(self._status[4] + self._status[5]) + else: + removed = set() + unknown = set() + return (f for f in self.subset + if (f in self.ctx and f not in removed) or f in unknown) def narrow(self, files): return matchctx(self.ctx, self.filter(files), self._status) @@ -438,14 +454,26 @@ return True return False +# filesets using matchctx.existing() +_existingcallers = [ + 'binary', + 'exec', + 'grep', + 'size', + 'symlink', +] + def getfileset(ctx, expr): tree, pos = parse(expr) if (pos != len(expr)): raise error.ParseError(_("invalid token"), pos) # do we need status info? - if _intree(['modified', 'added', 'removed', 'deleted', - 'unknown', 'ignored', 'clean'], tree): + if (_intree(['modified', 'added', 'removed', 'deleted', + 'unknown', 'ignored', 'clean'], tree) or + # Using matchctx.existing() on a workingctx requires us to check + # for deleted files. + (ctx.rev() is None and _intree(_existingcallers, tree))): unknown = _intree(['unknown'], tree) ignored = _intree(['ignored'], tree) @@ -457,7 +485,7 @@ subset.extend(c) else: status = None - subset = ctx.walk(ctx.match([])) + subset = list(ctx.walk(ctx.match([]))) return getset(matchctx(ctx, subset, status), tree) diff -r 635d4807e9c6 -r 02e2308b61f7 mercurial/localrepo.py --- a/mercurial/localrepo.py Mon Aug 13 16:09:35 2012 +0400 +++ b/mercurial/localrepo.py Tue Aug 21 12:27:47 2012 -0500 @@ -1009,7 +1009,7 @@ util.rename(self.join('undo.dirstate'), self.join('dirstate')) try: branch = self.opener.read('undo.branch') - self.dirstate.setbranch(branch) + self.dirstate.setbranch(encoding.tolocal(branch)) except IOError: ui.warn(_('named branch could not be reset: ' 'current branch is still \'%s\'\n') diff -r 635d4807e9c6 -r 02e2308b61f7 mercurial/parsers.c --- a/mercurial/parsers.c Mon Aug 13 16:09:35 2012 +0400 +++ b/mercurial/parsers.c Tue Aug 21 12:27:47 2012 -0500 @@ -9,6 +9,7 @@ #include #include +#include #include #include "util.h" @@ -72,7 +73,7 @@ for (start = cur = str, zero = NULL; cur < str + len; cur++) { PyObject *file = NULL, *node = NULL; PyObject *flags = NULL; - int nlen; + ptrdiff_t nlen; if (!*cur) { zero = cur; @@ -94,7 +95,7 @@ nlen = cur - zero - 1; - node = unhexlify(zero + 1, nlen > 40 ? 40 : nlen); + node = unhexlify(zero + 1, nlen > 40 ? 40 : (int)nlen); if (!node) goto bail; @@ -1084,8 +1085,10 @@ return NULL; } - if (nodelen > 40) - nodelen = 40; + if (nodelen > 40) { + PyErr_SetString(PyExc_ValueError, "key too long"); + return NULL; + } for (i = 0; i < nodelen; i++) hexdigit(node, i); diff -r 635d4807e9c6 -r 02e2308b61f7 mercurial/store.py --- a/mercurial/store.py Mon Aug 13 16:09:35 2012 +0400 +++ b/mercurial/store.py Tue Aug 21 12:27:47 2012 -0500 @@ -7,7 +7,7 @@ from i18n import _ import osutil, scmutil, util -import os, stat +import os, stat, errno _sha = util.sha1 @@ -398,12 +398,14 @@ def datafiles(self): rewrite = False existing = [] - for f in self.fncache: + for f in sorted(self.fncache): ef = self.encode(f) try: yield f, ef, self.getsize(ef) existing.append(f) - except OSError: + except OSError, err: + if err.errno != errno.ENOENT: + raise # nonexistent entry rewrite = True if rewrite: diff -r 635d4807e9c6 -r 02e2308b61f7 mercurial/templatekw.py --- a/mercurial/templatekw.py Mon Aug 13 16:09:35 2012 +0400 +++ b/mercurial/templatekw.py Tue Aug 21 12:27:47 2012 -0500 @@ -275,6 +275,28 @@ """ return ctx.hex() +def showp1rev(repo, ctx, templ, **args): + """:p1rev: Integer. The repository-local revision number of the changeset's + first parent, or -1 if the changeset has no parents.""" + return ctx.p1().rev() + +def showp2rev(repo, ctx, templ, **args): + """:p2rev: Integer. The repository-local revision number of the changeset's + second parent, or -1 if the changeset has no second parent.""" + return ctx.p2().rev() + +def showp1node(repo, ctx, templ, **args): + """:p1node: String. The identification hash of the changeset's first parent, + as a 40 digit hexadecimal string. If the changeset has no parents, all + digits are 0.""" + return ctx.p1().hex() + +def showp2node(repo, ctx, templ, **args): + """:p2node: String. The identification hash of the changeset's second + parent, as a 40 digit hexadecimal string. If the changeset has no second + parent, all digits are 0.""" + return ctx.p2().hex() + def showphase(repo, ctx, templ, **args): """:phase: String. The changeset phase name.""" return ctx.phasestr() @@ -320,6 +342,10 @@ 'latesttagdistance': showlatesttagdistance, 'manifest': showmanifest, 'node': shownode, + 'p1rev': showp1rev, + 'p1node': showp1node, + 'p2rev': showp2rev, + 'p2node': showp2node, 'phase': showphase, 'phaseidx': showphaseidx, 'rev': showrev, diff -r 635d4807e9c6 -r 02e2308b61f7 tests/test-cat.t --- a/tests/test-cat.t Mon Aug 13 16:09:35 2012 +0400 +++ b/tests/test-cat.t Tue Aug 21 12:27:47 2012 -0500 @@ -21,3 +21,14 @@ [1] $ hg cat -r 1 b 1 + +Test fileset + + $ echo 3 > c + $ hg ci -Am addmore c + $ hg cat 'set:not(b) or a' + 3 + $ hg cat 'set:c or b' + 1 + 3 + diff -r 635d4807e9c6 -r 02e2308b61f7 tests/test-command-template.t --- a/tests/test-command-template.t Mon Aug 13 16:09:35 2012 +0400 +++ b/tests/test-command-template.t Tue Aug 21 12:27:47 2012 -0500 @@ -592,7 +592,8 @@ $ for key in author branch branches date desc file_adds file_dels file_mods \ > file_copies file_copies_switch files \ - > manifest node parents rev tags diffstat extras; do + > manifest node parents rev tags diffstat extras \ + > p1rev p2rev p1node p2node; do > for mode in '' --verbose --debug; do > hg log $mode --template "$key$mode: {$key}\n" > done @@ -1095,7 +1096,114 @@ extras--debug: branch=default extras--debug: branch=default extras--debug: branch=default - + p1rev: 7 + p1rev: -1 + p1rev: 5 + p1rev: 3 + p1rev: 3 + p1rev: 2 + p1rev: 1 + p1rev: 0 + p1rev: -1 + p1rev--verbose: 7 + p1rev--verbose: -1 + p1rev--verbose: 5 + p1rev--verbose: 3 + p1rev--verbose: 3 + p1rev--verbose: 2 + p1rev--verbose: 1 + p1rev--verbose: 0 + p1rev--verbose: -1 + p1rev--debug: 7 + p1rev--debug: -1 + p1rev--debug: 5 + p1rev--debug: 3 + p1rev--debug: 3 + p1rev--debug: 2 + p1rev--debug: 1 + p1rev--debug: 0 + p1rev--debug: -1 + p2rev: -1 + p2rev: -1 + p2rev: 4 + p2rev: -1 + p2rev: -1 + p2rev: -1 + p2rev: -1 + p2rev: -1 + p2rev: -1 + p2rev--verbose: -1 + p2rev--verbose: -1 + p2rev--verbose: 4 + p2rev--verbose: -1 + p2rev--verbose: -1 + p2rev--verbose: -1 + p2rev--verbose: -1 + p2rev--verbose: -1 + p2rev--verbose: -1 + p2rev--debug: -1 + p2rev--debug: -1 + p2rev--debug: 4 + p2rev--debug: -1 + p2rev--debug: -1 + p2rev--debug: -1 + p2rev--debug: -1 + p2rev--debug: -1 + p2rev--debug: -1 + p1node: 29114dbae42b9f078cf2714dbe3a86bba8ec7453 + p1node: 0000000000000000000000000000000000000000 + p1node: 13207e5a10d9fd28ec424934298e176197f2c67f + p1node: 10e46f2dcbf4823578cf180f33ecf0b957964c47 + p1node: 10e46f2dcbf4823578cf180f33ecf0b957964c47 + p1node: 97054abb4ab824450e9164180baf491ae0078465 + p1node: b608e9d1a3f0273ccf70fb85fd6866b3482bf965 + p1node: 1e4e1b8f71e05681d422154f5421e385fec3454f + p1node: 0000000000000000000000000000000000000000 + p1node--verbose: 29114dbae42b9f078cf2714dbe3a86bba8ec7453 + p1node--verbose: 0000000000000000000000000000000000000000 + p1node--verbose: 13207e5a10d9fd28ec424934298e176197f2c67f + p1node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47 + p1node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47 + p1node--verbose: 97054abb4ab824450e9164180baf491ae0078465 + p1node--verbose: b608e9d1a3f0273ccf70fb85fd6866b3482bf965 + p1node--verbose: 1e4e1b8f71e05681d422154f5421e385fec3454f + p1node--verbose: 0000000000000000000000000000000000000000 + p1node--debug: 29114dbae42b9f078cf2714dbe3a86bba8ec7453 + p1node--debug: 0000000000000000000000000000000000000000 + p1node--debug: 13207e5a10d9fd28ec424934298e176197f2c67f + p1node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47 + p1node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47 + p1node--debug: 97054abb4ab824450e9164180baf491ae0078465 + p1node--debug: b608e9d1a3f0273ccf70fb85fd6866b3482bf965 + p1node--debug: 1e4e1b8f71e05681d422154f5421e385fec3454f + p1node--debug: 0000000000000000000000000000000000000000 + p2node: 0000000000000000000000000000000000000000 + p2node: 0000000000000000000000000000000000000000 + p2node: bbe44766e73d5f11ed2177f1838de10c53ef3e74 + p2node: 0000000000000000000000000000000000000000 + p2node: 0000000000000000000000000000000000000000 + p2node: 0000000000000000000000000000000000000000 + p2node: 0000000000000000000000000000000000000000 + p2node: 0000000000000000000000000000000000000000 + p2node: 0000000000000000000000000000000000000000 + p2node--verbose: 0000000000000000000000000000000000000000 + p2node--verbose: 0000000000000000000000000000000000000000 + p2node--verbose: bbe44766e73d5f11ed2177f1838de10c53ef3e74 + p2node--verbose: 0000000000000000000000000000000000000000 + p2node--verbose: 0000000000000000000000000000000000000000 + p2node--verbose: 0000000000000000000000000000000000000000 + p2node--verbose: 0000000000000000000000000000000000000000 + p2node--verbose: 0000000000000000000000000000000000000000 + p2node--verbose: 0000000000000000000000000000000000000000 + p2node--debug: 0000000000000000000000000000000000000000 + p2node--debug: 0000000000000000000000000000000000000000 + p2node--debug: bbe44766e73d5f11ed2177f1838de10c53ef3e74 + p2node--debug: 0000000000000000000000000000000000000000 + p2node--debug: 0000000000000000000000000000000000000000 + p2node--debug: 0000000000000000000000000000000000000000 + p2node--debug: 0000000000000000000000000000000000000000 + p2node--debug: 0000000000000000000000000000000000000000 + p2node--debug: 0000000000000000000000000000000000000000 Filters work: diff -r 635d4807e9c6 -r 02e2308b61f7 tests/test-debugcomplete.t --- a/tests/test-debugcomplete.t Mon Aug 13 16:09:35 2012 +0400 +++ b/tests/test-debugcomplete.t Tue Aug 21 12:27:47 2012 -0500 @@ -229,7 +229,7 @@ debugdata: changelog, manifest debugdate: extended debugdiscovery: old, nonheads, ssh, remotecmd, insecure - debugfileset: + debugfileset: rev debugfsinfo: debuggetbundle: head, common, type debugignore: diff -r 635d4807e9c6 -r 02e2308b61f7 tests/test-encoding.t --- a/tests/test-encoding.t Mon Aug 13 16:09:35 2012 +0400 +++ b/tests/test-encoding.t Tue Aug 21 12:27:47 2012 -0500 @@ -44,6 +44,10 @@ marked working directory as branch \xe9 (esc) (branches are permanent and global, did you want a bookmark?) $ HGENCODING=latin-1 hg ci -m 'latin1 branch' + $ hg -q rollback + $ HGENCODING=latin-1 hg branch + \xe9 (esc) + $ HGENCODING=latin-1 hg ci -m 'latin1 branch' $ rm .hg/branch hg log (ascii) diff -r 635d4807e9c6 -r 02e2308b61f7 tests/test-fileset.t --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-fileset.t Tue Aug 21 12:27:47 2012 -0500 @@ -0,0 +1,228 @@ + $ fileset() { + > hg debugfileset "$@" + > } + + $ hg init repo + $ cd repo + $ echo a > a1 + $ echo a > a2 + $ echo b > b1 + $ echo b > b2 + $ hg ci -Am addfiles + adding a1 + adding a2 + adding b1 + adding b2 + +Test operators and basic patterns + + $ fileset a1 + a1 + $ fileset 'a*' + a1 + a2 + $ fileset '"re:a\d"' + a1 + a2 + $ fileset 'a1 or a2' + a1 + a2 + $ fileset 'a1 | a2' + a1 + a2 + $ fileset 'a* and "*1"' + a1 + $ fileset 'a* & "*1"' + a1 + $ fileset 'not (r"a*")' + b1 + b2 + $ fileset '! ("a*")' + b1 + b2 + $ fileset 'a* - a1' + a2 + +Test files status + + $ rm a1 + $ hg rm a2 + $ echo b >> b2 + $ hg cp b1 c1 + $ echo c > c2 + $ echo c > c3 + $ cat > .hgignore < \.hgignore + > 2$ + > EOF + $ fileset 'modified()' + b2 + $ fileset 'added()' + c1 + $ fileset 'removed()' + a2 + $ fileset 'deleted()' + a1 + $ fileset 'unknown()' + c3 + $ fileset 'ignored()' + .hgignore + c2 + $ fileset 'hgignore()' + a2 + b2 + $ fileset 'clean()' + b1 + $ fileset 'copied()' + c1 + +Test files properties + + >>> file('bin', 'wb').write('\0a') + $ fileset 'binary()' + $ fileset 'binary() and unknown()' + bin + $ echo '^bin$' >> .hgignore + $ fileset 'binary() and ignored()' + bin + $ hg add bin + $ fileset 'binary()' + bin + + $ fileset 'grep("b{1}")' + b2 + c1 + b1 + $ fileset 'grep("missingparens(")' + hg: parse error: invalid match pattern: unbalanced parenthesis + [255] + +#if execbit + $ chmod +x b2 + $ fileset 'exec()' + b2 +#endif + +#if symlink + $ ln -s b2 b2link + $ fileset 'symlink() and unknown()' + b2link + $ hg add b2link +#endif + + >>> file('1k', 'wb').write(' '*1024) + >>> file('2k', 'wb').write(' '*2048) + $ hg add 1k 2k + $ fileset 'size("bar")' + hg: parse error: couldn't parse size: bar + [255] + $ fileset 'size(1k)' + 1k + $ fileset '(1k or 2k) and size("< 2k")' + 1k + $ fileset '(1k or 2k) and size("<=2k")' + 1k + 2k + $ fileset '(1k or 2k) and size("> 1k")' + 2k + $ fileset '(1k or 2k) and size(">=1K")' + 1k + 2k + $ fileset '(1k or 2k) and size(".5KB - 1.5kB")' + 1k + +Test merge states + + $ hg ci -m manychanges + $ hg up -C 0 + * files updated, 0 files merged, * files removed, 0 files unresolved (glob) + $ echo c >> b2 + $ hg ci -m diverging b2 + created new head + $ fileset 'resolved()' + $ fileset 'unresolved()' + $ hg merge + merging b2 + warning: conflicts during merge. + merging b2 incomplete! (edit conflicts, then use 'hg resolve --mark') + * files updated, 0 files merged, * files removed, 1 files unresolved (glob) + use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon + [1] + $ fileset 'resolved()' + $ fileset 'unresolved()' + b2 + $ echo e > b2 + $ hg resolve -m b2 + $ fileset 'resolved()' + b2 + $ fileset 'unresolved()' + $ hg ci -m merge + +Test subrepo predicate + + $ hg init sub + $ echo a > sub/suba + $ hg -R sub add sub/suba + $ hg -R sub ci -m sub + $ echo 'sub = sub' > .hgsub + $ fileset 'subrepo()' + $ hg add .hgsub + $ fileset 'subrepo()' + sub + $ fileset 'subrepo("sub")' + sub + $ fileset 'subrepo("glob:*")' + sub + $ hg ci -m subrepo + +Test with a revision + + $ hg log -G --template '{rev} {desc}\n' + @ 4 subrepo + | + o 3 merge + |\ + | o 2 diverging + | | + o | 1 manychanges + |/ + o 0 addfiles + + $ echo unknown > unknown + $ fileset -r1 'modified()' + b2 + $ fileset -r1 'added() and c1' + c1 + $ fileset -r1 'removed()' + a2 + $ fileset -r1 'deleted()' + $ fileset -r1 'unknown()' + $ fileset -r1 'ignored()' + $ fileset -r1 'hgignore()' + b2 + bin + $ fileset -r1 'binary()' + bin + $ fileset -r1 'size(1k)' + 1k + $ fileset -r3 'resolved()' + $ fileset -r3 'unresolved()' + +#if execbit + $ fileset -r1 'exec()' + b2 +#endif + +#if symlink + $ fileset -r1 'symlink()' + b2link +#endif + + $ fileset -r4 'subrepo("re:su.*")' + sub + $ fileset -r4 'subrepo("sub")' + sub + $ fileset -r4 'b2 or c1' + b2 + c1 + diff -r 635d4807e9c6 -r 02e2308b61f7 tests/test-status.t --- a/tests/test-status.t Mon Aug 13 16:09:35 2012 +0400 +++ b/tests/test-status.t Tue Aug 21 12:27:47 2012 -0500 @@ -330,4 +330,9 @@ $ hg status -A --rev 1 1 R 1/2/3/4/5/b.txt +#if windows + $ hg --config ui.slash=false status -A --rev 1 1 + R 1\2\3\4\5\b.txt +#endif + $ cd .. diff -r 635d4807e9c6 -r 02e2308b61f7 tests/test-template-engine.t --- a/tests/test-template-engine.t Mon Aug 13 16:09:35 2012 +0400 +++ b/tests/test-template-engine.t Tue Aug 21 12:27:47 2012 -0500 @@ -36,4 +36,12 @@ $ hg log --style=./mymap 0 97e5f848f0936960273bbf75be6388cd0350a32b test + $ cat > changeset.txt << EOF + > {{p1rev}} {{p1node}} {{p2rev}} {{p2node}} + > EOF + $ hg ci -Ama + $ hg log --style=./mymap + 0 97e5f848f0936960273bbf75be6388cd0350a32b -1 0000000000000000000000000000000000000000 + -1 0000000000000000000000000000000000000000 -1 0000000000000000000000000000000000000000 + $ cd ..