martinvonz / jj

A Git-compatible VCS that is both simple and powerful
https://martinvonz.github.io/jj/
Apache License 2.0
8.16k stars 272 forks source link

FR: Revset expression for nth parent/child #3337

Open scott2000 opened 5 months ago

scott2000 commented 5 months ago

Is your feature request related to a problem? Please describe. In Git, I'm used to doing commands like git diff HEAD~3 to see the changes from the most recent 3 commits. However, there seems to be no easy way to do this with jj. Either I have to look at the log to find the change ID prefix like jj diff --from v, or I have to use multiple minus signs like jj diff --from @---. The same sort of issue might happen with +, but just less commonly.

Describe the solution you'd like I'm not sure about the syntax, but something like @-3 to mean @--- would be nice. However it seems like it was already discussed in #46, and it sounds like there were some concerns about ambiguity with branch names containing hyphens. Perhaps it could use braces for disambiguation similar to Git's x@{N} syntax, so x-{N} would mean the Nth level of parents of x, but without braces x-N would be a regular branch name.

Describe alternatives you've considered If it isn't possible to have it be an operator, it might be possible to add it to the children and parents revset functions. For instance, children(x[, count]) and parents(x[, count]). This would have the advantage of matching with ancestors(x[, depth]), but it is a bit clunky to write.

yuja commented 5 months ago

Perhaps it could use braces for disambiguation similar to Git's x@{N} syntax, so x-{N} would mean the Nth level of parents of x, but without braces x-N would be a regular branch name.

Alternatively, we could add a subscript operator like x{-N} or x[-N] meaning Nth generation back/forward from x. It can be easily parsed, but it might be hard to extend if we want other kind of counting system (something like Nth in the current stack.)

(FWIW, I would repeat - because - is easier to type than { or '['.)

children(x[, count]) and parents(x[, count]). This would have the advantage of matching with ancestors(x[, depth]), but it is a bit clunky to write.

Extending these functions also makes sense. ancestors() can have start_depth, stop_depth or depth_count, depth_offset, but it's more verbose.

scott2000 commented 2 months ago

Just wanted to add a workaround here:

revset-aliases."p(n)" = "roots(@ | ancestors(@-, n))"

p(0) = @, p(1) = @-, p(3) = @---, etc.