Re: [PATCH RFC 11/11] builtin/history: implement "split" subcommand
- From
Jean-Noël AVILA <jn.avila@free.fr>
- Date
- Aug 23, 2025, 16:37 UTC
- Message-ID
- <3298210.5fSG56mABF@cayenne>
- In-Reply-To
- <20250819-b4-pks-history-builtin-v1-11-9b77c32688fe@pks.im>
On Tuesday, 19 August 2025 12:56:07 CEST Patrick Steinhardt wrote:
Show 36 quoted lines
> It is quite a common use case that one wants to split up one commit into > multiple commits by moving parts of the changes of the original commit > out of it into a separate commit. This is quite an involved operation > though: > > 1. Identify the commit in question that is to be dropped. > > 2. Perform an interactive rebase on top of that commit's parent. > > 3. Modify the instruction sheet to "edit" the commit that is to be > split up. > > 4. Drop the commit via "git reset HEAD~". > > 5. Stage changes that should go into the first commit and commit it. > > 6. Stage changes that should go into the second commit and commit it. > > 7. Finalize the rebase. > > This is quite complex, and overall I would claim that most people who > are not experts in Git would struggle with this flow. > > Introduce a new "split" subcommand for git-history(1) to make this way > easier. All the user needs to do is to say `git history split $COMMIT`. > From hereon, Git asks the user which parts of the commit shall be moved > out into a separate commit and, once done, asks the user for the commit > message. Git then creates that split-out commit and applies the original > commit on top of it. > > Signed-off-by: Patrick Steinhardt <ps@pks.im> > --- > Documentation/git-history.adoc | 59 ++++++++ > builtin/history.c | 245 +++++++++++++++++++++++++++++++++ > t/meson.build | 1 + > t/t3452-history-split.sh | 304 ++++++++++++++++++++++++++++++++++++++
+++
Show 11 quoted lines
> 4 files changed, 609 insertions(+) > > diff --git a/Documentation/git-history.adoc b/Documentation/git-history.adoc > index 6e8b4e1326..f0f1f2a093 100644 > --- a/Documentation/git-history.adoc > +++ b/Documentation/git-history.adoc > @@ -10,6 +10,7 @@ SYNOPSIS > [synopsis] > git history drop [<options>] <revision> > git history reorder [<options>] <revision> --(before|after)=<revision> > +git history split [<options>] <revision> [--] [<pathspec>...]
I just realized that there are no other <options> available for the first two commands! So maybe simplify the synopsis for the time being.
The --message is specific to split, so maybe also cite is specifically here. I
> > DESCRIPTION > ----------- > @@ -47,6 +48,26 @@ reorder <revision> (--before=<revision>|--
after=<revision>)::
> commit. The commits must be related to one another and must be > reachable from the current `HEAD` commit. > > +split <revision> [--message=<message>] [--] [<pathspec>...]::
missing backticks. Also the order of options and <commit> are different from the general synopsis. Is this order allowed?
> + Interactively split up the commit into two commits by choosing
You can use the placeholder in this sentence: "Interactively split up <commit>..."
Show 10 quoted lines
> + hunks introduced by it that will be moved into the new split-out > + commit. These hunks will then be written into a new commit that > + becomes the parent of the previous commit. The original commit > + stays intact, except that its parent will be the newly split-out > + commit. > ++ > +The commit message of the new commit will be asked for by launching the > +configured editor. Authorship of the commit will be the same as for the > +original commit. > ++
I guess this only happens if --message is not passed?
> +If passed, _<pathspec>_ can be used to limit which changes shall be split
out
> +of the original commit. Files not matching any of the pathspecs will remain > +part of the original commit. For more details about the _<pathspec>_
syntax,
> +see the 'pathspec' entry.
You may have meant: + For more details, see the 'pathspec' entry in linkgit:gitglossary[7].
Show 51 quoted lines
> ++ > +It is invalid to select either all or no hunks, as that would lead to > +one of the commits becoming empty. > + > EXAMPLES > -------- > > @@ -88,6 +109,44 @@ f44a46e third > bf7438d first > ---------- > > +* Split a commit. > ++ > +---------- > +$ git log --stat --oneline > +3f81232 (HEAD -> main) original > + bar | 1 + > + foo | 1 + > + 2 files changed, 2 insertions(+) > + > +$ git history split HEAD --message="split-out commit" > +diff --git a/bar b/bar > +new file mode 100644 > +index 0000000..5716ca5 > +--- /dev/null > ++++ b/bar > +@@ -0,0 +1 @@ > ++bar > +(1/1) Stage addition [y,n,q,a,d,e,p,?]? y > + > +diff --git a/foo b/foo > +new file mode 100644 > +index 0000000..257cc56 > +--- /dev/null > ++++ b/foo > +@@ -0,0 +1 @@ > ++foo > +(1/1) Stage addition [y,n,q,a,d,e,p,?]? n > + > +$ git log --stat --oneline > +7cebe64 (HEAD -> main) original > + foo | 1 + > + 1 file changed, 1 insertion(+) > +d1582f3 split-out commit > + bar | 1 + > + 1 file changed, 1 insertion(+) > +---------- > + > + > CONFIGURATION > -------------