FR: split: keep change ID and bookmarks together and add CLI flag to choose the successor commit
Is your feature request related to a problem? Please describe.
This feature request supersedes #10028. It proposes a subset of the functionality proposed there.
When jj split divides one commit into two, it currently moves the original change ID to the selected changes (the first/parent commit) and leaves the original bookmarks on the remaining changes (the second/child commit).
Splitting a commit's identity across the two resulting commits is confusing and causes unexpected behavior. Furthermore, neither resulting commit gets both the change ID and bookmarks, as most users would expect.
There are cases where the user would want the change ID and bookmarks (“the identity”) to go to the commit with the remaining changes, and cases where the user would want the identity to go to the commit with the selected changes.
- Placing the identity with the remaining changes (the child commit) is desired when splitting a refactoring commit out from a feature commit while intending to open or update a single PR with both commits.
- Placing the identity with the selected changes (the parent commit) is desired when splitting a commit in a stacked-diff workflow (such as Gerrit or Critique, where 1 commit = 1 CL) or when splitting two logically independent features into separate PRs.
Describe the solution you'd like
Keep change ID and bookmarks coupled: The commit that gets the original change ID will always also get the original commit's bookmarks.
Default behavior: By default, the commit containing the user's remaining changes (the child commit in a sequential split) will retain the original change ID and bookmarks (matching the behavior of jj split -B and https://github.com/jj-vcs/jj/pull/6466).
CLI flag to select successor: Introduce a CLI flag to choose which commit retains the original change ID and bookmarks. Specifically:
--identity=remaining(default): Remaining/child commit retains identity and bookmarks.--identity=selected: Selected/parent commit retains identity and bookmarks.
Delete split.legacy-bookmark-behavior: The config setting split.legacy-bookmark-behavior will simply be deleted. This setting was never documented and this FR proposes no new config setting to which the old setting can be migrated. ConfigMigrationRule::custom will be used to tell users to use the new CLI flag instead.
Describe alternatives you've considered
Flag naming & syntax:
--successor=<selected|remaining>: I personally prefer the term “successor” to “identity”, but I think many users confuse “successor” with “descendant”, so I chose--identityfor clarity.--keep-selected/--keep-remaining: This is a bit shorter than--identity, but the meaning is not clear from the flag name.--stack/--stacked: Focuses on user workflow intent ("stack a new follow-up change on top while keeping the current commit's identity intact"). While intuitive for some users, it has the trade-off of potentially overloading the term "stack" (since both split outcomes produce a topological stack of commits), it lacks a natural inverse flag, and many users of stacked diff workflows are not familiar with the term.--evict: Historical name discussed in #3419 to indicate that selected changes are "evicted" into a new commit while the original commit retains identity. While descriptive in some contexts, it can be confusing jargon for newer users.--parent/--childor--first/--last: Positional naming.selected/remainingwas preferred in past discussions because it explicitly describes the diff-selection action rather than graph topology.
Config setting: We could introduce a config setting for the value of --identity. This is omitted from this FR based on discussion in #10028.
Implementation via move flags: It is not possible to use move flags to reproduce the behavior of --identity. See detailed analysis.
Additional context Superseded FR:
- #10028
- #10029
Other past discussions about jj split's choice of successor:
- #3419
- #6458
- #6466
Source: jj-vcs/jj