Subject: [PATCH v5 0/5] doc: git-rebase: clarify DESCRIPTION section

From: "Julia Evans via GitGitGadget" <[email-masked]>
Date: Mon, 11 Aug 2025 20:12:02 +0000

* Add a note about how you can use git rebase to reorder or combine commits
 * Convert the explanation of how rebase works to an ordered list, make it
   more accurate (include how duplicate commits are removed), and remove the
   diagram showing how duplicate commits are removed. I'm happy to bring the
   diagram back if folks think it's important, but I felt like it made the
   section end in an awkward way and I'm not sure that "git rebase removes
   duplicate commits" really needs a diagram to explain it.

Julia Evans (5):
  doc: git-rebase: start with an example
  doc: git rebase: dedup merge conflict discussion
  doc: git rebase: clarify arguments syntax
  doc: git-rebase: move --onto explanation down
  doc: git-rebase: update discussion of internals

 Documentation/git-rebase.adoc | 305 ++++++++++++++++------------------
 1 file changed, 139 insertions(+), 166 deletions(-)

base-commit: 2c2ba49d55ff26c1082b8137b1ec5eeccb4337d1
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1949%2Fjvns%2Fclarify-rebase-v5
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1949/jvns/clarify-rebase-v5
Pull-Request: https://github.com/gitgitgadget/git/pull/1949

Range-diff vs v4:

 1:  07a4bdb7ce5 ! 1:  c2f2e05078f doc: git-rebase: start with an example
     @@ Metadata
       ## Commit message ##
          doc: git-rebase: start with an example
      
     -    Start with an example that mirrors the example in the `git-merge` man
     -    page, to make it easier for folks to understand the difference between a
     -    rebase and a merge.
     +    - Start with an example that mirrors the example in the `git-merge` man
     +      page, to make it easier for folks to understand the difference between
     +      a rebase and a merge.
     +    - Mention that rebase can combine or reorder commits
      
          Signed-off-by: Julia Evans <[email-masked]>
      
     @@ Documentation/git-rebase.adoc: SYNOPSIS
      +                 /
      +    D---E---F---G master
      +------------
     ++
     ++You can also use `git rebase` to reorder or combine commits: see INTERACTIVE
     ++MODE below for how to do that.
      +
       If `<branch>` is specified, `git rebase` will perform an automatic
       `git switch <branch>` before doing anything else.  Otherwise
 2:  061790686b9 ! 2:  5459b7ff560 doc: git rebase: dedup merge conflict discussion
     @@ Commit message
      
       ## Documentation/git-rebase.adoc ##
      @@ Documentation/git-rebase.adoc: shortcut for `git checkout topic && git rebase master`.
     -     D---E---F---G master
     - ------------
     + You can also use `git rebase` to reorder or combine commits: see INTERACTIVE
     + MODE below for how to do that.
       
      +If there is a merge conflict during this process, `git rebase` will stop at the
      +first problematic commit and leave conflict markers. If this happens, you can do
     @@ Documentation/git-rebase.adoc: shortcut for `git checkout topic && git rebase ma
      +3. Skip the commit that caused the merge conflict with
      +
      +   git rebase --skip
     -+
      +
       If `<branch>` is specified, `git rebase` will perform an automatic
       `git switch <branch>` before doing anything else.  Otherwise
 3:  fe9e161a51b ! 3:  948c205f1e6 doc: git rebase: clarify arguments syntax
     @@ Documentation/git-rebase.adoc: one of these things:
       
          git rebase --skip
       
     --
      -If `<branch>` is specified, `git rebase` will perform an automatic
      -`git switch <branch>` before doing anything else.  Otherwise
      -it remains on the current branch.
 4:  b37ebc8389d = 4:  e229b9fccb2 doc: git-rebase: move --onto explanation down
 5:  105a65e6e71 ! 5:  5ab235b067b doc: git-rebase: update discussion of internals
     @@ Commit message
          - make it clearer that we're talking about a multistep process
          - give a more technically accurate description how rebase works with the
            merge backend.
     -    - delete a duplicate explanation of how git rebase skips commits with
     -      the same textual changes (it's explained in more detail a few lines
     -      further down)
     +    - 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
     @@ Documentation/git-rebase.adoc: linkgit:git-config[1] for details) and the `--for
      -to point at the tip of the branch before the reset.
      +Here is a more detailed description of what `git rebase <upstream>` does:
      +
     -+First, it makes 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.
     -+
     -+Then it checks out `<upstream>` (or `<newbase>` if the `--onto` option was
     -+supplied) with the equivalent of `git switch --detach <upstream>`.
     -+
     -+Then it replays 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.
     -+
     -+Finally, it updates your branch to point to the final commit with the equivalent
     -+of `git switch -C <branch>`.
     ++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.
     ++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.
     ++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>`.
       
       [NOTE]
     -+`ORIG_HEAD` is set to point at the tip of the branch before the rebase.
     - `ORIG_HEAD` is not guaranteed to still point to the previous branch tip
     - at the end of the rebase if other commands that write that pseudo-ref
     - (e.g. `git reset`) are used during the rebase. The previous branch tip,
     - however, is accessible using the reflog of the current branch
     - (i.e. `@{1}`, see linkgit:gitrevisions[7]).
     - 
     +-`ORIG_HEAD` is not guaranteed to still point to the previous branch tip
     +-at the end of the rebase if other commands that write that pseudo-ref
     +-(e.g. `git reset`) are used during the rebase. The previous branch tip,
     +-however, is accessible using the reflog of the current branch
     +-(i.e. `@{1}`, see linkgit:gitrevisions[7]).
     +-
      -The commits that were previously saved into the temporary area are
      -then reapplied to the current branch, one by one, in order. Note that
      -any commits in `HEAD` which introduce the same textual changes as a commit
      -in `HEAD..<upstream>` are omitted (i.e., a patch already accepted upstream
      -with a different commit message or timestamp will be skipped).
      -
     - If the upstream branch already contains a change you have made (e.g.,
     - because you mailed a patch which was applied upstream), then that commit
     - will be skipped and warnings will be issued (if the 'merge' backend is
     +-If the upstream branch already contains a change you have made (e.g.,
     +-because you mailed a patch which was applied upstream), then that commit
     +-will be skipped and warnings will be issued (if the 'merge' backend is
     +-used).  For example, running `git rebase master` on the following
     +-history (in which `A'` and `A` introduce the same set of changes, but
     +-have different committer information):
     +-
     +-------------
     +-          A---B---C topic
     +-         /
     +-    D---E---A'---F master
     +-------------
     +-
     +-will result in:
     +-
     +-------------
     +-                   B'---C' topic
     +-                  /
     +-    D---E---A'---F master
     +-------------
     ++When starting the rebase, `ORIG_HEAD` is set to point to the commit at the tip
     ++of the to-be-rebased branch. However, `ORIG_HEAD` is not guaranteed to still
     ++point to that commit at the end of the rebase if other commands that change
     ++`ORIG_HEAD` (like `git reset`) are used during the rebase. The previous branch
     ++tip, however, is accessible using the reflog of the current branch (i.e. `@{1}`,
     ++see linkgit:gitrevisions[7].
     + 
     + MODE OPTIONS
     + ------------

-- 
gitgitgadget