Having two branches, how can I find the latest revision(s) where the two branches were merged? Is there a standard Mercurial command to do that?
This is the same as ques
If you have more than two branches then you have to add an additional filter to Lazy Badger's answer, because children() might give you also children that are not in your branches.
hg log -r "children(ancestor(default, Cleanup)) and merge() and branch(default|Cleanup)" --template "{rev}\n"
other o---o-----m1---o
/
default o---o---a---b---o
\
another o---o-----m2---o
ancestor(default, other) == a
children(ancestor(default, other)) == (m1,b,m2)
children(ancestor(default, other)) and merge() == (m1,m2)
children(ancestor(default, other)) and merge() and branch(default, other) == m1
You can rewrite this query to:
Let's assume you have two branches, identified by R1
and R2
, be it the name of the branches or the revision number or hash of a changeset in each, or whatnot.
Then you can find the changeset you're looking for as:
hg log --rev "ancestor(R1,R2)"
hg log -r "children(ancestor(default, Cleanup)) and merge()" --template "{rev}\n"
is latest merge for default and Cleanup branches (polished version of Tim Henigan's answer).
Just for the posterity this is not right in the case the left branch has not been merged with the right branch, but the left branch has lately been merged into right.
The correct solution is:
last(parents((ancestors('{left_branch}') and branch('{left_branch}') and merge())) and branch({right_branch}))
hg log -r "last(ancestors(target) & branch(source))"
This gives you the least common ancestor of target and source branch ON source branch.
source o---a---o---m2---o
\ /
intermediate o--o--m1---b---o
\
target o---o------------m3---o
The least common ancestor of source and target branch in this example would be b, but b is not on the source branch, we therefore want to get a back.
To get b back you can use the solution of Lasse:
hg log -r "ancestor(source, target)"
I often want to know the latest "default" revision in some task branch and I don't care if my task branch was directly merged with default or via some intermediate path.
You can find all the merges from a source branch into a destination branch with this revset query:
children(p2(::DESTINATION and merge()) and branch(SOURCE)) and branch(DESTINATION)
::DESTINATION and merge()
gets all merges in the destination branch. p2(set)
returns the second parent of each merge, which is always the changeset on the source branch which was merged into the destination branchand branch(SOURCE)
filters all those merges into just those that came from the source branch.children(set)
returns all the children of p2()
, one of which is the merge we're looking forand branch(DESTINATION)
filters the children of p2()
to just show changesets on the destination branch, which, it just so happens, are the merges we're looking for.So, to get the last merge from source into destination, wrap the above query with the max(set)
query. So the final command would be:
max(children(p2(::DESTINATION and merge()) and branch(SOURCE)) and branch(DESTINATION))