martinvonz / jj

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

FR: revset syntax to resolve an expression at an old operation #1283

Closed ilyagr closed 1 month ago

ilyagr commented 1 year ago

It would be nice to have something like xyz#a5b to represent the commit that the change xyz was at operation a5b. So, one could do jj log --at-op a5b and follow that up with jj restore --from xyz#a5b.

martinvonz commented 1 year ago

xyz@a5b is another option, but then we'd probably need to replace the use of @ for branch@remote syntax.

martinvonz commented 1 year ago

If we choose @ for the operator, we'd probably also want to remove it from the allowed characters in an identifier: https://github.com/martinvonz/jj/blob/92f9fe5a1b12035e52866fd8abcae60b9e86bea9/lib/src/revset.pest#L15-L19

martinvonz commented 1 year ago

But since we use @ for the working-copy commit, that's doesn't seem like a good idea :) So never mind, # seems much better

ilyagr commented 1 year ago

I also don't particularly like #, but I haven't thought of a better option.

One ambiguity is whether @#abc6 should be the commit that was current at abc6 or the commit with the same change id as @ at abc6. I would probably want the former, but that would require exceptional treatment for revsets that include @.

Update On Discord, Martin suggested that the revset be expanded by first loading operation abc6 and then computing @ in that context. That would solve this problem.

ilyagr commented 1 year ago

This would also be quite useful for branches.

yuja commented 1 year ago

So expr#op will be the operator to evaluate expr within the environment at op. If we can't find a better operator character, we can try with a function syntax first.

ilyagr commented 3 months ago

A related FR would be a "universal reflog", a way to see or use the "previous value" of something like "main@origin" as something like "main@origin#1". This would ignore any past operations that didn't change the value of "main@origin". (Of course, we'd need a different symbol or syntax if main@origin#1 treats 1 as an operation id. Or, perhaps we could use one of ^% for op id. % makes the most sense to me at the moment, not sure why).

I think filtering by revset could already be implemented as an option to jj op log (similarly to filtering by file for jj log), but that's a separate feature and would be more awkward to use.