diff --git a/mercurial/revset.py b/mercurial/revset.py --- a/mercurial/revset.py +++ b/mercurial/revset.py @@ -561,6 +561,50 @@ def _firstdescendants(repo, subset, x): # Like ``descendants(set)`` but follows only the first parents. return _descendants(repo, subset, x, followfirst=True) +def destination(repo, subset, x): + """``destination([set])`` + Changesets that were created by a graft, transplant or rebase operation, + with the given revisions specified as the source. Omitting the optional set + is the same as passing all(). + """ + if x is not None: + args = set(getset(repo, range(len(repo)), x)) + else: + args = set(getall(repo, range(len(repo)), x)) + + dests = set() + + # subset contains all of the possible destinations that can be returned, so + # iterate over them and see if their source(s) were provided in the args. + # Even if the immediate src of r is not in the args, src's source (or + # further back) may be. Scanning back further than the immediate src allows + # transitive transplants and rebases to yield the same results as transitive + # grafts. + for r in subset: + src = _getrevsource(repo, r) + lineage = None + + while src is not None: + if lineage is None: + lineage = list() + + lineage.append(r) + + # The visited lineage is a match if the current source is in the arg + # set. Since every candidate dest is visited by way of iterating + # subset, any dests futher back in the lineage will be tested by a + # different iteration over subset. Likewise, if the src was already + # selected, the current lineage can be selected without going back + # further. + if src in args or src in dests: + dests.update(lineage) + break + + r = src + src = _getrevsource(repo, r) + + return [r for r in subset if r in dests] + def draft(repo, subset, x): """``draft()`` Changeset in draft phase.""" @@ -1399,6 +1443,7 @@ symbols = { "desc": desc, "descendants": descendants, "_firstdescendants": _firstdescendants, + "destination": destination, "draft": draft, "extinct": extinct, "extra": extra, diff --git a/tests/test-graft.t b/tests/test-graft.t --- a/tests/test-graft.t +++ b/tests/test-graft.t @@ -405,3 +405,131 @@ Now transplant a graft to test following date: Thu Jan 01 00:00:00 1970 +0000 summary: 2 +Test simple destination + $ hg log -r 'destination()' + changeset: 7:ef0ef43d49e7 + parent: 0:68795b066622 + user: foo + date: Thu Jan 01 00:00:00 1970 +0000 + summary: 2 + + changeset: 8:6b9e5368ca4e + user: bar + date: Thu Jan 01 00:00:00 1970 +0000 + summary: 1 + + changeset: 9:1905859650ec + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: 5 + + changeset: 10:52dc0b4c6907 + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: 4 + + changeset: 11:882b35362a6b + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: 3 + + changeset: 13:9db0f28fd374 + user: foo + date: Thu Jan 01 00:00:00 1970 +0000 + summary: 2 + + changeset: 14:f64defefacee + parent: 1:5d205f8b35b6 + user: foo + date: Thu Jan 01 00:00:00 1970 +0000 + summary: 3 + + changeset: 17:64ecd9071ce8 + user: bar + date: Thu Jan 01 00:00:00 1970 +0000 + summary: 1 + + changeset: 19:2e80e1351d6e + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: 2 + + changeset: 21:7e61b508e709 + branch: dev + tag: tip + user: foo + date: Thu Jan 01 00:00:00 1970 +0000 + summary: 2 + + $ hg log -r 'destination(2)' + changeset: 7:ef0ef43d49e7 + parent: 0:68795b066622 + user: foo + date: Thu Jan 01 00:00:00 1970 +0000 + summary: 2 + + changeset: 13:9db0f28fd374 + user: foo + date: Thu Jan 01 00:00:00 1970 +0000 + summary: 2 + + changeset: 19:2e80e1351d6e + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: 2 + + changeset: 21:7e61b508e709 + branch: dev + tag: tip + user: foo + date: Thu Jan 01 00:00:00 1970 +0000 + summary: 2 + +Transplants of grafts can find a destination... + $ hg log -r 'destination(7)' + changeset: 21:7e61b508e709 + branch: dev + tag: tip + user: foo + date: Thu Jan 01 00:00:00 1970 +0000 + summary: 2 + +... grafts of grafts unfortunately can't + $ hg graft -q 13 + $ hg log -r 'destination(13)' +All copies of a cset + $ hg log -r 'origin(13) or destination(origin(13))' + changeset: 2:5c095ad7e90f + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: 2 + + changeset: 7:ef0ef43d49e7 + parent: 0:68795b066622 + user: foo + date: Thu Jan 01 00:00:00 1970 +0000 + summary: 2 + + changeset: 13:9db0f28fd374 + user: foo + date: Thu Jan 01 00:00:00 1970 +0000 + summary: 2 + + changeset: 19:2e80e1351d6e + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: 2 + + changeset: 21:7e61b508e709 + branch: dev + user: foo + date: Thu Jan 01 00:00:00 1970 +0000 + summary: 2 + + changeset: 22:1313d0a825e2 + branch: dev + tag: tip + user: foo + date: Thu Jan 01 00:00:00 1970 +0000 + summary: 2 + diff --git a/tests/test-transplant.t b/tests/test-transplant.t --- a/tests/test-transplant.t +++ b/tests/test-transplant.t @@ -83,6 +83,74 @@ test tranplanted keyword 1 0 +test destination() revset predicate with a transplant of a transplant; new +clone so subsequent rollback isn't affected + $ hg clone -q . ../destination + $ cd ../destination + $ hg up -Cq 0 + $ hg branch -q b4 + $ hg ci -qm "b4" + $ hg transplant 7 + applying ffd6818a3975 + ffd6818a3975 transplanted to 502236fa76bb + + + $ hg log -r 'destination()' + changeset: 5:e234d668f844 + parent: 1:d11e3596cc1a + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: b1 + + changeset: 6:539f377d78df + user: test + date: Thu Jan 01 00:00:01 1970 +0000 + summary: b2 + + changeset: 7:ffd6818a3975 + user: test + date: Thu Jan 01 00:00:02 1970 +0000 + summary: b3 + + changeset: 9:502236fa76bb + branch: b4 + tag: tip + user: test + date: Thu Jan 01 00:00:02 1970 +0000 + summary: b3 + + $ hg log -r 'destination(a53251cdf717)' + changeset: 7:ffd6818a3975 + user: test + date: Thu Jan 01 00:00:02 1970 +0000 + summary: b3 + + changeset: 9:502236fa76bb + branch: b4 + tag: tip + user: test + date: Thu Jan 01 00:00:02 1970 +0000 + summary: b3 + + +test subset parameter in reverse order + $ hg log -r 'reverse(all()) and destination(a53251cdf717)' + changeset: 9:502236fa76bb + branch: b4 + tag: tip + user: test + date: Thu Jan 01 00:00:02 1970 +0000 + summary: b3 + + changeset: 7:ffd6818a3975 + user: test + date: Thu Jan 01 00:00:02 1970 +0000 + summary: b3 + + +back to the original dir + $ cd ../rebase + rollback the transplant $ hg rollback repository tip rolled back to revision 4 (undo transplant)