jj icon indicating copy to clipboard operation
jj copied to clipboard

FR: Specify multiple revisions in interdiff from/to

Open CGamesPlay opened this issue 3 weeks ago • 8 comments

Is your feature request related to a problem? Please describe. From https://github.com/jj-vcs/jj/discussions/8265. I've got a PR from a non-JJ git user in revisions a..b. The author rebases their commit and modifies the changes, giving a new range c..d. If a..b was just b and c..d was just d, then I could use jj interdiff --from b --to d to see what changed, however because they are ranges, I can no longer use interdiff.

Describe the solution you'd like It would be ideal if interdiff was able to accept entire revsets for both from/to arguments. That would transparently just squash both revsets into a single revision, and then proceed as normal.

Describe alternatives you've considered The workaround is to do the first step manually:

  1. Duplicate a..b & c..d
  2. Squash a..b2 into b2 and c..d2 into d2
  3. Run jj interdiff --from b2 --to d2
  4. Run jj abandon b2 d2 and jj edit to go back to where you were when you started.

This is a very manual process that needlessly changes the working copy revision several times and can't easily be scripted.

Additional context Add any other context or screenshots about the feature request here.

CGamesPlay avatar Dec 10 '25 05:12 CGamesPlay

Perhaps, the requested feature is the same as (or very close to) https://github.com/jj-vcs/jj/issues/498?

yuja avatar Dec 10 '25 11:12 yuja

It could be the same. The issue as written, copying git range-diff, it is definitely NOT what I am looking for. But the first comment is exactly what I am looking for, i.e. “generalized interdiff”.

CGamesPlay avatar Dec 10 '25 13:12 CGamesPlay

Given the way you've written a..b, doesn't that mean that a is an ancestor of b? I'm struggling to understand why you can't just interdiff or just diff the original b and d.

joyously avatar Dec 10 '25 15:12 joyously

I agree, it really should just work. Except it's multiple revisions, and it doesn't.

$ jj interdiff -f main..d6a3eb26  -t main..bookmark-13a9
Error: Revset `main..d6a3eb26` resolved to more than one revision

CGamesPlay avatar Dec 10 '25 15:12 CGamesPlay

I agree, it really should just work.

You are agreeing with yourself, not what I said. I'm asking about interdiff -f d6a3eb26 -t bookmark-13a9, which should encompass those ancestors. Or does that include too many ancestors? I'm thinking that for a review, it needs to work with everything existing.

joyously avatar Dec 10 '25 15:12 joyously

I'm asking about interdiff -f d6a3eb26 -t bookmark-13a9, which should encompass those ancestors. Or does that include too many ancestors?

Oh, my mistake. To answer directly: no, interdiff does not include the ancestors that I want to examine. I addressed that in my original message; perhaps a diagram would make this clearer:

a ──┬── q ── r ── s ── b
    │
    └── e ── f ── c ── w ── x ── y ── d

If I use interdiff --from b --to d, jj will internally rebase b onto y and compare with d, thereby dropping the changes in q, r, s, w, x, and y. What I actually want is to squash a..b into b2, then squash c..d into d2, and interdiff --from b2 --to d2 (as I mentioned in my original workaround).

CGamesPlay avatar Dec 10 '25 15:12 CGamesPlay

OK, and plain diff -f b -t d ? (I don't really get what interdiff does. It's a diff of diffs?)

joyously avatar Dec 10 '25 16:12 joyously

Plain diff -f b -t d would include changes in e and f, which is also not what I want (this is the point of interdiff: "excludes changes from other commits by temporarily rebasing --from onto --to's parents").

CGamesPlay avatar Dec 10 '25 16:12 CGamesPlay