split: implement -A/-B/-d flags
See the comments in the commit descriptions.
The last two commits implement jj --parallel -r x as jj split -r x -A x- -B x+ as discussed in #3419, but I'm not sure to see the point, except to document --parallel as equivalent to -A x- -B x+ (or -d x- if x has no descendant). I'm including them here to continue the discussion.
Still some tests to implement, but some early feedback would be appreciated!
Checklist
If applicable:
- [x] I have updated
CHANGELOG.md - [ ] I have updated the documentation (README.md, docs/, demos/)
- [ ] I have updated the config schema (cli/src/config-schema.json)
- [x] I have added tests to cover my changes
(non-blocking)
The 'first commit / part' (with the selected changes to be split out) can now go anywhere in the commit tree, including after the 'second commit / part'. While historically the names made sense because of the parent-child relationship (the 'first commit' would always be the parent of the 'second commit' and therefore come before the 'second commit'), it may make sense to refer to these two commits with more meaningful names in the CLI output, docs and elsewhere.
Quoting https://github.com/jj-vcs/jj/pull/6458#discussion_r2074211895 by @martinvonz:
"the split commit" is not clear to me. It's pretty clear once you're read the next sentence, but I like the phrasing you used in the commit description and in the changelog (i.e. "the commit with the selected changes")
My suggestion is to replace 'first commit / part' and 'second commit / part' with 'commit with selected changes' and 'commit with remaining changes' consistently (or 'revision with…'?). For example, if qpvuntsm is the revision containing the changes being split out, then the CLI output would be:
Selected changes: qpvuntsm c002c01e fix in file1
Remaining changes: kkmpptxz 0841f981 my feature
An alternative is to rename 'second commit' to 'source commit', as in the 'source' of the split operation. But then renaming 'first commit' to 'destination commit' would be confusing, since this collides with the commit referenced by the -d/--destination flag if used (which would actually become the parent of the 'destination commit').
For example, if
qpvuntsmis the revision containing the changes being split out, then the CLI output would be:Selected changes: qpvuntsm c002c01e fix in file1 Remaining changes: kkmpptxz 0841f981 my feature
I like this output — it's very clear IMO.
Just want to bring up a consideration that @ilyagr raised about these flags a while back that I think hasn’t been resurfaced since then: it’s a little unclear how the UI should work with these flags when using external diff editors. With the built‐in editor, it’s very obvious: you’re selecting hunks that get placed in a new commit on top of the selected destination. But with other diff editors, it’s a little weirder, since you’re constructing a state that immediately gets rebased – and indeed that rebase can result in conflicts (even with the built‐in editor). Arguably you would want the base to be the destination commit and you move hunks selectively from the source commit – that way you’re constructing the actual resulting tree directly and can avoid creating conflicts – but I think it’s not clear how we would achieve that without making the UI with the built‐in editor weird.
This is not intended as a blocking comment of any kind but just as a note that we should try this out with external diff editors and see what seems to make sense. Possibly we could have a per‐editor flag for how it should act, even.
I've created #6509 to rename first/second commit in selected/remaining changes