You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Is your feature request related to a problem? Please describe.
There's been a proliferation of flags added to various commands that create or rebase commits. For example, --insert-before/--insert-after should be added to many commands, but hasn't been yet. Rebasing is a core competency and reason to use jj. I think we should invest in a unified flexible design to control "rebase behavior" rather than add more flags.
Most commands that create or rebase commits could reuse some of these options, including:
jj abandon
jj commit
jj describe
jj duplicate
jj new
jj parallelize
jj rebase
jj split
jj squash
Describe the solution you'd like
Roughly speaking jj rebase --dest X (and similar for other commands) should accept an expression representing "rebase behavior" (and also accept a revset for backward compatibility and the common case).
As an example, suppose you're using a "mega-merge" strategy. You have a bunch of commits in X that you want to insert before the mega-merge commit as standalone commits. You want to take this opportunity to also write some helpful messages for each commit. If this wouldn't merge cleanly, then you want to abort the operation rather than produce conflicts. An example invocation might look like this:
$ jj rebase -r X -d 'behavior(after=trunk(), before=@, topology="horizontal", empty="keep", message="prompt", merge="abort")'
However, if you have a commit in X and you need to split it as part of doing the mega-merge, then maybe you'll issue an invocation like this:
To demonstrate the general applicability of this design, see the issues linked below.
Given a commit set X that's being rebased, the following are some relevant axes to control rebase behavior:
Location: one or more of the following:
"after" revset Y: commit set X is rebased to be children of Y. This is the current behavior of jj rebase -r X -d Y.
"before" revset Z: after rebasing the commit set, the commits in Z will be rebased as children of it. This is the current behavior of jj rebase -r X --insert-before Z.
related: "replace" revset W: abandon the commits in W and behave as if W's parents were provided for after and W's children were provided for before.
"preserve": Default. If a commit in X was an ancestor of another commit in X before the rebase, then it remains so after the rebase. This is the current behavior of jj rebase.
"horizontal": Commits in X are rebased individually to be siblings. This is the behavior of jj parallelize.
"vertical": Commits in X are rebased to be a chain of children (in an arbitrary order). No current equivalent.
"drop": Default. Drop any commits in X that are empty.
"preserve": Preserve all commits in X, even those that are empty.
"keep": Drop commits in X that were non-empty before the rebase but empty after the rebase. (Should this be the new default?) Related to --keep-emptied.
related: "deduplicate": Determine if any commits have already been applied via patch ID semantics.
"preserve": Default. Allow conflicts to be generated and recorded.
"reparent": Set the parents of commits in X without actually doing "rebasing" (patch application).
"abort": If conflicts would be generated, instead abort the operation.
"ours"/"theirs": When conflicts are generated, use one of the sides to resolve them. (There are several additional aspects that can be configured here.)
Not sure about this one, but there might be generally-relevant configuration. If we adopt topics instead of bookmarks, then it might also make sense to configure topic behavior here.
Preserve current behavior. Add flags to each command that might need them. I think it's extra work overall and results in a less flexible/coherent system. However, command-line flags are generally more discoverable/accessible than the revset language.
Additional context
This also covers some use-cases for #3814, but is not a complete substitute.
The text was updated successfully, but these errors were encountered:
This seems like a lot of options. Hopefully, all will be considered in the context of undo and of simultaneous access (scripts in two windows).
I don't think we need to do anything special to support undo for this design. I believe we basically snapshot the repo before and after the operation, without regard to which operations actually ran. Simultaneous modifications are a problem, but not specific to this either.
Is your feature request related to a problem? Please describe.
There's been a proliferation of flags added to various commands that create or rebase commits. For example,
--insert-before
/--insert-after
should be added to many commands, but hasn't been yet. Rebasing is a core competency and reason to use jj. I think we should invest in a unified flexible design to control "rebase behavior" rather than add more flags.Most commands that create or rebase commits could reuse some of these options, including:
jj abandon
jj commit
jj describe
jj duplicate
jj new
jj parallelize
jj rebase
jj split
jj squash
Describe the solution you'd like
Roughly speaking
jj rebase --dest X
(and similar for other commands) should accept an expression representing "rebase behavior" (and also accept a revset for backward compatibility and the common case).As an example, suppose you're using a "mega-merge" strategy. You have a bunch of commits in
X
that you want to insert before the mega-merge commit as standalone commits. You want to take this opportunity to also write some helpful messages for each commit. If this wouldn't merge cleanly, then you want to abort the operation rather than produce conflicts. An example invocation might look like this:$ jj rebase -r X -d 'behavior(after=trunk(), before=@, topology="horizontal", empty="keep", message="prompt", merge="abort")'
However, if you have a commit in
X
and you need to split it as part of doing the mega-merge, then maybe you'll issue an invocation like this:$ jj split -r X -d 'behavior(after=trunk(), before=@, topology="horizontal", message="prompt", merge="ours")'
To demonstrate the general applicability of this design, see the issues linked below.
Given a commit set
X
that's being rebased, the following are some relevant axes to control rebase behavior:Y
: commit setX
is rebased to be children ofY
. This is the current behavior ofjj rebase -r X -d Y
.Z
: after rebasing the commit set, the commits inZ
will be rebased as children of it. This is the current behavior ofjj rebase -r X --insert-before Z
.W
: abandon the commits inW
and behave as ifW
's parents were provided forafter
andW
's children were provided forbefore
.jj rebase -r
should be able to rebase a commit onto its descendant, insert commits before or after another commit (now AKA better tools for reordering commits part 1) #1188, FR:reorder
AKAhistedit
command (better tools for reordering commits part 2) #1531, FR:jj duplicate -d
#3518, FR: Add--insert-before
and--insert-after
tosplit
,new
,duplicate
, etc. #3772, FR: when abandoning the working copy, use the same children for the new change #4468X
was an ancestor of another commit inX
before the rebase, then it remains so after the rebase. This is the current behavior ofjj rebase
.X
are rebased individually to be siblings. This is the behavior ofjj parallelize
.X
are rebased to be a chain of children (in an arbitrary order). No current equivalent.jj parallelize
command #1079, FR:jj split --horizontal/--siblings/--sideways
#2274,jj
unexpectedly simplifies ancestry when rewriting a commit that is both a direct child and an indirect descendant of another commit #2600, Don't introduce new redundant ancestor merges when auto-rebasing #4351Y
: Set the signature value toY
. Some current equivalents.git commit
's--author <id>
option injj {desc,commit}
#4170Y
: For each commit inX
, set the message to string (or template)Y
.X
.jj split
ergonomics #1155, FR: Improvejj backout
generated description #2669, FR:jj split --message
, likejj commit --message
#3060X
that are empty.X
, even those that are empty.X
that were non-empty before the rebase but empty after the rebase. (Should this be the new default?) Related to--keep-emptied
.jj sync
command #1039, FR: add "signed-off-by" line #1399, FR:--allow-empty
forsquash
andunsquash
. #1406, FR:git commit --verbose
equivalent forjj describe
#1946, FR: better detection of commits that were made empty #2979, FR: support for bulk-editing of commit descriptions #3120,rebase --skip-empty
on merge commits doesn't remove deleted parents #3766, FR: Implement jj git sync #4641, FR: Configuration setting to use--keep-emptied
by default when squashing #4668Y
: Set the change ID toY
explicitly. No current equivalent.X
without actually doing "rebasing" (patch application).jj fix -r X
to fixX
with minimal effects onX..
#3805, Consider not partially resolving merged trees #4152--advance-branches
flag forjj commit
#2338, What shouldjj split
do with branches? #3419, FR: Stop branches from sliding back onjj abandon
, delete them instead #3505, FR: Supportjj fix -r X
to fixX
with minimal effects onX..
#3805Describe alternatives you've considered
Additional context
This also covers some use-cases for #3814, but is not a complete substitute.
The text was updated successfully, but these errors were encountered: