FR: `jj linearize`
jj parallelize (https://docs.jj-vcs.dev/latest/cli-reference/#jj-parallelize):
Parallelize revisions by making them siblings
But sometimes I'd like to actually make revisions "linear"; i.e., give them a parent-child chain relationship. (For example, in repos where I only work by myself and push to main directly, I may have a bunch of revisions that are all good to be pushed, but of course I want to maintain linear history of main. So I need to manually arrange them to be a single chain before I can push main. This operation can also be useful for ensuring there are no conflicts when revisions are ordered in some way.) This can be achieved with multiple invocations of jj rebase, but does not scale well. It appears that jj arrange does not do well with (or just doesn't allow) moving revisions between "branches"; e.g., jj new 'trunk()'; jj new 'trunk()'; jj arrange 'trunk()::' does not let me make them parent-child.
I'm not sure if this is a good idea, so open to discussion. Running jj rebase is not that much trouble, and I don't do this a ton. But maybe it'd be nice to have a mirror operation of jj parallelize anyway?
Some thoughts:
- I don't know if this should be non-interactive. If I have commits A, B, and C and run
jj linearize A B C(assuming positional revsets), how wouldjjdecide the order?- I could imagine some
--orderflag similar tojj bookmark list --sort, but it feels not that useful since it could only operate on random metadata that jj knows about, such as committer timestamp or whatever, and the user might want to actually semantically order the revisions. - Another option could be "the revisions will be processed in the order given and each successive revision will be a child of the previous", but that doesn't really work well with actual revset expressions (
jj linearize 'A|B'), which are inherently sets and thus unordered. Topological order also is not deterministic (the implementation might be, but can't be assumed in general). - Yet another option is that it could take a
--stdinflag and accept a list of change IDs or commit IDs on stdin, which is then used as the ancestor -> descendant order. Then the user can script it, likejj log -G -r 'mutable()' -T 'commit_id ++ "\n"' | jj linearize --stdinor something (bad example because this does not use a user-defined order, but you get the point).
- I could imagine some
- The TUI that
jj arrangeuses could be nice, where all the given revisions are put in a single chain (with some arbitrary default ordering, like by committer timestamp), and the user reorders them as desired. A text buffer (likegit rebase -iorhg histedit) could also work, which might be better for bulk edits since many users have more line-editing capabilities in their editors. Maybe that could be an option too? - Conflicts are not really an issue, since this would run into the same "problems" as manual
jj rebasecommands. - This could also be super simple and accept no other flags other than the revisions, and then linearize them in a defined manner (such as topological sort). Then the user can use
jj arrangeafter to reorder them as they wish. I think this isn't that ideal since intermediate conflicts might show up between the steps, and distinct operations makes it harder tojj undo, but there's an argument to be made about CLI simplicity :)
Source: jj-vcs/jj