martinvonz / jj

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

FR: Ability to specify tree for first commit of `jj split` #4179

Open mlcui-corp opened 1 month ago

mlcui-corp commented 1 month ago

Is your feature request related to a problem? Please describe.

Example 1: A user is working on a change...

@ z: old tree
o main
|

...but they forgot to jj new and accidentally put their changes into @!

@ z: new tree
o main
|

The user wants to get to the following log:

@ y: new tree
o z: old tree 
o main
|

Example 2: A user wants to split a change...

@ z: tree one
o main
|

...but it requires modifications are too hard to make in a diff editor, or they want to make some modifications and run some tests on those changes.

The user creates a new change on top, undoing some of their changes to get to their desired state:

@ y: tree two
o z: tree one
o main
|

The user wants to get to the following log:

o z: tree one
@ x: tree two
o main
|

Example 3: Same as example 2, but instead of creating a new change on top, the user duplicates z:

@ y: tree two
| o z: tree one
|/
o main
|

Describe the solution you'd like

An argument for jj split which, similar to jj restore --from, allows users to specify a revision to "restore the tree from" in the first commit.

Example 1 becomes jj split -r z --restore_from old_commit_id. Example 2 becomes jj split -r z --restore_from y. Example 3 becomes jj split -r z --restore_from y (the same as Example 2).

Describe alternatives you've considered

Additional context

Example 2 was briefly discussed on Discord. Currently, this involves either jj backout -r y && jj squash -r y, or using jj restore --from with other commands.

ilyagr commented 1 month ago

Funny you should say that. PTAL #4097.

It seems to me that is exactly me predicting your suggestion, but let me know if there's a difference I missed from not reading carefully.

Now I know there are 3 people who want it :)

Update: Thanks for examples 2 and 3, I haven't considered them before.

To clarify Example 2 a bit, I presume you are suggesting doing jj split -r z --from y.

mlcui-corp commented 2 days ago

Revisiting this request - I'm still not too certain whether this workflow is better suited to a jj rebase --preserve-tree. Example 1 could be achieved with jj duplicate old_commit_id, then jj rebase --preserve-tree -s z -d RESULT_OF_LAST_COMMAND.

Following https://github.com/martinvonz/jj/issues/3772#issuecomment-2143544784, I could possibly foresee something like jj rebase --preserve-tree -s z -d duplicate(old_commit_id), or jj rebase --preserve-tree -s old_commit_id -d duplicate(z, hide_orig=true) as well. Both are quite complicated for the common situation that people get themselves into, so I think having a jj split --restore-from might be worthwhile just for that specific situation.

Example 2 and Example 3 are definitely more suited for a jj rebase --preserve-tree command IMO.