Git's Triple-Dot as a jj Revset
While working on a repo that has a lot of divergent then merged branches, I was reviewing a merge request on Github. I wanted to take a look at the changes in more detail from the terminal, but found that I couldn’t quite get the same diff.
Github’s diff view is based on main...feature
, where we are merging feature
into main
. What this actually means is that we take a diff from the latest common commit between the two branches and the feature branches. I typically do such diffs using the equivalent of main..feature
, but if main
has been merged in part way through the feature
, this is not quite right.
Getting the equivalent base commit to ...
in jj
’s revset syntax is pretty simple: heads(::main & ::feature)
.
Breaking that down
::main & ::feature
<= intersection of all commits on main
and feature
heads()
<= Filter to only commits without descendants (leaves)
heads(::main & ::feature)
<= Last shared commit(s)
Most of the time, you will only have one commit from this and can use it as a base for the diff:
jj diff --from 'heads(::main & ::feature)' --to feature
The exception is when we have “branched” using a “merge” (the first commit that deviated from your trunk branch has two parents, both of which are on the trunk branch). That is kind of odd and I have not encountered that in practice yet (though I’m sure there will be genuine examples out there!).