diff --git a/mercurial/revset.py b/mercurial/revset.py --- a/mercurial/revset.py +++ b/mercurial/revset.py @@ -1335,6 +1335,29 @@ return subset & rs +@predicate(b'nodefromfile(path)') +def nodefromfile(repo, subset, x): + """ + An alias for ``::.`` (ancestors of the working directory's first parent). + If file pattern is specified, the histories of files matching given + pattern in the revision given by startrev are followed, including copies. + """ + path = getstring(x, _(b"nodefromfile require a file path")) + listed_rev = set() + try: + with pycompat.open(path, 'rb') as f: + for line in f: + n = line.strip() + rn = _node(repo, n) + if rn is not None: + listed_rev.add(rn) + except IOError as exc: + m = _(b'cannot open nodes file "%s": %s') + m %= (path, encoding.strtolocal(exc.strerror)) + raise error.Abort(m) + return subset & baseset(listed_rev) + + @predicate(b'all()', safe=True) def getall(repo, subset, x): """All changesets, the same as ``0:tip``.""" @@ -1697,13 +1720,9 @@ return subset & names -@predicate(b'id(string)', safe=True) -def node_(repo, subset, x): - """Revision non-ambiguously specified by the given hex string prefix.""" - # i18n: "id" is a keyword - l = getargs(x, 1, 1, _(b"id requires one argument")) - # i18n: "id" is a keyword - n = getstring(l[0], _(b"id requires a string")) +def _node(repo, n): + """process a node input""" + rn = None if len(n) == 40: try: rn = repo.changelog.rev(bin(n)) @@ -1712,7 +1731,6 @@ except (LookupError, TypeError): rn = None else: - rn = None try: pm = scmutil.resolvehexnodeidprefix(repo, n) if pm is not None: @@ -1721,6 +1739,17 @@ pass except error.WdirUnsupported: rn = wdirrev + return rn + + +@predicate(b'id(string)', safe=True) +def node_(repo, subset, x): + """Revision non-ambiguously specified by the given hex string prefix.""" + # i18n: "id" is a keyword + l = getargs(x, 1, 1, _(b"id requires one argument")) + # i18n: "id" is a keyword + n = getstring(l[0], _(b"id requires a string")) + rn = _node(repo, n) if rn is None: return baseset() diff --git a/tests/test-default-push.t b/tests/test-default-push.t --- a/tests/test-default-push.t +++ b/tests/test-default-push.t @@ -137,6 +137,7 @@ $ hg --config 'paths.default:pushrev=notdefined()' push pushing to file:/*/$TESTTMP/pushurlsource/../pushurldest (glob) hg: parse error: unknown identifier: notdefined + (did you mean nodefromfile?) [10] $ hg --config 'paths.default:pushrev=(' push diff --git a/tests/test-revset.t b/tests/test-revset.t --- a/tests/test-revset.t +++ b/tests/test-revset.t @@ -3108,3 +3108,18 @@ $ log 'expectsize(0:2, :2)' abort: revset size mismatch. expected between 0 and 2, got 3 [255] + +Test getting list of node from file + + $ hg log -r '0:2' -T '{node}\n' > some.nodes + $ hg log -r 'nodefromfile("some.nodes")' -T '{rev}\n' + 0 + 1 + 2 + $ hg log -r 'nodefromfile("missing-file")' -T '{rev}\n' + abort: cannot open nodes file "missing-file": $ENOENT$ + [255] + $ echo bad-node > bad.nodes + $ hg log -r 'nodefromfile("bad.nodes")' -T '{rev}\n' + $ echo abcdefabcdefabcdeabcdeabcdeabcdeabcdeabc > missing.nodes +