Subject: Re: [PATCH v5 5/5] doc: git-rebase: update discussion of internals

From: Junio C Hamano <[email-masked]>
Date: Mon, 11 Aug 2025 14:14:23 -0700

"Julia Evans via GitGitGadget" <[email-masked]> writes:

> From: Julia Evans <[email-masked]>
>
> - make it clearer that we're talking about a multistep process
> - give a more technically accurate description how rebase works with the
>   merge backend.
> - condense the explanation of how git rebase skips commits with the same
>   textual changes into a single bullet point and remove the explanatory
>   diagram. Lots of things which are more complicated are already being
>   explained without a diagram.
> - remove the explanation of how exactly `--fork-point` and `--root`
>   work since that information is in the OPTIONS section
> - put all discussion of `ORIG_HEAD` inside the note
>
> Signed-off-by: Julia Evans <[email-masked]>
> ---
>  Documentation/git-rebase.adoc | 66 ++++++++++++-----------------------
>  1 file changed, 23 insertions(+), 43 deletions(-)
>
> diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc
> index 750f5e67e4c3..b4e5519d2839 100644
> --- a/Documentation/git-rebase.adoc
> +++ b/Documentation/git-rebase.adoc
> @@ -68,51 +68,31 @@ linkgit:git-config[1] for details) and the `--fork-point` option is
>  assumed.  If you are currently not on any branch or if the current
>  branch does not have a configured upstream, the rebase will abort.
>  
> -All changes made by commits in the current branch but that are not
> -in `<upstream>` are saved to a temporary area.  This is the same set
> -of commits that would be shown by `git log <upstream>..HEAD`; or by
> -`git log 'fork_point'..HEAD`, if `--fork-point` is active (see the
> -description on `--fork-point` below); or by `git log HEAD`, if the
> -`--root` option is specified.
> -
> -The current branch is reset to `<upstream>` or `<newbase>` if the
> -`--onto` option was supplied.  This has the exact same effect as
> -`git reset --hard <upstream>` (or `<newbase>`). `ORIG_HEAD` is set
> -to point at the tip of the branch before the reset.

> +Here is a more detailed description of what `git rebase <upstream>` does:

Were there a sketchy description given elsewhere already?  I
personally feel that giving too much details here would not
necessarily help readers' understanding.  I'd prefer to see an
introduction read more like "The command conceptually does these
things in the following order", and leave the level of description
also to match that introduction.  It may be just me, but when
somebody says "here is a detailed description", I would expect it to
contain little or no white lies mixed in, even for simplicity.

But of course others may have different opinions ;-)

> +1. Make a list of all commits in the current branch that are not in
> +   `<upstream>`. This is the same set of commits that would be shown by `git log
> +   <upstream>..HEAD`. You can use `--fork-point` or `--root` to change how this
> +   list of commits is constructed.

Didn't somebody mention "git log --cherry-pick <upstream>..HEAD"?
If omission of it is for simplicity, that is fine, but that is
another reason why we do not want to say "more detaild description".

Also, shouldn't there be step #0 that says "If the <branch> to rebase
is given, check out that branch and make it current", for the HEAD
in this description to work correctly?

> +2. Check whether any of those commits are duplicates of commits already
> +   in `<upstream>`, remove them from the list, and print out a warning about
> +   each removed commit. You can use `--reapply-cherry-picks` to include
> +   duplicate commits.

This is done as part of #1 above as part of a single invocation of
revision walk (i.e. a loop in sequencer.c:sequencer_make_script()
that calls get_revision() repeatedly).

> +3. Check out `<upstream>` (or `<newbase>` if the `--onto` option was
> +   supplied) with the equivalent of `git checkout --detach <upstream>`.
> +4. Replay the commits, one by one, in order. This is similar to running
> +   `git cherry-pick <commit>` for each commit. See REBASING MERGES for how merges
> +   are handled.
> +5. Update your branch to point to the final commit with the equivalent
> +   of `git switch -C <branch>`.

In step #3, you switched to <upstream> with "git checkout"; here you
use "git switch".  Uninitiated readers would wonder what criteria
were used to decide which one among these two different commands to
use in steps #3 and #5, even though either would work fine.  Because
this page is not where readers come to learn about the equivalence
of these two commands that are not essential to learning "git
rebase", it is better, so once you started with "git checkout", to
stick to it throughout to reduce the mental burden to first-time
learners.

Thanks.