* [PATCH 0/5] doc: git-rebase: clarify DESCRIPTION section
@ 2025-08-08 15:24 Julia Evans via GitGitGadget
2025-08-08 15:24 ` [PATCH 1/5] doc: git-rebase: start with an example Julia Evans via GitGitGadget
` (5 more replies)
0 siblings, 6 replies; 103+ messages in thread
From: Julia Evans via GitGitGadget @ 2025-08-08 15:24 UTC (permalink / raw)
To: git; +Cc: Julia Evans
This patch series reorganizes the DESCRIPTION section of the git rebase man
page. My goal is to make the page more accessible to git newcomers (who from
my experience have an extremely difficult time understanding git man pages)
while keeping the exact same information available for more advanced users.
This series:
* puts more commonly used information first (a basic example of a rebase
and "how to fix merge conflicts" are moved to before "how rebase modifies
ORIG_HEAD" and "what git rebase <upstream> <branch> does")
* removes duplication
* more closely parallels the git merge man page's structure by starting it
with the same example history
* moves the --onto examples to their own section
I've never contributed to Git before so I'd appreciate any pointers to past
discussions of Git's documentation philosophy or who the target audience for
Git documentation is.
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 | 287 ++++++++++++++++------------------
1 file changed, 139 insertions(+), 148 deletions(-)
base-commit: 64cbe5e2e8a7b0f92c780b210e602496bd5cad0f
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1949%2Fjvns%2Fclarify-rebase-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1949/jvns/clarify-rebase-v1
Pull-Request: https://github.com/gitgitgadget/git/pull/1949
--
gitgitgadget
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH 1/5] doc: git-rebase: start with an example
2025-08-08 15:24 [PATCH 0/5] doc: git-rebase: clarify DESCRIPTION section Julia Evans via GitGitGadget
@ 2025-08-08 15:24 ` Julia Evans via GitGitGadget
2025-08-08 16:30 ` Junio C Hamano
2025-08-08 15:24 ` [PATCH 2/5] doc: git rebase: dedup merge conflict discussion Julia Evans via GitGitGadget
` (4 subsequent siblings)
5 siblings, 1 reply; 103+ messages in thread
From: Julia Evans via GitGitGadget @ 2025-08-08 15:24 UTC (permalink / raw)
To: git; +Cc: Julia Evans, Julia Evans
From: Julia Evans <julia@jvns.ca>
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.
Signed-off-by: Julia Evans <julia@jvns.ca>
---
Documentation/git-rebase.adoc | 46 +++++++++++++++--------------------
1 file changed, 20 insertions(+), 26 deletions(-)
diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc
index 956d3048f5a6..fee73623990d 100644
--- a/Documentation/git-rebase.adoc
+++ b/Documentation/git-rebase.adoc
@@ -16,6 +16,26 @@ SYNOPSIS
DESCRIPTION
-----------
+Transplant a series of commits onto a different starting point.
+
+For example, assume the following history exists and the current branch is `topic`:
+
+------------
+ A---B---C topic
+ /
+ D---E---F---G master
+------------
+
+Then `git rebase master` will find all of the commits since `topic` diverged
+from `master` and copy the changes in each of those commits on top of the
+`master` branch.
+
+------------
+ A'--B'--C' topic
+ /
+ D---E---F---G master
+------------
+
If `<branch>` is specified, `git rebase` will perform an automatic
`git switch <branch>` before doing anything else. Otherwise
it remains on the current branch.
@@ -58,32 +78,6 @@ that caused the merge failure with `git rebase --skip`. To check out the
original `<branch>` and remove the `.git/rebase-apply` working files, use
the command `git rebase --abort` instead.
-Assume the following history exists and the current branch is "topic":
-
-------------
- A---B---C topic
- /
- D---E---F---G master
-------------
-
-From this point, the result of either of the following commands:
-
-
- git rebase master
- git rebase master topic
-
-would be:
-
-------------
- A'--B'--C' topic
- /
- D---E---F---G master
-------------
-
-*NOTE:* The latter form is just a short-hand of `git checkout topic`
-followed by `git rebase master`. When rebase exits `topic` will
-remain the checked-out branch.
-
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
--
gitgitgadget
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH 2/5] doc: git rebase: dedup merge conflict discussion
2025-08-08 15:24 [PATCH 0/5] doc: git-rebase: clarify DESCRIPTION section Julia Evans via GitGitGadget
2025-08-08 15:24 ` [PATCH 1/5] doc: git-rebase: start with an example Julia Evans via GitGitGadget
@ 2025-08-08 15:24 ` Julia Evans via GitGitGadget
2025-08-08 17:48 ` Junio C Hamano
2025-08-08 15:24 ` [PATCH 3/5] doc: git rebase: clarify arguments syntax Julia Evans via GitGitGadget
` (3 subsequent siblings)
5 siblings, 1 reply; 103+ messages in thread
From: Julia Evans via GitGitGadget @ 2025-08-08 15:24 UTC (permalink / raw)
To: git; +Cc: Julia Evans, Julia Evans
From: Julia Evans <julia@jvns.ca>
Previously there were two explanations, this combines them both into a
single explanation.
Signed-off-by: Julia Evans <julia@jvns.ca>
---
Documentation/git-rebase.adoc | 52 ++++++++++++++++-------------------
1 file changed, 23 insertions(+), 29 deletions(-)
diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc
index fee73623990d..3087e558b509 100644
--- a/Documentation/git-rebase.adoc
+++ b/Documentation/git-rebase.adoc
@@ -36,6 +36,29 @@ from `master` and copy the changes in each of those commits on top of the
D---E---F---G master
------------
+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:
+
+1. Resolve the conflict. You can use `git diff` to find the markers (<<<<<<)
+ and make edits to resolve the conflict. For each file you edit, you need to
+ tell Git that the conflict has been resolved. Typically this would be
+ done with
+
+ git add <filename>
+
+ You can then continue the rebasing process with
+
+ git rebase --continue
+
+2. Stop the `git rebase` and return your branch to its original state with
+
+ git rebase --abort
+
+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
it remains on the current branch.
@@ -71,13 +94,6 @@ 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).
-It is possible that a merge failure will prevent this process from being
-completely automatic. You will have to resolve any such merge failure
-and run `git rebase --continue`. Another option is to bypass the commit
-that caused the merge failure with `git rebase --skip`. To check out the
-original `<branch>` and remove the `.git/rebase-apply` working files, use
-the command `git rebase --abort` instead.
-
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
@@ -180,28 +196,6 @@ This is useful if F and G were flawed in some way, or should not be
part of topicA. Note that the argument to `--onto` and the `<upstream>`
parameter can be any valid commit-ish.
-In case of conflict, `git rebase` will stop at the first problematic commit
-and leave conflict markers in the tree. You can use `git diff` to locate
-the markers (<<<<<<) and make edits to resolve the conflict. For each
-file you edit, you need to tell Git that the conflict has been resolved,
-typically this would be done with
-
-
- git add <filename>
-
-
-After resolving the conflict manually and updating the index with the
-desired resolution, you can continue the rebasing process with
-
-
- git rebase --continue
-
-
-Alternatively, you can undo the 'git rebase' with
-
-
- git rebase --abort
-
MODE OPTIONS
------------
--
gitgitgadget
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH 3/5] doc: git rebase: clarify arguments syntax
2025-08-08 15:24 [PATCH 0/5] doc: git-rebase: clarify DESCRIPTION section Julia Evans via GitGitGadget
2025-08-08 15:24 ` [PATCH 1/5] doc: git-rebase: start with an example Julia Evans via GitGitGadget
2025-08-08 15:24 ` [PATCH 2/5] doc: git rebase: dedup merge conflict discussion Julia Evans via GitGitGadget
@ 2025-08-08 15:24 ` Julia Evans via GitGitGadget
2025-08-08 15:24 ` [PATCH 4/5] doc: git-rebase: move --onto explanation down Julia Evans via GitGitGadget
` (2 subsequent siblings)
5 siblings, 0 replies; 103+ messages in thread
From: Julia Evans via GitGitGadget @ 2025-08-08 15:24 UTC (permalink / raw)
To: git; +Cc: Julia Evans, Julia Evans
From: Julia Evans <julia@jvns.ca>
I found this extremely hard to understand as it was and this seemed like
a clearer wording to me.
Signed-off-by: Julia Evans <julia@jvns.ca>
---
Documentation/git-rebase.adoc | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc
index 3087e558b509..ada9f6b2614b 100644
--- a/Documentation/git-rebase.adoc
+++ b/Documentation/git-rebase.adoc
@@ -58,12 +58,10 @@ first problematic commit and leave conflict markers. If this happens, you can:
git rebase --skip
+`git rebase <upstream> <branch>` is shorthand for `git switch <branch>`
+followed by `git rebase <upstream>`.
-If `<branch>` is specified, `git rebase` will perform an automatic
-`git switch <branch>` before doing anything else. Otherwise
-it remains on the current branch.
-
-If `<upstream>` is not specified, the upstream configured in
+If you don't specify an `<upstream>` to rebase onto, the upstream configured in
`branch.<name>.remote` and `branch.<name>.merge` options will be used (see
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
--
gitgitgadget
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH 4/5] doc: git-rebase: move --onto explanation down
2025-08-08 15:24 [PATCH 0/5] doc: git-rebase: clarify DESCRIPTION section Julia Evans via GitGitGadget
` (2 preceding siblings ...)
2025-08-08 15:24 ` [PATCH 3/5] doc: git rebase: clarify arguments syntax Julia Evans via GitGitGadget
@ 2025-08-08 15:24 ` Julia Evans via GitGitGadget
2025-08-08 15:24 ` [PATCH 5/5] doc: git-rebase: update discussion of internals Julia Evans via GitGitGadget
2025-08-08 19:15 ` [PATCH v2 0/5] doc: git-rebase: clarify DESCRIPTION section Julia Evans via GitGitGadget
5 siblings, 0 replies; 103+ messages in thread
From: Julia Evans via GitGitGadget @ 2025-08-08 15:24 UTC (permalink / raw)
To: git; +Cc: Julia Evans, Julia Evans
From: Julia Evans <julia@jvns.ca>
There's a very clear explanation with examples of using --onto which is
currently buried in the very long DESCRIPTION section. This moves it to
its own section, so that we can reference the explanation from the
`--onto` option by name.
Signed-off-by: Julia Evans <julia@jvns.ca>
---
Documentation/git-rebase.adoc | 168 ++++++++++++++++++----------------
1 file changed, 87 insertions(+), 81 deletions(-)
diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc
index ada9f6b2614b..c63d67f340a0 100644
--- a/Documentation/git-rebase.adoc
+++ b/Documentation/git-rebase.adoc
@@ -113,87 +113,6 @@ will result in:
D---E---A'---F master
------------
-Here is how you would transplant a topic branch based on one
-branch to another, to pretend that you forked the topic branch
-from the latter branch, using `rebase --onto`.
-
-First let's assume your 'topic' is based on branch 'next'.
-For example, a feature developed in 'topic' depends on some
-functionality which is found in 'next'.
-
-------------
- o---o---o---o---o master
- \
- o---o---o---o---o next
- \
- o---o---o topic
-------------
-
-We want to make 'topic' forked from branch 'master'; for example,
-because the functionality on which 'topic' depends was merged into the
-more stable 'master' branch. We want our tree to look like this:
-
-------------
- o---o---o---o---o master
- | \
- | o'--o'--o' topic
- \
- o---o---o---o---o next
-------------
-
-We can get this using the following command:
-
- git rebase --onto master next topic
-
-
-Another example of --onto option is to rebase part of a
-branch. If we have the following situation:
-
-------------
- H---I---J topicB
- /
- E---F---G topicA
- /
- A---B---C---D master
-------------
-
-then the command
-
- git rebase --onto master topicA topicB
-
-would result in:
-
-------------
- H'--I'--J' topicB
- /
- | E---F---G topicA
- |/
- A---B---C---D master
-------------
-
-This is useful when topicB does not depend on topicA.
-
-A range of commits could also be removed with rebase. If we have
-the following situation:
-
-------------
- E---F---G---H---I---J topicA
-------------
-
-then the command
-
- git rebase --onto topicA~5 topicA~3 topicA
-
-would result in the removal of commits F and G:
-
-------------
- E---H'---I'---J' topicA
-------------
-
-This is useful if F and G were flawed in some way, or should not be
-part of topicA. Note that the argument to `--onto` and the `<upstream>`
-parameter can be any valid commit-ish.
-
MODE OPTIONS
------------
@@ -239,6 +158,8 @@ As a special case, you may use "A\...B" as a shortcut for the
merge base of A and B if there is exactly one merge base. You can
leave out at most one of A and B, in which case it defaults to HEAD.
+See TRANSPLANTING A TOPIC BRANCH WITH --ONTO below for examples.
+
--keep-base::
Set the starting point at which to create the new commits to the
merge base of `<upstream>` and `<branch>`. Running
@@ -1017,6 +938,91 @@ consistent (they compile, pass the testsuite, etc.) you should use
after each commit, test, and amend the commit if fixes are necessary.
+TRANSPLANTING A TOPIC BRANCH WITH --ONTO
+----------------------------------------
+
+Here is how you would transplant a topic branch based on one
+branch to another, to pretend that you forked the topic branch
+from the latter branch, using `rebase --onto`.
+
+First let's assume your 'topic' is based on branch 'next'.
+For example, a feature developed in 'topic' depends on some
+functionality which is found in 'next'.
+
+------------
+ o---o---o---o---o master
+ \
+ o---o---o---o---o next
+ \
+ o---o---o topic
+------------
+
+We want to make 'topic' forked from branch 'master'; for example,
+because the functionality on which 'topic' depends was merged into the
+more stable 'master' branch. We want our tree to look like this:
+
+------------
+ o---o---o---o---o master
+ | \
+ | o'--o'--o' topic
+ \
+ o---o---o---o---o next
+------------
+
+We can get this using the following command:
+
+ git rebase --onto master next topic
+
+
+Another example of --onto option is to rebase part of a
+branch. If we have the following situation:
+
+------------
+ H---I---J topicB
+ /
+ E---F---G topicA
+ /
+ A---B---C---D master
+------------
+
+then the command
+
+ git rebase --onto master topicA topicB
+
+would result in:
+
+------------
+ H'--I'--J' topicB
+ /
+ | E---F---G topicA
+ |/
+ A---B---C---D master
+------------
+
+This is useful when topicB does not depend on topicA.
+
+A range of commits could also be removed with rebase. If we have
+the following situation:
+
+------------
+ E---F---G---H---I---J topicA
+------------
+
+then the command
+
+ git rebase --onto topicA~5 topicA~3 topicA
+
+would result in the removal of commits F and G:
+
+------------
+ E---H'---I'---J' topicA
+------------
+
+This is useful if F and G were flawed in some way, or should not be
+part of topicA. Note that the argument to `--onto` and the `<upstream>`
+parameter can be any valid commit-ish.
+
+
RECOVERING FROM UPSTREAM REBASE
-------------------------------
--
gitgitgadget
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH 5/5] doc: git-rebase: update discussion of internals
2025-08-08 15:24 [PATCH 0/5] doc: git-rebase: clarify DESCRIPTION section Julia Evans via GitGitGadget
` (3 preceding siblings ...)
2025-08-08 15:24 ` [PATCH 4/5] doc: git-rebase: move --onto explanation down Julia Evans via GitGitGadget
@ 2025-08-08 15:24 ` Julia Evans via GitGitGadget
2025-08-08 19:15 ` [PATCH v2 0/5] doc: git-rebase: clarify DESCRIPTION section Julia Evans via GitGitGadget
5 siblings, 0 replies; 103+ messages in thread
From: Julia Evans via GitGitGadget @ 2025-08-08 15:24 UTC (permalink / raw)
To: git; +Cc: Julia Evans, Julia Evans
From: Julia Evans <julia@jvns.ca>
- make it clearer that we're talking about three steps of a process
- 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)
- move the `ORIG_HEAD` note down so that it doesn't interrupt the
discussion of the mechanics.
Signed-off-by: Julia Evans <julia@jvns.ca>
---
Documentation/git-rebase.adoc | 15 +++++++--------
1 file changed, 7 insertions(+), 8 deletions(-)
diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc
index c63d67f340a0..6b79cd0daca9 100644
--- a/Documentation/git-rebase.adoc
+++ b/Documentation/git-rebase.adoc
@@ -67,18 +67,23 @@ 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
+Here is a more detailed description of what `git rebase <upstream>` does:
+
+First, 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
+Then 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.
+Then the commits that were previously saved into the temporary area are
+reapplied to the current branch, one by one, in order.
+
[NOTE]
`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
@@ -86,12 +91,6 @@ at the end of the rebase if other commands that write that pseudo-ref
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
--
gitgitgadget
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [PATCH 1/5] doc: git-rebase: start with an example
2025-08-08 15:24 ` [PATCH 1/5] doc: git-rebase: start with an example Julia Evans via GitGitGadget
@ 2025-08-08 16:30 ` Junio C Hamano
2025-08-08 17:13 ` Julia Evans
0 siblings, 1 reply; 103+ messages in thread
From: Junio C Hamano @ 2025-08-08 16:30 UTC (permalink / raw)
To: Julia Evans via GitGitGadget; +Cc: git, Julia Evans
"Julia Evans via GitGitGadget" <gitgitgadget@gmail.com> writes:
> From: Julia Evans <julia@jvns.ca>
>
> 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.
>
> Signed-off-by: Julia Evans <julia@jvns.ca>
> ---
> Documentation/git-rebase.adoc | 46 +++++++++++++++--------------------
> 1 file changed, 20 insertions(+), 26 deletions(-)
>
> diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc
> index 956d3048f5a6..fee73623990d 100644
> --- a/Documentation/git-rebase.adoc
> +++ b/Documentation/git-rebase.adoc
> @@ -16,6 +16,26 @@ SYNOPSIS
>
> DESCRIPTION
> -----------
> +Transplant a series of commits onto a different starting point.
It is an excellent idea to start with what it does, before
explaining how you would drive it.
> +For example, assume the following history exists and the current branch is `topic`:
The line is a bit overly long, and the style a bit on the
"description of dry facts" side, which might want to give
a bit more "motivation" to help readers.
Here is my attempt.
Imagine that you have been working on the `topic` branch in this
history, and you'd want to "catch up" to the work done on the
`master` branch.
*** Illustration of "before" state ***
You want to transplant the commits you made on `topic` since it
diverged from `master` (i.e. A, B, and C), on top of the current
`master`. You can do so by running `git rebase master` while the
`topic` branch is checked out. `git rebase master topic` works
as a short-cut to `git checkout topic && git rebase master`.
*** Illustration of "after" state ***
perhaps?
Note that you lost the mention of `git rebase master topic` syntax
and the explanation that the form being a shorthand for checkout
followed by rebase, which I do not think appear anywhere else in the
document, so my suggested rewrite above resurrects it.
> +------------
> + A---B---C topic
> + /
> + D---E---F---G master
> +------------
> +
> +Then `git rebase master` will find all of the commits since `topic` diverged
> +from `master` and copy the changes in each of those commits on top of the
> +`master` branch.
> +
> +------------
> + A'--B'--C' topic
> + /
> + D---E---F---G master
> +------------
> +
> If `<branch>` is specified, `git rebase` will perform an automatic
> `git switch <branch>` before doing anything else. Otherwise
> it remains on the current branch.
> @@ -58,32 +78,6 @@ that caused the merge failure with `git rebase --skip`. To check out the
> original `<branch>` and remove the `.git/rebase-apply` working files, use
> the command `git rebase --abort` instead.
>
> -Assume the following history exists and the current branch is "topic":
> -
> -------------
> - A---B---C topic
> - /
> - D---E---F---G master
> -------------
> -
> -From this point, the result of either of the following commands:
> -
> -
> - git rebase master
> - git rebase master topic
> -
> -would be:
> -
> -------------
> - A'--B'--C' topic
> - /
> - D---E---F---G master
> -------------
> -
> -*NOTE:* The latter form is just a short-hand of `git checkout topic`
> -followed by `git rebase master`. When rebase exits `topic` will
> -remain the checked-out branch.
> -
> 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
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [PATCH 1/5] doc: git-rebase: start with an example
2025-08-08 16:30 ` Junio C Hamano
@ 2025-08-08 17:13 ` Julia Evans
2025-08-08 18:11 ` Junio C Hamano
0 siblings, 1 reply; 103+ messages in thread
From: Julia Evans @ 2025-08-08 17:13 UTC (permalink / raw)
To: Junio C Hamano, Julia Evans via GitGitGadget; +Cc: git
On Fri, Aug 8, 2025, at 12:30 PM, Junio C Hamano wrote:
> "Julia Evans via GitGitGadget" <gitgitgadget@gmail.com> writes:
>
>> From: Julia Evans <julia@jvns.ca>
>>
>> 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.
>>
>> Signed-off-by: Julia Evans <julia@jvns.ca>
>> ---
>> Documentation/git-rebase.adoc | 46 +++++++++++++++--------------------
>> 1 file changed, 20 insertions(+), 26 deletions(-)
>>
>> diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc
>> index 956d3048f5a6..fee73623990d 100644
>> --- a/Documentation/git-rebase.adoc
>> +++ b/Documentation/git-rebase.adoc
>> @@ -16,6 +16,26 @@ SYNOPSIS
>>
>> DESCRIPTION
>> -----------
>> +Transplant a series of commits onto a different starting point.
>
> It is an excellent idea to start with what it does, before
> explaining how you would drive it.
>
>> +For example, assume the following history exists and the current branch is `topic`:
>
> The line is a bit overly long, and the style a bit on the
> "description of dry facts" side, which might want to give
> a bit more "motivation" to help readers.
I'm very happy to hear that feedback: I thought it was very dry as well, but I copied that part from elsewhere in the man page because I thought that was git's preferred documentation style. I'll work on making it less dry.
> Note that you lost the mention of `git rebase master topic` syntax
> and the explanation that the form being a shorthand for checkout
> followed by rebase, which I do not think appear anywhere else in the
> document, so my suggested rewrite above resurrects it.
That's actually in PATCH 3/5 of this series: I also thought the explanation that the form being a shorthand for checkout followed by rebase was extremely clear so I moved it to be the primary explanation of what `git rebase <upstream> <branch>` does.
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [PATCH 2/5] doc: git rebase: dedup merge conflict discussion
2025-08-08 15:24 ` [PATCH 2/5] doc: git rebase: dedup merge conflict discussion Julia Evans via GitGitGadget
@ 2025-08-08 17:48 ` Junio C Hamano
0 siblings, 0 replies; 103+ messages in thread
From: Junio C Hamano @ 2025-08-08 17:48 UTC (permalink / raw)
To: Julia Evans via GitGitGadget; +Cc: git, Julia Evans
"Julia Evans via GitGitGadget" <gitgitgadget@gmail.com> writes:
> +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:
By using the numbered enumeration below, we may mislead the readers
that these are the things they have to do in this order, when we
actually are giving them choices.
If this happens, you can do one of these things:
would be an easy workaround.
> +1. Resolve the conflict. You can use `git diff` to find the markers (<<<<<<)
> + and make edits to resolve the conflict. For each file you edit, you need to
> + tell Git that the conflict has been resolved. Typically this would be
> + done with
> +
> + git add <filename>
> +
> + You can then continue the rebasing process with
> +
> + git rebase --continue
The original (below) does not do a perfect job, but I am afraid that
this increases the chance of misunderstanding by new readers that
they'd run "continue" after marking each confclited fines as "done"
with "git add", by reducing a sentence to a mere "then" in "You can
then continue".
Typically after resolving all the conflicts in a single
file, you would tell Git that you are done with this file:
git add <filename>
And after dealing with all the conflicted files and telling
Git that you are done, you would continue the rebasing
process with
git rebase --continue
or something?
> +2. Stop the `git rebase` and return your branch to its original state with
> +
> + git rebase --abort
> +
> +3. Skip the commit that caused the merge conflict with
> +
> + git rebase --skip
The explanation in the above looks good, and the new organization is
much easier to follow and is definite improvement compared to the
original.
I am not sure how the above how the above formats, though,
especially on a medium that is not monospaced text (e.g., html
rendition, not "git help -m rebase" on terminals). The prose should
typeset just like the normal text (i.e. your "Transplant a series of
commits" in the previous step that starts the description section),
but the command that the users would type should be typeset in
monospace typewriter. Have you tried?
Thanks.
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [PATCH 1/5] doc: git-rebase: start with an example
2025-08-08 17:13 ` Julia Evans
@ 2025-08-08 18:11 ` Junio C Hamano
0 siblings, 0 replies; 103+ messages in thread
From: Junio C Hamano @ 2025-08-08 18:11 UTC (permalink / raw)
To: Julia Evans; +Cc: Julia Evans via GitGitGadget, git
"Julia Evans" <julia@jvns.ca> writes:
> I'm very happy to hear that feedback: I thought it was very dry as
> well, but I copied that part from elsewhere in the man page
> because I thought that was git's preferred documentation
> style. I'll work on making it less dry.
[administrivia: please wrap your overlong lines; we write for this
hypothetiical reader on an 80-column terminal].
>> Note that you lost the mention of `git rebase master topic` syntax
>> and the explanation that the form being a shorthand for checkout
>> followed by rebase, which I do not think appear anywhere else in the
>> document, so my suggested rewrite above resurrects it.
>
> That's actually in PATCH 3/5 of this series:...
Which I think is too late; both are quite commonly used and useful,
so showing them upfront when the command line examples are first
introduced would be more preferrable.
Thanks.
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v2 0/5] doc: git-rebase: clarify DESCRIPTION section
2025-08-08 15:24 [PATCH 0/5] doc: git-rebase: clarify DESCRIPTION section Julia Evans via GitGitGadget
` (4 preceding siblings ...)
2025-08-08 15:24 ` [PATCH 5/5] doc: git-rebase: update discussion of internals Julia Evans via GitGitGadget
@ 2025-08-08 19:15 ` Julia Evans via GitGitGadget
2025-08-08 19:15 ` [PATCH v2 1/5] doc: git-rebase: start with an example Julia Evans via GitGitGadget
` (6 more replies)
5 siblings, 7 replies; 103+ messages in thread
From: Julia Evans via GitGitGadget @ 2025-08-08 19:15 UTC (permalink / raw)
To: git; +Cc: Julia Evans
Thanks for the review comments, here are the new changes which:
* make the intro to the man page less dry, with the suggested wording
* clarify the merge conflict resolution explanation & fix the HTML
formatting issues
* move the explanation of the git rebase <upstream> <branch> syntax up into
the intro
I'm still curious about the intention for the git rebase master topic
syntax, since I'd never heard of it before. Is it just to save on typing,
since it's fewer characters than git switch topic and then git rebase
master? I ask because someone mentioned to me on Mastodon
(https://hachyderm.io/@simontatham/114988051822317920) that they sometimes
use git rebase HEAD main as part of their workflow, which is not equivalent
to git checkout main && git rebase HEAD. That made me think that there might
be some broader intent to enable rebases that wouldn't otherwise be possible
without that syntax.
I'll wrap my text to 80 characters in the future, still learning the process
for emailing a plain-text mailing list :)
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 | 285 ++++++++++++++++------------------
1 file changed, 137 insertions(+), 148 deletions(-)
base-commit: 2c2ba49d55ff26c1082b8137b1ec5eeccb4337d1
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1949%2Fjvns%2Fclarify-rebase-v2
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1949/jvns/clarify-rebase-v2
Pull-Request: https://github.com/gitgitgadget/git/pull/1949
Range-diff vs v1:
1: ac3a91c04bf ! 1: 26b742eb49f doc: git-rebase: start with an example
@@ Documentation/git-rebase.adoc: SYNOPSIS
-----------
+Transplant a series of commits onto a different starting point.
+
-+For example, assume the following history exists and the current branch is `topic`:
++For example, imagine that you have been working on the `topic` branch in this
++history, and you want to "catch up" to the work done on the `master` branch.
+
+------------
+ A---B---C topic
@@ Documentation/git-rebase.adoc: SYNOPSIS
+ D---E---F---G master
+------------
+
-+Then `git rebase master` will find all of the commits since `topic` diverged
-+from `master` and copy the changes in each of those commits on top of the
-+`master` branch.
++You want to transplant the commits you made on `topic` since it diverged from
++`master` (i.e. A, B, and C), on top of the current `master`. You can do this
++by running `git rebase master` while the `topic` branch is checked out. If you
++want to rebase `topic` while on another branch, `git rebase master topic` is a
++short-cut for `git switch topic && git rebase master`.
+
+------------
+ A'--B'--C' topic
2: f4f0a5a1172 ! 2: 249a5127904 doc: git rebase: dedup merge conflict discussion
@@ Commit message
Signed-off-by: Julia Evans <julia@jvns.ca>
## Documentation/git-rebase.adoc ##
-@@ Documentation/git-rebase.adoc: from `master` and copy the changes in each of those commits on top of the
+@@ Documentation/git-rebase.adoc: short-cut for `git switch topic && git rebase master`.
D---E---F---G master
------------
+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:
++first problematic commit and leave conflict markers. If this happens, you can do
++one of these things:
+
+1. Resolve the conflict. You can use `git diff` to find the markers (<<<<<<)
+ and make edits to resolve the conflict. For each file you edit, you need to
-+ tell Git that the conflict has been resolved. Typically this would be
-+ done with
-+
-+ git add <filename>
-+
-+ You can then continue the rebasing process with
++ tell Git that the conflict has been resolved. You can mark the conflict as
++ resolved with `git add <filename>`. After resolving all of the conflicts,
++ you can continue the rebasing process with
+
+ git rebase --continue
+
3: b27117ea19a ! 3: ce7ab74ea0f doc: git rebase: clarify arguments syntax
@@ Metadata
## Commit message ##
doc: git rebase: clarify arguments syntax
- I found this extremely hard to understand as it was and this seemed like
- a clearer wording to me.
+ This removes the explanation of `git rebase <upstream> <branch>`, since
+ it was already explained above that it's shorthand for `git switch
+ <branch> && git rebase <upstream>`
Signed-off-by: Julia Evans <julia@jvns.ca>
## Documentation/git-rebase.adoc ##
-@@ Documentation/git-rebase.adoc: first problematic commit and leave conflict markers. If this happens, you can:
+@@ Documentation/git-rebase.adoc: one of these things:
git rebase --skip
-+`git rebase <upstream> <branch>` is shorthand for `git switch <branch>`
-+followed by `git rebase <upstream>`.
-
+-
-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: 28b00d3b32f = 4: 590d7486d3d doc: git-rebase: move --onto explanation down
5: 7d4dc6d2c04 = 5: ad97cd9e671 doc: git-rebase: update discussion of internals
--
gitgitgadget
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v2 1/5] doc: git-rebase: start with an example
2025-08-08 19:15 ` [PATCH v2 0/5] doc: git-rebase: clarify DESCRIPTION section Julia Evans via GitGitGadget
@ 2025-08-08 19:15 ` Julia Evans via GitGitGadget
2025-08-08 23:31 ` Junio C Hamano
2025-08-08 19:15 ` [PATCH v2 2/5] doc: git rebase: dedup merge conflict discussion Julia Evans via GitGitGadget
` (5 subsequent siblings)
6 siblings, 1 reply; 103+ messages in thread
From: Julia Evans via GitGitGadget @ 2025-08-08 19:15 UTC (permalink / raw)
To: git; +Cc: Julia Evans, Julia Evans
From: Julia Evans <julia@jvns.ca>
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.
Signed-off-by: Julia Evans <julia@jvns.ca>
---
Documentation/git-rebase.adoc | 49 ++++++++++++++++-------------------
1 file changed, 23 insertions(+), 26 deletions(-)
diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc
index 956d3048f5a6..6dacf693bd71 100644
--- a/Documentation/git-rebase.adoc
+++ b/Documentation/git-rebase.adoc
@@ -16,6 +16,29 @@ SYNOPSIS
DESCRIPTION
-----------
+Transplant a series of commits onto a different starting point.
+
+For example, imagine that you have been working on the `topic` branch in this
+history, and you want to "catch up" to the work done on the `master` branch.
+
+------------
+ A---B---C topic
+ /
+ D---E---F---G master
+------------
+
+You want to transplant the commits you made on `topic` since it diverged from
+`master` (i.e. A, B, and C), on top of the current `master`. You can do this
+by running `git rebase master` while the `topic` branch is checked out. If you
+want to rebase `topic` while on another branch, `git rebase master topic` is a
+short-cut for `git switch topic && git rebase master`.
+
+------------
+ A'--B'--C' topic
+ /
+ D---E---F---G master
+------------
+
If `<branch>` is specified, `git rebase` will perform an automatic
`git switch <branch>` before doing anything else. Otherwise
it remains on the current branch.
@@ -58,32 +81,6 @@ that caused the merge failure with `git rebase --skip`. To check out the
original `<branch>` and remove the `.git/rebase-apply` working files, use
the command `git rebase --abort` instead.
-Assume the following history exists and the current branch is "topic":
-
-------------
- A---B---C topic
- /
- D---E---F---G master
-------------
-
-From this point, the result of either of the following commands:
-
-
- git rebase master
- git rebase master topic
-
-would be:
-
-------------
- A'--B'--C' topic
- /
- D---E---F---G master
-------------
-
-*NOTE:* The latter form is just a short-hand of `git checkout topic`
-followed by `git rebase master`. When rebase exits `topic` will
-remain the checked-out branch.
-
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
--
gitgitgadget
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v2 2/5] doc: git rebase: dedup merge conflict discussion
2025-08-08 19:15 ` [PATCH v2 0/5] doc: git-rebase: clarify DESCRIPTION section Julia Evans via GitGitGadget
2025-08-08 19:15 ` [PATCH v2 1/5] doc: git-rebase: start with an example Julia Evans via GitGitGadget
@ 2025-08-08 19:15 ` Julia Evans via GitGitGadget
2025-08-08 19:15 ` [PATCH v2 3/5] doc: git rebase: clarify arguments syntax Julia Evans via GitGitGadget
` (4 subsequent siblings)
6 siblings, 0 replies; 103+ messages in thread
From: Julia Evans via GitGitGadget @ 2025-08-08 19:15 UTC (permalink / raw)
To: git; +Cc: Julia Evans, Julia Evans
From: Julia Evans <julia@jvns.ca>
Previously there were two explanations, this combines them both into a
single explanation.
Signed-off-by: Julia Evans <julia@jvns.ca>
---
Documentation/git-rebase.adoc | 50 +++++++++++++++--------------------
1 file changed, 21 insertions(+), 29 deletions(-)
diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc
index 6dacf693bd71..a93c616f38b1 100644
--- a/Documentation/git-rebase.adoc
+++ b/Documentation/git-rebase.adoc
@@ -39,6 +39,27 @@ short-cut for `git switch topic && git rebase master`.
D---E---F---G master
------------
+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
+one of these things:
+
+1. Resolve the conflict. You can use `git diff` to find the markers (<<<<<<)
+ and make edits to resolve the conflict. For each file you edit, you need to
+ tell Git that the conflict has been resolved. You can mark the conflict as
+ resolved with `git add <filename>`. After resolving all of the conflicts,
+ you can continue the rebasing process with
+
+ git rebase --continue
+
+2. Stop the `git rebase` and return your branch to its original state with
+
+ git rebase --abort
+
+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
it remains on the current branch.
@@ -74,13 +95,6 @@ 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).
-It is possible that a merge failure will prevent this process from being
-completely automatic. You will have to resolve any such merge failure
-and run `git rebase --continue`. Another option is to bypass the commit
-that caused the merge failure with `git rebase --skip`. To check out the
-original `<branch>` and remove the `.git/rebase-apply` working files, use
-the command `git rebase --abort` instead.
-
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
@@ -183,28 +197,6 @@ This is useful if F and G were flawed in some way, or should not be
part of topicA. Note that the argument to `--onto` and the `<upstream>`
parameter can be any valid commit-ish.
-In case of conflict, `git rebase` will stop at the first problematic commit
-and leave conflict markers in the tree. You can use `git diff` to locate
-the markers (<<<<<<) and make edits to resolve the conflict. For each
-file you edit, you need to tell Git that the conflict has been resolved,
-typically this would be done with
-
-
- git add <filename>
-
-
-After resolving the conflict manually and updating the index with the
-desired resolution, you can continue the rebasing process with
-
-
- git rebase --continue
-
-
-Alternatively, you can undo the 'git rebase' with
-
-
- git rebase --abort
-
MODE OPTIONS
------------
--
gitgitgadget
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v2 3/5] doc: git rebase: clarify arguments syntax
2025-08-08 19:15 ` [PATCH v2 0/5] doc: git-rebase: clarify DESCRIPTION section Julia Evans via GitGitGadget
2025-08-08 19:15 ` [PATCH v2 1/5] doc: git-rebase: start with an example Julia Evans via GitGitGadget
2025-08-08 19:15 ` [PATCH v2 2/5] doc: git rebase: dedup merge conflict discussion Julia Evans via GitGitGadget
@ 2025-08-08 19:15 ` Julia Evans via GitGitGadget
2025-08-08 21:09 ` Junio C Hamano
2025-08-08 19:15 ` [PATCH v2 4/5] doc: git-rebase: move --onto explanation down Julia Evans via GitGitGadget
` (3 subsequent siblings)
6 siblings, 1 reply; 103+ messages in thread
From: Julia Evans via GitGitGadget @ 2025-08-08 19:15 UTC (permalink / raw)
To: git; +Cc: Julia Evans, Julia Evans
From: Julia Evans <julia@jvns.ca>
This removes the explanation of `git rebase <upstream> <branch>`, since
it was already explained above that it's shorthand for `git switch
<branch> && git rebase <upstream>`
Signed-off-by: Julia Evans <julia@jvns.ca>
---
Documentation/git-rebase.adoc | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc
index a93c616f38b1..e700b92e35ac 100644
--- a/Documentation/git-rebase.adoc
+++ b/Documentation/git-rebase.adoc
@@ -59,12 +59,7 @@ 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.
-
-If `<upstream>` is not specified, the upstream configured in
+If you don't specify an `<upstream>` to rebase onto, the upstream configured in
`branch.<name>.remote` and `branch.<name>.merge` options will be used (see
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
--
gitgitgadget
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v2 4/5] doc: git-rebase: move --onto explanation down
2025-08-08 19:15 ` [PATCH v2 0/5] doc: git-rebase: clarify DESCRIPTION section Julia Evans via GitGitGadget
` (2 preceding siblings ...)
2025-08-08 19:15 ` [PATCH v2 3/5] doc: git rebase: clarify arguments syntax Julia Evans via GitGitGadget
@ 2025-08-08 19:15 ` Julia Evans via GitGitGadget
2025-08-08 19:15 ` [PATCH v2 5/5] doc: git-rebase: update discussion of internals Julia Evans via GitGitGadget
` (2 subsequent siblings)
6 siblings, 0 replies; 103+ messages in thread
From: Julia Evans via GitGitGadget @ 2025-08-08 19:15 UTC (permalink / raw)
To: git; +Cc: Julia Evans, Julia Evans
From: Julia Evans <julia@jvns.ca>
There's a very clear explanation with examples of using --onto which is
currently buried in the very long DESCRIPTION section. This moves it to
its own section, so that we can reference the explanation from the
`--onto` option by name.
Signed-off-by: Julia Evans <julia@jvns.ca>
---
Documentation/git-rebase.adoc | 168 ++++++++++++++++++----------------
1 file changed, 87 insertions(+), 81 deletions(-)
diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc
index e700b92e35ac..6a4b3dbd5960 100644
--- a/Documentation/git-rebase.adoc
+++ b/Documentation/git-rebase.adoc
@@ -111,87 +111,6 @@ will result in:
D---E---A'---F master
------------
-Here is how you would transplant a topic branch based on one
-branch to another, to pretend that you forked the topic branch
-from the latter branch, using `rebase --onto`.
-
-First let's assume your 'topic' is based on branch 'next'.
-For example, a feature developed in 'topic' depends on some
-functionality which is found in 'next'.
-
-------------
- o---o---o---o---o master
- \
- o---o---o---o---o next
- \
- o---o---o topic
-------------
-
-We want to make 'topic' forked from branch 'master'; for example,
-because the functionality on which 'topic' depends was merged into the
-more stable 'master' branch. We want our tree to look like this:
-
-------------
- o---o---o---o---o master
- | \
- | o'--o'--o' topic
- \
- o---o---o---o---o next
-------------
-
-We can get this using the following command:
-
- git rebase --onto master next topic
-
-
-Another example of --onto option is to rebase part of a
-branch. If we have the following situation:
-
-------------
- H---I---J topicB
- /
- E---F---G topicA
- /
- A---B---C---D master
-------------
-
-then the command
-
- git rebase --onto master topicA topicB
-
-would result in:
-
-------------
- H'--I'--J' topicB
- /
- | E---F---G topicA
- |/
- A---B---C---D master
-------------
-
-This is useful when topicB does not depend on topicA.
-
-A range of commits could also be removed with rebase. If we have
-the following situation:
-
-------------
- E---F---G---H---I---J topicA
-------------
-
-then the command
-
- git rebase --onto topicA~5 topicA~3 topicA
-
-would result in the removal of commits F and G:
-
-------------
- E---H'---I'---J' topicA
-------------
-
-This is useful if F and G were flawed in some way, or should not be
-part of topicA. Note that the argument to `--onto` and the `<upstream>`
-parameter can be any valid commit-ish.
-
MODE OPTIONS
------------
@@ -237,6 +156,8 @@ As a special case, you may use "A\...B" as a shortcut for the
merge base of A and B if there is exactly one merge base. You can
leave out at most one of A and B, in which case it defaults to HEAD.
+See TRANSPLANTING A TOPIC BRANCH WITH --ONTO below for examples.
+
--keep-base::
Set the starting point at which to create the new commits to the
merge base of `<upstream>` and `<branch>`. Running
@@ -1015,6 +936,91 @@ consistent (they compile, pass the testsuite, etc.) you should use
after each commit, test, and amend the commit if fixes are necessary.
+TRANSPLANTING A TOPIC BRANCH WITH --ONTO
+----------------------------------------
+
+Here is how you would transplant a topic branch based on one
+branch to another, to pretend that you forked the topic branch
+from the latter branch, using `rebase --onto`.
+
+First let's assume your 'topic' is based on branch 'next'.
+For example, a feature developed in 'topic' depends on some
+functionality which is found in 'next'.
+
+------------
+ o---o---o---o---o master
+ \
+ o---o---o---o---o next
+ \
+ o---o---o topic
+------------
+
+We want to make 'topic' forked from branch 'master'; for example,
+because the functionality on which 'topic' depends was merged into the
+more stable 'master' branch. We want our tree to look like this:
+
+------------
+ o---o---o---o---o master
+ | \
+ | o'--o'--o' topic
+ \
+ o---o---o---o---o next
+------------
+
+We can get this using the following command:
+
+ git rebase --onto master next topic
+
+
+Another example of --onto option is to rebase part of a
+branch. If we have the following situation:
+
+------------
+ H---I---J topicB
+ /
+ E---F---G topicA
+ /
+ A---B---C---D master
+------------
+
+then the command
+
+ git rebase --onto master topicA topicB
+
+would result in:
+
+------------
+ H'--I'--J' topicB
+ /
+ | E---F---G topicA
+ |/
+ A---B---C---D master
+------------
+
+This is useful when topicB does not depend on topicA.
+
+A range of commits could also be removed with rebase. If we have
+the following situation:
+
+------------
+ E---F---G---H---I---J topicA
+------------
+
+then the command
+
+ git rebase --onto topicA~5 topicA~3 topicA
+
+would result in the removal of commits F and G:
+
+------------
+ E---H'---I'---J' topicA
+------------
+
+This is useful if F and G were flawed in some way, or should not be
+part of topicA. Note that the argument to `--onto` and the `<upstream>`
+parameter can be any valid commit-ish.
+
+
RECOVERING FROM UPSTREAM REBASE
-------------------------------
--
gitgitgadget
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v2 5/5] doc: git-rebase: update discussion of internals
2025-08-08 19:15 ` [PATCH v2 0/5] doc: git-rebase: clarify DESCRIPTION section Julia Evans via GitGitGadget
` (3 preceding siblings ...)
2025-08-08 19:15 ` [PATCH v2 4/5] doc: git-rebase: move --onto explanation down Julia Evans via GitGitGadget
@ 2025-08-08 19:15 ` Julia Evans via GitGitGadget
2025-08-08 21:54 ` Junio C Hamano
2025-08-08 22:52 ` [PATCH v3 0/5] doc: git-rebase: clarify DESCRIPTION section Julia Evans via GitGitGadget
2025-08-09 15:04 ` [PATCH v2 " D. Ben Knoble
6 siblings, 1 reply; 103+ messages in thread
From: Julia Evans via GitGitGadget @ 2025-08-08 19:15 UTC (permalink / raw)
To: git; +Cc: Julia Evans, Julia Evans
From: Julia Evans <julia@jvns.ca>
- make it clearer that we're talking about three steps of a process
- 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)
- move the `ORIG_HEAD` note down so that it doesn't interrupt the
discussion of the mechanics.
Signed-off-by: Julia Evans <julia@jvns.ca>
---
Documentation/git-rebase.adoc | 15 +++++++--------
1 file changed, 7 insertions(+), 8 deletions(-)
diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc
index 6a4b3dbd5960..5a49e4f2de9a 100644
--- a/Documentation/git-rebase.adoc
+++ b/Documentation/git-rebase.adoc
@@ -65,18 +65,23 @@ 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
+Here is a more detailed description of what `git rebase <upstream>` does:
+
+First, 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
+Then 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.
+Then the commits that were previously saved into the temporary area are
+reapplied to the current branch, one by one, in order.
+
[NOTE]
`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
@@ -84,12 +89,6 @@ at the end of the rebase if other commands that write that pseudo-ref
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
--
gitgitgadget
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [PATCH v2 3/5] doc: git rebase: clarify arguments syntax
2025-08-08 19:15 ` [PATCH v2 3/5] doc: git rebase: clarify arguments syntax Julia Evans via GitGitGadget
@ 2025-08-08 21:09 ` Junio C Hamano
0 siblings, 0 replies; 103+ messages in thread
From: Junio C Hamano @ 2025-08-08 21:09 UTC (permalink / raw)
To: Julia Evans via GitGitGadget; +Cc: git, Julia Evans
"Julia Evans via GitGitGadget" <gitgitgadget@gmail.com> writes:
> From: Julia Evans <julia@jvns.ca>
>
> This removes the explanation of `git rebase <upstream> <branch>`, since
> it was already explained above that it's shorthand for `git switch
> <branch> && git rebase <upstream>`
We usually do not say "This [commit] does X". In this particular
case, since the objective is so obvious, we do not necessarily have
to follow the whole "summarize the current state, explain why it is
problematic, and then tell somebody sitting in front of a keyboard
to change the code in this and that way to make it improve" 9 yards;
just tweaking it into
Remove the redundant explanation of `git ...`, since it was
already explained earlier.
would be sufficient.
Although the proposed log message does not mention it, I actually
like the other change in this patch, that rephrases the "if you
don't specify...", even better. The addtional "to rebase onto" does
make the description clearer.
Thanks.
> Signed-off-by: Julia Evans <julia@jvns.ca>
> ---
> Documentation/git-rebase.adoc | 7 +------
> 1 file changed, 1 insertion(+), 6 deletions(-)
>
> diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc
> index a93c616f38b1..e700b92e35ac 100644
> --- a/Documentation/git-rebase.adoc
> +++ b/Documentation/git-rebase.adoc
> @@ -59,12 +59,7 @@ 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.
> -
> -If `<upstream>` is not specified, the upstream configured in
> +If you don't specify an `<upstream>` to rebase onto, the upstream configured in
> `branch.<name>.remote` and `branch.<name>.merge` options will be used (see
> 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
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [PATCH v2 5/5] doc: git-rebase: update discussion of internals
2025-08-08 19:15 ` [PATCH v2 5/5] doc: git-rebase: update discussion of internals Julia Evans via GitGitGadget
@ 2025-08-08 21:54 ` Junio C Hamano
0 siblings, 0 replies; 103+ messages in thread
From: Junio C Hamano @ 2025-08-08 21:54 UTC (permalink / raw)
To: Julia Evans via GitGitGadget; +Cc: git, Julia Evans
"Julia Evans via GitGitGadget" <gitgitgadget@gmail.com> writes:
> From: Julia Evans <julia@jvns.ca>
>
> - make it clearer that we're talking about three steps of a process
A good call. "First, then, then" does make it clear where each new
step begins. "First, then, finally" would make it even more obvious
which step concludes the sequence, though.
> - 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)
OK.
> - move the `ORIG_HEAD` note down so that it doesn't interrupt the
> discussion of the mechanics.
I thought you moved the "finally we reapply" up, instead of moving
the note down ;-) And when viewed that way, a more direct way to
justify this change is that you made sure these three steps are kept
together.
Again, good change.
> -All changes made by commits in the current branch but that are not
> +Here is a more detailed description of what `git rebase <upstream>` does:
> +
> +First, 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.
If we are ambitious, we may want to rewrite this first step to put
almost no stress on "saving" and "temporary area". Especially when
you rebase with merge backend, it would be morally a sequence of
cherry-pick, without us having to save anything---we only need to
figure out which commits to replay in what order.
First, the command figures out changes from which commits to
replay in what order. The set of commits are those shown by
`git log <base>..HEAD`, where <base> is the <upstream> if given,
or computed fork-point if the `--fork-point` option is active,
or all commits that lead to `HEAD` if `--root` is given.
> -The current branch is reset to `<upstream>` or `<newbase>` if the
> +Then 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.
"This has the exact same effect as" made my reading hiccup.
Then `git reset --hard` rewinds the current branch to the commit
given by `--onto`, if specified, or to `<upstream>`.
I am not sure if it is worth talking about ORIG_HEAD at this point,
as that is part of what `git reset --hard` does with this step.
Given especially that we have NOTE that says ORIG_HEAD cannot be
relied upon once the replaying of commits begin, mentioning the
value of ORIG_HEAD before the replaying begins does not seem to add
much value to the explanation.
> +Then the commits that were previously saved into the temporary area are
> +reapplied to the current branch, one by one, in order.
Yup. As I suggested, "Then" -> "Finally".
I do not know how much detail we want to give to readers, and I do
to prefer to tell some white lie in end-user facing documentation if
simplified description helps the initial understanding, so I am not
yet decided if I recommend rewriting these "three step" explanation,
but FYI, the modern rebase machinery works slightly differently:
First the command figures out what to replay, on which commit,
and in what order.
Then the HEAD is detached ("git checkout --detach <onto>") to
the commit the first change is replayed onto.
Then the changes are replayed, one by one, in the order.
Optionally a mergy history can be rebased while retaining
the topology.
Finally, the branch being rebased is made to point at the
resulting HEAD (i.e. equivalent to "git checkout -B <branch>"
to jump back from the detached HEAD state).
The difference between the simplified procedure and this "replaying
is done while on detached HEAD" procedure gives us a somewhat big
usability improvement, as a rebasing will be recorded in a single
reflog event for the branch getting rebased, no matter how many
commits are on the branch.
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v3 0/5] doc: git-rebase: clarify DESCRIPTION section
2025-08-08 19:15 ` [PATCH v2 0/5] doc: git-rebase: clarify DESCRIPTION section Julia Evans via GitGitGadget
` (4 preceding siblings ...)
2025-08-08 19:15 ` [PATCH v2 5/5] doc: git-rebase: update discussion of internals Julia Evans via GitGitGadget
@ 2025-08-08 22:52 ` Julia Evans via GitGitGadget
2025-08-08 22:52 ` [PATCH v3 1/5] doc: git-rebase: start with an example Julia Evans via GitGitGadget
` (5 more replies)
2025-08-09 15:04 ` [PATCH v2 " D. Ben Knoble
6 siblings, 6 replies; 103+ messages in thread
From: Julia Evans via GitGitGadget @ 2025-08-08 22:52 UTC (permalink / raw)
To: git; +Cc: Julia Evans
I liked the idea of trying a more ambitious rewrite of the "here's how git
rebase works internally" section, so here's an attempt at it.
My idea is to give an accurate technical description of how the merge
backend works while deferring some of the details (like how exactly
--fork-point works or what happens when you rebase a merge) to later in the
man page. I've also tried to use a minimum of git jargon, for example saying
"Then it checks out <upstream>" instead of mentioning anything about a
"detached HEAD" since I know that term can jarring for folks who aren't used
to that term.
I hedged a bit by saying that rebase is "similar to" running git cherry-pick
repeatedly since I think of a rebase as being like doing a bunch of
cherry-picks (and very often hear people describing it that way), but I'm
sure that there are differences that I'm not aware of.
I've also updated the "clarify arguments syntax" commit message.
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 | 300 ++++++++++++++++------------------
1 file changed, 145 insertions(+), 155 deletions(-)
base-commit: 2c2ba49d55ff26c1082b8137b1ec5eeccb4337d1
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1949%2Fjvns%2Fclarify-rebase-v3
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1949/jvns/clarify-rebase-v3
Pull-Request: https://github.com/gitgitgadget/git/pull/1949
Range-diff vs v2:
1: 26b742eb49f = 1: 26b742eb49f doc: git-rebase: start with an example
2: 249a5127904 = 2: 249a5127904 doc: git rebase: dedup merge conflict discussion
3: ce7ab74ea0f ! 3: 013a5044ef3 doc: git rebase: clarify arguments syntax
@@ Metadata
## Commit message ##
doc: git rebase: clarify arguments syntax
- This removes the explanation of `git rebase <upstream> <branch>`, since
- it was already explained above that it's shorthand for `git switch
- <branch> && git rebase <upstream>`
+ Remove duplicate explanation of `git rebase <upstream> <branch>` which
+ is already explained above.
Signed-off-by: Julia Evans <julia@jvns.ca>
4: 590d7486d3d = 4: c574a27412d doc: git-rebase: move --onto explanation down
5: ad97cd9e671 ! 5: eabacd3c159 doc: git-rebase: update discussion of internals
@@ Metadata
## Commit message ##
doc: git-rebase: update discussion of internals
- - make it clearer that we're talking about three steps of a process
+ - 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)
- - move the `ORIG_HEAD` note down so that it doesn't interrupt the
- discussion of the mechanics.
+ - 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 <julia@jvns.ca>
@@ Documentation/git-rebase.adoc: linkgit:git-config[1] for details) and the `--for
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:
+
-+First, 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
-+Then 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.
-
-+Then the commits that were previously saved into the temporary area are
-+reapplied to the current branch, one by one, in order.
++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>`.
+
[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
-@@ Documentation/git-rebase.adoc: 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]).
--
gitgitgadget
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v3 1/5] doc: git-rebase: start with an example
2025-08-08 22:52 ` [PATCH v3 0/5] doc: git-rebase: clarify DESCRIPTION section Julia Evans via GitGitGadget
@ 2025-08-08 22:52 ` Julia Evans via GitGitGadget
2025-08-08 22:52 ` [PATCH v3 2/5] doc: git rebase: dedup merge conflict discussion Julia Evans via GitGitGadget
` (4 subsequent siblings)
5 siblings, 0 replies; 103+ messages in thread
From: Julia Evans via GitGitGadget @ 2025-08-08 22:52 UTC (permalink / raw)
To: git; +Cc: Julia Evans, Julia Evans
From: Julia Evans <julia@jvns.ca>
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.
Signed-off-by: Julia Evans <julia@jvns.ca>
---
Documentation/git-rebase.adoc | 49 ++++++++++++++++-------------------
1 file changed, 23 insertions(+), 26 deletions(-)
diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc
index 956d3048f5a6..6dacf693bd71 100644
--- a/Documentation/git-rebase.adoc
+++ b/Documentation/git-rebase.adoc
@@ -16,6 +16,29 @@ SYNOPSIS
DESCRIPTION
-----------
+Transplant a series of commits onto a different starting point.
+
+For example, imagine that you have been working on the `topic` branch in this
+history, and you want to "catch up" to the work done on the `master` branch.
+
+------------
+ A---B---C topic
+ /
+ D---E---F---G master
+------------
+
+You want to transplant the commits you made on `topic` since it diverged from
+`master` (i.e. A, B, and C), on top of the current `master`. You can do this
+by running `git rebase master` while the `topic` branch is checked out. If you
+want to rebase `topic` while on another branch, `git rebase master topic` is a
+short-cut for `git switch topic && git rebase master`.
+
+------------
+ A'--B'--C' topic
+ /
+ D---E---F---G master
+------------
+
If `<branch>` is specified, `git rebase` will perform an automatic
`git switch <branch>` before doing anything else. Otherwise
it remains on the current branch.
@@ -58,32 +81,6 @@ that caused the merge failure with `git rebase --skip`. To check out the
original `<branch>` and remove the `.git/rebase-apply` working files, use
the command `git rebase --abort` instead.
-Assume the following history exists and the current branch is "topic":
-
-------------
- A---B---C topic
- /
- D---E---F---G master
-------------
-
-From this point, the result of either of the following commands:
-
-
- git rebase master
- git rebase master topic
-
-would be:
-
-------------
- A'--B'--C' topic
- /
- D---E---F---G master
-------------
-
-*NOTE:* The latter form is just a short-hand of `git checkout topic`
-followed by `git rebase master`. When rebase exits `topic` will
-remain the checked-out branch.
-
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
--
gitgitgadget
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v3 2/5] doc: git rebase: dedup merge conflict discussion
2025-08-08 22:52 ` [PATCH v3 0/5] doc: git-rebase: clarify DESCRIPTION section Julia Evans via GitGitGadget
2025-08-08 22:52 ` [PATCH v3 1/5] doc: git-rebase: start with an example Julia Evans via GitGitGadget
@ 2025-08-08 22:52 ` Julia Evans via GitGitGadget
2025-08-08 22:52 ` [PATCH v3 3/5] doc: git rebase: clarify arguments syntax Julia Evans via GitGitGadget
` (3 subsequent siblings)
5 siblings, 0 replies; 103+ messages in thread
From: Julia Evans via GitGitGadget @ 2025-08-08 22:52 UTC (permalink / raw)
To: git; +Cc: Julia Evans, Julia Evans
From: Julia Evans <julia@jvns.ca>
Previously there were two explanations, this combines them both into a
single explanation.
Signed-off-by: Julia Evans <julia@jvns.ca>
---
Documentation/git-rebase.adoc | 50 +++++++++++++++--------------------
1 file changed, 21 insertions(+), 29 deletions(-)
diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc
index 6dacf693bd71..a93c616f38b1 100644
--- a/Documentation/git-rebase.adoc
+++ b/Documentation/git-rebase.adoc
@@ -39,6 +39,27 @@ short-cut for `git switch topic && git rebase master`.
D---E---F---G master
------------
+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
+one of these things:
+
+1. Resolve the conflict. You can use `git diff` to find the markers (<<<<<<)
+ and make edits to resolve the conflict. For each file you edit, you need to
+ tell Git that the conflict has been resolved. You can mark the conflict as
+ resolved with `git add <filename>`. After resolving all of the conflicts,
+ you can continue the rebasing process with
+
+ git rebase --continue
+
+2. Stop the `git rebase` and return your branch to its original state with
+
+ git rebase --abort
+
+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
it remains on the current branch.
@@ -74,13 +95,6 @@ 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).
-It is possible that a merge failure will prevent this process from being
-completely automatic. You will have to resolve any such merge failure
-and run `git rebase --continue`. Another option is to bypass the commit
-that caused the merge failure with `git rebase --skip`. To check out the
-original `<branch>` and remove the `.git/rebase-apply` working files, use
-the command `git rebase --abort` instead.
-
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
@@ -183,28 +197,6 @@ This is useful if F and G were flawed in some way, or should not be
part of topicA. Note that the argument to `--onto` and the `<upstream>`
parameter can be any valid commit-ish.
-In case of conflict, `git rebase` will stop at the first problematic commit
-and leave conflict markers in the tree. You can use `git diff` to locate
-the markers (<<<<<<) and make edits to resolve the conflict. For each
-file you edit, you need to tell Git that the conflict has been resolved,
-typically this would be done with
-
-
- git add <filename>
-
-
-After resolving the conflict manually and updating the index with the
-desired resolution, you can continue the rebasing process with
-
-
- git rebase --continue
-
-
-Alternatively, you can undo the 'git rebase' with
-
-
- git rebase --abort
-
MODE OPTIONS
------------
--
gitgitgadget
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v3 3/5] doc: git rebase: clarify arguments syntax
2025-08-08 22:52 ` [PATCH v3 0/5] doc: git-rebase: clarify DESCRIPTION section Julia Evans via GitGitGadget
2025-08-08 22:52 ` [PATCH v3 1/5] doc: git-rebase: start with an example Julia Evans via GitGitGadget
2025-08-08 22:52 ` [PATCH v3 2/5] doc: git rebase: dedup merge conflict discussion Julia Evans via GitGitGadget
@ 2025-08-08 22:52 ` Julia Evans via GitGitGadget
2025-08-08 22:52 ` [PATCH v3 4/5] doc: git-rebase: move --onto explanation down Julia Evans via GitGitGadget
` (2 subsequent siblings)
5 siblings, 0 replies; 103+ messages in thread
From: Julia Evans via GitGitGadget @ 2025-08-08 22:52 UTC (permalink / raw)
To: git; +Cc: Julia Evans, Julia Evans
From: Julia Evans <julia@jvns.ca>
Remove duplicate explanation of `git rebase <upstream> <branch>` which
is already explained above.
Signed-off-by: Julia Evans <julia@jvns.ca>
---
Documentation/git-rebase.adoc | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc
index a93c616f38b1..e700b92e35ac 100644
--- a/Documentation/git-rebase.adoc
+++ b/Documentation/git-rebase.adoc
@@ -59,12 +59,7 @@ 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.
-
-If `<upstream>` is not specified, the upstream configured in
+If you don't specify an `<upstream>` to rebase onto, the upstream configured in
`branch.<name>.remote` and `branch.<name>.merge` options will be used (see
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
--
gitgitgadget
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v3 4/5] doc: git-rebase: move --onto explanation down
2025-08-08 22:52 ` [PATCH v3 0/5] doc: git-rebase: clarify DESCRIPTION section Julia Evans via GitGitGadget
` (2 preceding siblings ...)
2025-08-08 22:52 ` [PATCH v3 3/5] doc: git rebase: clarify arguments syntax Julia Evans via GitGitGadget
@ 2025-08-08 22:52 ` Julia Evans via GitGitGadget
2025-08-08 22:52 ` [PATCH v3 5/5] doc: git-rebase: update discussion of internals Julia Evans via GitGitGadget
2025-08-09 1:14 ` [PATCH v4 0/5] doc: git-rebase: clarify DESCRIPTION section Julia Evans via GitGitGadget
5 siblings, 0 replies; 103+ messages in thread
From: Julia Evans via GitGitGadget @ 2025-08-08 22:52 UTC (permalink / raw)
To: git; +Cc: Julia Evans, Julia Evans
From: Julia Evans <julia@jvns.ca>
There's a very clear explanation with examples of using --onto which is
currently buried in the very long DESCRIPTION section. This moves it to
its own section, so that we can reference the explanation from the
`--onto` option by name.
Signed-off-by: Julia Evans <julia@jvns.ca>
---
Documentation/git-rebase.adoc | 168 ++++++++++++++++++----------------
1 file changed, 87 insertions(+), 81 deletions(-)
diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc
index e700b92e35ac..6a4b3dbd5960 100644
--- a/Documentation/git-rebase.adoc
+++ b/Documentation/git-rebase.adoc
@@ -111,87 +111,6 @@ will result in:
D---E---A'---F master
------------
-Here is how you would transplant a topic branch based on one
-branch to another, to pretend that you forked the topic branch
-from the latter branch, using `rebase --onto`.
-
-First let's assume your 'topic' is based on branch 'next'.
-For example, a feature developed in 'topic' depends on some
-functionality which is found in 'next'.
-
-------------
- o---o---o---o---o master
- \
- o---o---o---o---o next
- \
- o---o---o topic
-------------
-
-We want to make 'topic' forked from branch 'master'; for example,
-because the functionality on which 'topic' depends was merged into the
-more stable 'master' branch. We want our tree to look like this:
-
-------------
- o---o---o---o---o master
- | \
- | o'--o'--o' topic
- \
- o---o---o---o---o next
-------------
-
-We can get this using the following command:
-
- git rebase --onto master next topic
-
-
-Another example of --onto option is to rebase part of a
-branch. If we have the following situation:
-
-------------
- H---I---J topicB
- /
- E---F---G topicA
- /
- A---B---C---D master
-------------
-
-then the command
-
- git rebase --onto master topicA topicB
-
-would result in:
-
-------------
- H'--I'--J' topicB
- /
- | E---F---G topicA
- |/
- A---B---C---D master
-------------
-
-This is useful when topicB does not depend on topicA.
-
-A range of commits could also be removed with rebase. If we have
-the following situation:
-
-------------
- E---F---G---H---I---J topicA
-------------
-
-then the command
-
- git rebase --onto topicA~5 topicA~3 topicA
-
-would result in the removal of commits F and G:
-
-------------
- E---H'---I'---J' topicA
-------------
-
-This is useful if F and G were flawed in some way, or should not be
-part of topicA. Note that the argument to `--onto` and the `<upstream>`
-parameter can be any valid commit-ish.
-
MODE OPTIONS
------------
@@ -237,6 +156,8 @@ As a special case, you may use "A\...B" as a shortcut for the
merge base of A and B if there is exactly one merge base. You can
leave out at most one of A and B, in which case it defaults to HEAD.
+See TRANSPLANTING A TOPIC BRANCH WITH --ONTO below for examples.
+
--keep-base::
Set the starting point at which to create the new commits to the
merge base of `<upstream>` and `<branch>`. Running
@@ -1015,6 +936,91 @@ consistent (they compile, pass the testsuite, etc.) you should use
after each commit, test, and amend the commit if fixes are necessary.
+TRANSPLANTING A TOPIC BRANCH WITH --ONTO
+----------------------------------------
+
+Here is how you would transplant a topic branch based on one
+branch to another, to pretend that you forked the topic branch
+from the latter branch, using `rebase --onto`.
+
+First let's assume your 'topic' is based on branch 'next'.
+For example, a feature developed in 'topic' depends on some
+functionality which is found in 'next'.
+
+------------
+ o---o---o---o---o master
+ \
+ o---o---o---o---o next
+ \
+ o---o---o topic
+------------
+
+We want to make 'topic' forked from branch 'master'; for example,
+because the functionality on which 'topic' depends was merged into the
+more stable 'master' branch. We want our tree to look like this:
+
+------------
+ o---o---o---o---o master
+ | \
+ | o'--o'--o' topic
+ \
+ o---o---o---o---o next
+------------
+
+We can get this using the following command:
+
+ git rebase --onto master next topic
+
+
+Another example of --onto option is to rebase part of a
+branch. If we have the following situation:
+
+------------
+ H---I---J topicB
+ /
+ E---F---G topicA
+ /
+ A---B---C---D master
+------------
+
+then the command
+
+ git rebase --onto master topicA topicB
+
+would result in:
+
+------------
+ H'--I'--J' topicB
+ /
+ | E---F---G topicA
+ |/
+ A---B---C---D master
+------------
+
+This is useful when topicB does not depend on topicA.
+
+A range of commits could also be removed with rebase. If we have
+the following situation:
+
+------------
+ E---F---G---H---I---J topicA
+------------
+
+then the command
+
+ git rebase --onto topicA~5 topicA~3 topicA
+
+would result in the removal of commits F and G:
+
+------------
+ E---H'---I'---J' topicA
+------------
+
+This is useful if F and G were flawed in some way, or should not be
+part of topicA. Note that the argument to `--onto` and the `<upstream>`
+parameter can be any valid commit-ish.
+
+
RECOVERING FROM UPSTREAM REBASE
-------------------------------
--
gitgitgadget
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v3 5/5] doc: git-rebase: update discussion of internals
2025-08-08 22:52 ` [PATCH v3 0/5] doc: git-rebase: clarify DESCRIPTION section Julia Evans via GitGitGadget
` (3 preceding siblings ...)
2025-08-08 22:52 ` [PATCH v3 4/5] doc: git-rebase: move --onto explanation down Julia Evans via GitGitGadget
@ 2025-08-08 22:52 ` Julia Evans via GitGitGadget
2025-08-09 1:14 ` [PATCH v4 0/5] doc: git-rebase: clarify DESCRIPTION section Julia Evans via GitGitGadget
5 siblings, 0 replies; 103+ messages in thread
From: Julia Evans via GitGitGadget @ 2025-08-08 22:52 UTC (permalink / raw)
To: git; +Cc: Julia Evans, Julia Evans
From: Julia Evans <julia@jvns.ca>
- 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)
- 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 <julia@jvns.ca>
---
Documentation/git-rebase.adoc | 34 +++++++++++++++++-----------------
1 file changed, 17 insertions(+), 17 deletions(-)
diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc
index 6a4b3dbd5960..df77bbdecfec 100644
--- a/Documentation/git-rebase.adoc
+++ b/Documentation/git-rebase.adoc
@@ -65,31 +65,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:
+
+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>`.
[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]).
-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
--
gitgitgadget
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [PATCH v2 1/5] doc: git-rebase: start with an example
2025-08-08 19:15 ` [PATCH v2 1/5] doc: git-rebase: start with an example Julia Evans via GitGitGadget
@ 2025-08-08 23:31 ` Junio C Hamano
0 siblings, 0 replies; 103+ messages in thread
From: Junio C Hamano @ 2025-08-08 23:31 UTC (permalink / raw)
To: Julia Evans via GitGitGadget; +Cc: git, Julia Evans
"Julia Evans via GitGitGadget" <gitgitgadget@gmail.com> writes:
> +Transplant a series of commits onto a different starting point.
> +
> +For example, imagine that you have been working on the `topic` branch in this
> +history, and you want to "catch up" to the work done on the `master` branch.
> +
> +------------
> + A---B---C topic
> + /
> + D---E---F---G master
> +------------
> +
> +You want to transplant the commits you made on `topic` since it diverged from
> +`master` (i.e. A, B, and C), on top of the current `master`. You can do this
> +by running `git rebase master` while the `topic` branch is checked out. If you
> +want to rebase `topic` while on another branch, `git rebase master topic` is a
> +short-cut for `git switch topic && git rebase master`.
s/switch/checkout/, as that is how the original defines the short-cut.
> +------------
> + A'--B'--C' topic
> + /
> + D---E---F---G master
> +------------
> +
Other than that, looks great.
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v4 0/5] doc: git-rebase: clarify DESCRIPTION section
2025-08-08 22:52 ` [PATCH v3 0/5] doc: git-rebase: clarify DESCRIPTION section Julia Evans via GitGitGadget
` (4 preceding siblings ...)
2025-08-08 22:52 ` [PATCH v3 5/5] doc: git-rebase: update discussion of internals Julia Evans via GitGitGadget
@ 2025-08-09 1:14 ` Julia Evans via GitGitGadget
2025-08-09 1:14 ` [PATCH v4 1/5] doc: git-rebase: start with an example Julia Evans via GitGitGadget
` (5 more replies)
5 siblings, 6 replies; 103+ messages in thread
From: Julia Evans via GitGitGadget @ 2025-08-09 1:14 UTC (permalink / raw)
To: git; +Cc: Julia Evans
Replaced git switch topic && git rebase master with git checkout topic &&
git rebase master
Also "short-cut" with "shortcut" which is the spelling used elsewhere in the
man pages
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 | 300 ++++++++++++++++------------------
1 file changed, 145 insertions(+), 155 deletions(-)
base-commit: 2c2ba49d55ff26c1082b8137b1ec5eeccb4337d1
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1949%2Fjvns%2Fclarify-rebase-v4
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1949/jvns/clarify-rebase-v4
Pull-Request: https://github.com/gitgitgadget/git/pull/1949
Range-diff vs v3:
1: 26b742eb49f ! 1: 07a4bdb7ce5 doc: git-rebase: start with an example
@@ Documentation/git-rebase.adoc: SYNOPSIS
+`master` (i.e. A, B, and C), on top of the current `master`. You can do this
+by running `git rebase master` while the `topic` branch is checked out. If you
+want to rebase `topic` while on another branch, `git rebase master topic` is a
-+short-cut for `git switch topic && git rebase master`.
++shortcut for `git checkout topic && git rebase master`.
+
+------------
+ A'--B'--C' topic
2: 249a5127904 ! 2: 061790686b9 doc: git rebase: dedup merge conflict discussion
@@ Commit message
Signed-off-by: Julia Evans <julia@jvns.ca>
## Documentation/git-rebase.adoc ##
-@@ Documentation/git-rebase.adoc: short-cut for `git switch topic && git rebase master`.
+@@ Documentation/git-rebase.adoc: shortcut for `git checkout topic && git rebase master`.
D---E---F---G master
------------
3: 013a5044ef3 = 3: fe9e161a51b doc: git rebase: clarify arguments syntax
4: c574a27412d = 4: b37ebc8389d doc: git-rebase: move --onto explanation down
5: eabacd3c159 = 5: 105a65e6e71 doc: git-rebase: update discussion of internals
--
gitgitgadget
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v4 1/5] doc: git-rebase: start with an example
2025-08-09 1:14 ` [PATCH v4 0/5] doc: git-rebase: clarify DESCRIPTION section Julia Evans via GitGitGadget
@ 2025-08-09 1:14 ` Julia Evans via GitGitGadget
2025-08-10 15:41 ` Phillip Wood
` (2 more replies)
2025-08-09 1:14 ` [PATCH v4 2/5] doc: git rebase: dedup merge conflict discussion Julia Evans via GitGitGadget
` (4 subsequent siblings)
5 siblings, 3 replies; 103+ messages in thread
From: Julia Evans via GitGitGadget @ 2025-08-09 1:14 UTC (permalink / raw)
To: git; +Cc: Julia Evans, Julia Evans
From: Julia Evans <julia@jvns.ca>
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.
Signed-off-by: Julia Evans <julia@jvns.ca>
---
Documentation/git-rebase.adoc | 49 ++++++++++++++++-------------------
1 file changed, 23 insertions(+), 26 deletions(-)
diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc
index 956d3048f5a6..449f01fba560 100644
--- a/Documentation/git-rebase.adoc
+++ b/Documentation/git-rebase.adoc
@@ -16,6 +16,29 @@ SYNOPSIS
DESCRIPTION
-----------
+Transplant a series of commits onto a different starting point.
+
+For example, imagine that you have been working on the `topic` branch in this
+history, and you want to "catch up" to the work done on the `master` branch.
+
+------------
+ A---B---C topic
+ /
+ D---E---F---G master
+------------
+
+You want to transplant the commits you made on `topic` since it diverged from
+`master` (i.e. A, B, and C), on top of the current `master`. You can do this
+by running `git rebase master` while the `topic` branch is checked out. If you
+want to rebase `topic` while on another branch, `git rebase master topic` is a
+shortcut for `git checkout topic && git rebase master`.
+
+------------
+ A'--B'--C' topic
+ /
+ D---E---F---G master
+------------
+
If `<branch>` is specified, `git rebase` will perform an automatic
`git switch <branch>` before doing anything else. Otherwise
it remains on the current branch.
@@ -58,32 +81,6 @@ that caused the merge failure with `git rebase --skip`. To check out the
original `<branch>` and remove the `.git/rebase-apply` working files, use
the command `git rebase --abort` instead.
-Assume the following history exists and the current branch is "topic":
-
-------------
- A---B---C topic
- /
- D---E---F---G master
-------------
-
-From this point, the result of either of the following commands:
-
-
- git rebase master
- git rebase master topic
-
-would be:
-
-------------
- A'--B'--C' topic
- /
- D---E---F---G master
-------------
-
-*NOTE:* The latter form is just a short-hand of `git checkout topic`
-followed by `git rebase master`. When rebase exits `topic` will
-remain the checked-out branch.
-
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
--
gitgitgadget
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v4 2/5] doc: git rebase: dedup merge conflict discussion
2025-08-09 1:14 ` [PATCH v4 0/5] doc: git-rebase: clarify DESCRIPTION section Julia Evans via GitGitGadget
2025-08-09 1:14 ` [PATCH v4 1/5] doc: git-rebase: start with an example Julia Evans via GitGitGadget
@ 2025-08-09 1:14 ` Julia Evans via GitGitGadget
2025-08-11 8:46 ` Patrick Steinhardt
2025-08-09 1:14 ` [PATCH v4 3/5] doc: git rebase: clarify arguments syntax Julia Evans via GitGitGadget
` (3 subsequent siblings)
5 siblings, 1 reply; 103+ messages in thread
From: Julia Evans via GitGitGadget @ 2025-08-09 1:14 UTC (permalink / raw)
To: git; +Cc: Julia Evans, Julia Evans
From: Julia Evans <julia@jvns.ca>
Previously there were two explanations, this combines them both into a
single explanation.
Signed-off-by: Julia Evans <julia@jvns.ca>
---
Documentation/git-rebase.adoc | 50 +++++++++++++++--------------------
1 file changed, 21 insertions(+), 29 deletions(-)
diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc
index 449f01fba560..e30b9535fff1 100644
--- a/Documentation/git-rebase.adoc
+++ b/Documentation/git-rebase.adoc
@@ -39,6 +39,27 @@ shortcut for `git checkout topic && git rebase master`.
D---E---F---G master
------------
+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
+one of these things:
+
+1. Resolve the conflict. You can use `git diff` to find the markers (<<<<<<)
+ and make edits to resolve the conflict. For each file you edit, you need to
+ tell Git that the conflict has been resolved. You can mark the conflict as
+ resolved with `git add <filename>`. After resolving all of the conflicts,
+ you can continue the rebasing process with
+
+ git rebase --continue
+
+2. Stop the `git rebase` and return your branch to its original state with
+
+ git rebase --abort
+
+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
it remains on the current branch.
@@ -74,13 +95,6 @@ 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).
-It is possible that a merge failure will prevent this process from being
-completely automatic. You will have to resolve any such merge failure
-and run `git rebase --continue`. Another option is to bypass the commit
-that caused the merge failure with `git rebase --skip`. To check out the
-original `<branch>` and remove the `.git/rebase-apply` working files, use
-the command `git rebase --abort` instead.
-
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
@@ -183,28 +197,6 @@ This is useful if F and G were flawed in some way, or should not be
part of topicA. Note that the argument to `--onto` and the `<upstream>`
parameter can be any valid commit-ish.
-In case of conflict, `git rebase` will stop at the first problematic commit
-and leave conflict markers in the tree. You can use `git diff` to locate
-the markers (<<<<<<) and make edits to resolve the conflict. For each
-file you edit, you need to tell Git that the conflict has been resolved,
-typically this would be done with
-
-
- git add <filename>
-
-
-After resolving the conflict manually and updating the index with the
-desired resolution, you can continue the rebasing process with
-
-
- git rebase --continue
-
-
-Alternatively, you can undo the 'git rebase' with
-
-
- git rebase --abort
-
MODE OPTIONS
------------
--
gitgitgadget
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v4 3/5] doc: git rebase: clarify arguments syntax
2025-08-09 1:14 ` [PATCH v4 0/5] doc: git-rebase: clarify DESCRIPTION section Julia Evans via GitGitGadget
2025-08-09 1:14 ` [PATCH v4 1/5] doc: git-rebase: start with an example Julia Evans via GitGitGadget
2025-08-09 1:14 ` [PATCH v4 2/5] doc: git rebase: dedup merge conflict discussion Julia Evans via GitGitGadget
@ 2025-08-09 1:14 ` Julia Evans via GitGitGadget
2025-08-09 1:14 ` [PATCH v4 4/5] doc: git-rebase: move --onto explanation down Julia Evans via GitGitGadget
` (2 subsequent siblings)
5 siblings, 0 replies; 103+ messages in thread
From: Julia Evans via GitGitGadget @ 2025-08-09 1:14 UTC (permalink / raw)
To: git; +Cc: Julia Evans, Julia Evans
From: Julia Evans <julia@jvns.ca>
Remove duplicate explanation of `git rebase <upstream> <branch>` which
is already explained above.
Signed-off-by: Julia Evans <julia@jvns.ca>
---
Documentation/git-rebase.adoc | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc
index e30b9535fff1..914f743ae00f 100644
--- a/Documentation/git-rebase.adoc
+++ b/Documentation/git-rebase.adoc
@@ -59,12 +59,7 @@ 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.
-
-If `<upstream>` is not specified, the upstream configured in
+If you don't specify an `<upstream>` to rebase onto, the upstream configured in
`branch.<name>.remote` and `branch.<name>.merge` options will be used (see
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
--
gitgitgadget
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v4 4/5] doc: git-rebase: move --onto explanation down
2025-08-09 1:14 ` [PATCH v4 0/5] doc: git-rebase: clarify DESCRIPTION section Julia Evans via GitGitGadget
` (2 preceding siblings ...)
2025-08-09 1:14 ` [PATCH v4 3/5] doc: git rebase: clarify arguments syntax Julia Evans via GitGitGadget
@ 2025-08-09 1:14 ` Julia Evans via GitGitGadget
2025-08-09 14:55 ` D. Ben Knoble
2025-08-09 1:14 ` [PATCH v4 5/5] doc: git-rebase: update discussion of internals Julia Evans via GitGitGadget
2025-08-11 20:12 ` [PATCH v5 0/5] doc: git-rebase: clarify DESCRIPTION section Julia Evans via GitGitGadget
5 siblings, 1 reply; 103+ messages in thread
From: Julia Evans via GitGitGadget @ 2025-08-09 1:14 UTC (permalink / raw)
To: git; +Cc: Julia Evans, Julia Evans
From: Julia Evans <julia@jvns.ca>
There's a very clear explanation with examples of using --onto which is
currently buried in the very long DESCRIPTION section. This moves it to
its own section, so that we can reference the explanation from the
`--onto` option by name.
Signed-off-by: Julia Evans <julia@jvns.ca>
---
Documentation/git-rebase.adoc | 168 ++++++++++++++++++----------------
1 file changed, 87 insertions(+), 81 deletions(-)
diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc
index 914f743ae00f..50c84f138212 100644
--- a/Documentation/git-rebase.adoc
+++ b/Documentation/git-rebase.adoc
@@ -111,87 +111,6 @@ will result in:
D---E---A'---F master
------------
-Here is how you would transplant a topic branch based on one
-branch to another, to pretend that you forked the topic branch
-from the latter branch, using `rebase --onto`.
-
-First let's assume your 'topic' is based on branch 'next'.
-For example, a feature developed in 'topic' depends on some
-functionality which is found in 'next'.
-
-------------
- o---o---o---o---o master
- \
- o---o---o---o---o next
- \
- o---o---o topic
-------------
-
-We want to make 'topic' forked from branch 'master'; for example,
-because the functionality on which 'topic' depends was merged into the
-more stable 'master' branch. We want our tree to look like this:
-
-------------
- o---o---o---o---o master
- | \
- | o'--o'--o' topic
- \
- o---o---o---o---o next
-------------
-
-We can get this using the following command:
-
- git rebase --onto master next topic
-
-
-Another example of --onto option is to rebase part of a
-branch. If we have the following situation:
-
-------------
- H---I---J topicB
- /
- E---F---G topicA
- /
- A---B---C---D master
-------------
-
-then the command
-
- git rebase --onto master topicA topicB
-
-would result in:
-
-------------
- H'--I'--J' topicB
- /
- | E---F---G topicA
- |/
- A---B---C---D master
-------------
-
-This is useful when topicB does not depend on topicA.
-
-A range of commits could also be removed with rebase. If we have
-the following situation:
-
-------------
- E---F---G---H---I---J topicA
-------------
-
-then the command
-
- git rebase --onto topicA~5 topicA~3 topicA
-
-would result in the removal of commits F and G:
-
-------------
- E---H'---I'---J' topicA
-------------
-
-This is useful if F and G were flawed in some way, or should not be
-part of topicA. Note that the argument to `--onto` and the `<upstream>`
-parameter can be any valid commit-ish.
-
MODE OPTIONS
------------
@@ -237,6 +156,8 @@ As a special case, you may use "A\...B" as a shortcut for the
merge base of A and B if there is exactly one merge base. You can
leave out at most one of A and B, in which case it defaults to HEAD.
+See TRANSPLANTING A TOPIC BRANCH WITH --ONTO below for examples.
+
--keep-base::
Set the starting point at which to create the new commits to the
merge base of `<upstream>` and `<branch>`. Running
@@ -1015,6 +936,91 @@ consistent (they compile, pass the testsuite, etc.) you should use
after each commit, test, and amend the commit if fixes are necessary.
+TRANSPLANTING A TOPIC BRANCH WITH --ONTO
+----------------------------------------
+
+Here is how you would transplant a topic branch based on one
+branch to another, to pretend that you forked the topic branch
+from the latter branch, using `rebase --onto`.
+
+First let's assume your 'topic' is based on branch 'next'.
+For example, a feature developed in 'topic' depends on some
+functionality which is found in 'next'.
+
+------------
+ o---o---o---o---o master
+ \
+ o---o---o---o---o next
+ \
+ o---o---o topic
+------------
+
+We want to make 'topic' forked from branch 'master'; for example,
+because the functionality on which 'topic' depends was merged into the
+more stable 'master' branch. We want our tree to look like this:
+
+------------
+ o---o---o---o---o master
+ | \
+ | o'--o'--o' topic
+ \
+ o---o---o---o---o next
+------------
+
+We can get this using the following command:
+
+ git rebase --onto master next topic
+
+
+Another example of --onto option is to rebase part of a
+branch. If we have the following situation:
+
+------------
+ H---I---J topicB
+ /
+ E---F---G topicA
+ /
+ A---B---C---D master
+------------
+
+then the command
+
+ git rebase --onto master topicA topicB
+
+would result in:
+
+------------
+ H'--I'--J' topicB
+ /
+ | E---F---G topicA
+ |/
+ A---B---C---D master
+------------
+
+This is useful when topicB does not depend on topicA.
+
+A range of commits could also be removed with rebase. If we have
+the following situation:
+
+------------
+ E---F---G---H---I---J topicA
+------------
+
+then the command
+
+ git rebase --onto topicA~5 topicA~3 topicA
+
+would result in the removal of commits F and G:
+
+------------
+ E---H'---I'---J' topicA
+------------
+
+This is useful if F and G were flawed in some way, or should not be
+part of topicA. Note that the argument to `--onto` and the `<upstream>`
+parameter can be any valid commit-ish.
+
+
RECOVERING FROM UPSTREAM REBASE
-------------------------------
--
gitgitgadget
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v4 5/5] doc: git-rebase: update discussion of internals
2025-08-09 1:14 ` [PATCH v4 0/5] doc: git-rebase: clarify DESCRIPTION section Julia Evans via GitGitGadget
` (3 preceding siblings ...)
2025-08-09 1:14 ` [PATCH v4 4/5] doc: git-rebase: move --onto explanation down Julia Evans via GitGitGadget
@ 2025-08-09 1:14 ` Julia Evans via GitGitGadget
2025-08-10 15:42 ` Phillip Wood
2025-08-11 8:46 ` [PATCH v4 5/5] doc: git-rebase: update discussion of internals Patrick Steinhardt
2025-08-11 20:12 ` [PATCH v5 0/5] doc: git-rebase: clarify DESCRIPTION section Julia Evans via GitGitGadget
5 siblings, 2 replies; 103+ messages in thread
From: Julia Evans via GitGitGadget @ 2025-08-09 1:14 UTC (permalink / raw)
To: git; +Cc: Julia Evans, Julia Evans
From: Julia Evans <julia@jvns.ca>
- 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)
- 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 <julia@jvns.ca>
---
Documentation/git-rebase.adoc | 34 +++++++++++++++++-----------------
1 file changed, 17 insertions(+), 17 deletions(-)
diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc
index 50c84f138212..c16ee37b46a7 100644
--- a/Documentation/git-rebase.adoc
+++ b/Documentation/git-rebase.adoc
@@ -65,31 +65,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:
+
+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>`.
[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]).
-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
--
gitgitgadget
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [PATCH v4 4/5] doc: git-rebase: move --onto explanation down
2025-08-09 1:14 ` [PATCH v4 4/5] doc: git-rebase: move --onto explanation down Julia Evans via GitGitGadget
@ 2025-08-09 14:55 ` D. Ben Knoble
0 siblings, 0 replies; 103+ messages in thread
From: D. Ben Knoble @ 2025-08-09 14:55 UTC (permalink / raw)
To: Julia Evans via GitGitGadget; +Cc: git, Julia Evans
On Fri, Aug 8, 2025 at 9:14 PM Julia Evans via GitGitGadget
<gitgitgadget@gmail.com> wrote:
>
> From: Julia Evans <julia@jvns.ca>
>
> There's a very clear explanation with examples of using --onto which is
> currently buried in the very long DESCRIPTION section. This moves it to
> its own section, so that we can reference the explanation from the
> `--onto` option by name.
>
> Signed-off-by: Julia Evans <julia@jvns.ca>
> ---
> Documentation/git-rebase.adoc | 168 ++++++++++++++++++----------------
> 1 file changed, 87 insertions(+), 81 deletions(-)
>
> diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc
> index 914f743ae00f..50c84f138212 100644
> --- a/Documentation/git-rebase.adoc
> +++ b/Documentation/git-rebase.adoc
> @@ -111,87 +111,6 @@ will result in:
> D---E---A'---F master
> ------------
>
> -Here is how you would transplant a topic branch based on one
> -branch to another, to pretend that you forked the topic branch
> -from the latter branch, using `rebase --onto`.
I wonder if we should leave a pointer to the reader to the new section
here, also? The onto mode is not quite as common in my workflow as the
other modes, but when helping less experienced users out I often end
up using it, so keeping some reference to it early might be nice. IDK
where a natural point is, though.
> -
> -First let's assume your 'topic' is based on branch 'next'.
> -For example, a feature developed in 'topic' depends on some
> -functionality which is found in 'next'.
> -
> -------------
> - o---o---o---o---o master
> - \
> - o---o---o---o---o next
> - \
> - o---o---o topic
> -------------
> -
> -We want to make 'topic' forked from branch 'master'; for example,
> -because the functionality on which 'topic' depends was merged into the
> -more stable 'master' branch. We want our tree to look like this:
> -
> -------------
> - o---o---o---o---o master
> - | \
> - | o'--o'--o' topic
> - \
> - o---o---o---o---o next
> -------------
> -
> -We can get this using the following command:
> -
> - git rebase --onto master next topic
> -
> -
> -Another example of --onto option is to rebase part of a
> -branch. If we have the following situation:
> -
> -------------
> - H---I---J topicB
> - /
> - E---F---G topicA
> - /
> - A---B---C---D master
> -------------
> -
> -then the command
> -
> - git rebase --onto master topicA topicB
> -
> -would result in:
> -
> -------------
> - H'--I'--J' topicB
> - /
> - | E---F---G topicA
> - |/
> - A---B---C---D master
> -------------
> -
> -This is useful when topicB does not depend on topicA.
> -
> -A range of commits could also be removed with rebase. If we have
> -the following situation:
> -
> -------------
> - E---F---G---H---I---J topicA
> -------------
> -
> -then the command
> -
> - git rebase --onto topicA~5 topicA~3 topicA
> -
> -would result in the removal of commits F and G:
> -
> -------------
> - E---H'---I'---J' topicA
> -------------
> -
> -This is useful if F and G were flawed in some way, or should not be
> -part of topicA. Note that the argument to `--onto` and the `<upstream>`
> -parameter can be any valid commit-ish.
> -
> MODE OPTIONS
> ------------
>
> @@ -237,6 +156,8 @@ As a special case, you may use "A\...B" as a shortcut for the
> merge base of A and B if there is exactly one merge base. You can
> leave out at most one of A and B, in which case it defaults to HEAD.
>
> +See TRANSPLANTING A TOPIC BRANCH WITH --ONTO below for examples.
> +
> --keep-base::
> Set the starting point at which to create the new commits to the
> merge base of `<upstream>` and `<branch>`. Running
> @@ -1015,6 +936,91 @@ consistent (they compile, pass the testsuite, etc.) you should use
> after each commit, test, and amend the commit if fixes are necessary.
>
>
> +TRANSPLANTING A TOPIC BRANCH WITH --ONTO
> +----------------------------------------
> +
> +Here is how you would transplant a topic branch based on one
> +branch to another, to pretend that you forked the topic branch
> +from the latter branch, using `rebase --onto`.
> +
> +First let's assume your 'topic' is based on branch 'next'.
> +For example, a feature developed in 'topic' depends on some
> +functionality which is found in 'next'.
> +
> +------------
> + o---o---o---o---o master
> + \
> + o---o---o---o---o next
> + \
> + o---o---o topic
> +------------
> +
> +We want to make 'topic' forked from branch 'master'; for example,
> +because the functionality on which 'topic' depends was merged into the
> +more stable 'master' branch. We want our tree to look like this:
> +
> +------------
> + o---o---o---o---o master
> + | \
> + | o'--o'--o' topic
> + \
> + o---o---o---o---o next
> +------------
> +
> +We can get this using the following command:
> +
> + git rebase --onto master next topic
> +
> +
> +Another example of --onto option is to rebase part of a
> +branch. If we have the following situation:
> +
> +------------
> + H---I---J topicB
> + /
> + E---F---G topicA
> + /
> + A---B---C---D master
> +------------
> +
> +then the command
> +
> + git rebase --onto master topicA topicB
> +
> +would result in:
> +
> +------------
> + H'--I'--J' topicB
> + /
> + | E---F---G topicA
> + |/
> + A---B---C---D master
> +------------
> +
> +This is useful when topicB does not depend on topicA.
> +
> +A range of commits could also be removed with rebase. If we have
> +the following situation:
> +
> +------------
> + E---F---G---H---I---J topicA
> +------------
> +
> +then the command
> +
> + git rebase --onto topicA~5 topicA~3 topicA
> +
> +would result in the removal of commits F and G:
> +
> +------------
> + E---H'---I'---J' topicA
> +------------
> +
> +This is useful if F and G were flawed in some way, or should not be
> +part of topicA. Note that the argument to `--onto` and the `<upstream>`
> +parameter can be any valid commit-ish.
> +
> +
> RECOVERING FROM UPSTREAM REBASE
> -------------------------------
>
> --
> gitgitgadget
>
>
--
D. Ben Knoble
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [PATCH v2 0/5] doc: git-rebase: clarify DESCRIPTION section
2025-08-08 19:15 ` [PATCH v2 0/5] doc: git-rebase: clarify DESCRIPTION section Julia Evans via GitGitGadget
` (5 preceding siblings ...)
2025-08-08 22:52 ` [PATCH v3 0/5] doc: git-rebase: clarify DESCRIPTION section Julia Evans via GitGitGadget
@ 2025-08-09 15:04 ` D. Ben Knoble
6 siblings, 0 replies; 103+ messages in thread
From: D. Ben Knoble @ 2025-08-09 15:04 UTC (permalink / raw)
To: Julia Evans via GitGitGadget; +Cc: git, Julia Evans
On Fri, Aug 8, 2025 at 3:15 PM Julia Evans via GitGitGadget
<gitgitgadget@gmail.com> wrote:
>
> Thanks for the review comments, here are the new changes which:
>
> * make the intro to the man page less dry, with the suggested wording
> * clarify the merge conflict resolution explanation & fix the HTML
> formatting issues
> * move the explanation of the git rebase <upstream> <branch> syntax up into
> the intro
>
> I'm still curious about the intention for the git rebase master topic
> syntax, since I'd never heard of it before. Is it just to save on typing,
> since it's fewer characters than git switch topic and then git rebase
> master? I ask because someone mentioned to me on Mastodon
> (https://hachyderm.io/@simontatham/114988051822317920) that they sometimes
> use git rebase HEAD main as part of their workflow, which is not equivalent
> to git checkout main && git rebase HEAD. That made me think that there might
> be some broader intent to enable rebases that wouldn't otherwise be possible
> without that syntax.
I think the intent really is "shortcut." It's existed since the first
version of rebase (59e6b23ace ([PATCH] git-rebase-script: rebase local
commits to new upstream head., 2005-06-25),
https://lore.kernel.org/git/7v4qboejp6.fsf_-_@assigned-by-dhcp.cox.net/).
I didn't look too closely at that mailing list thread for any
justification of the shortcut, though.
The example mentioned on Mastodon is still a shortcut, it's just more
like a function than a macro (that is, the arguments are evaluated
first, then the shortcut applied):
git rebase HEAD main
becomes (in shell syntax)
head=$(git rev-parse HEAD)
git switch --detach main
git rebase $head
rather than
git switch --detach main
git rebase HEAD # too late, HEAD has changed
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [PATCH v4 1/5] doc: git-rebase: start with an example
2025-08-09 1:14 ` [PATCH v4 1/5] doc: git-rebase: start with an example Julia Evans via GitGitGadget
@ 2025-08-10 15:41 ` Phillip Wood
2025-08-11 8:46 ` Patrick Steinhardt
2025-08-11 9:13 ` Karthik Nayak
2 siblings, 0 replies; 103+ messages in thread
From: Phillip Wood @ 2025-08-10 15:41 UTC (permalink / raw)
To: Julia Evans via GitGitGadget, git; +Cc: Julia Evans
Hi Julia
On 09/08/2025 02:14, Julia Evans via GitGitGadget wrote:
> From: Julia Evans <julia@jvns.ca>
>
> 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.
This is a very welcome improvement which makes it clear what rebasing a
branch does. There are other important uses of rebase such as
rearranging commits and squashing fixup commits that it would be nice to
mention early on in the man page as well. Those do not necessarily
change the base of the branch. I wonder if we could add a sentence about
that which links to the INTERACTIVE MODE section.
Thanks
Phillip
> Signed-off-by: Julia Evans <julia@jvns.ca>
> ---
> Documentation/git-rebase.adoc | 49 ++++++++++++++++-------------------
> 1 file changed, 23 insertions(+), 26 deletions(-)
>
> diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc
> index 956d3048f5a6..449f01fba560 100644
> --- a/Documentation/git-rebase.adoc
> +++ b/Documentation/git-rebase.adoc
> @@ -16,6 +16,29 @@ SYNOPSIS
>
> DESCRIPTION
> -----------
> +Transplant a series of commits onto a different starting point.
> +
> +For example, imagine that you have been working on the `topic` branch in this
> +history, and you want to "catch up" to the work done on the `master` branch.
> +
> +------------
> + A---B---C topic
> + /
> + D---E---F---G master
> +------------
> +
> +You want to transplant the commits you made on `topic` since it diverged from
> +`master` (i.e. A, B, and C), on top of the current `master`. You can do this
> +by running `git rebase master` while the `topic` branch is checked out. If you
> +want to rebase `topic` while on another branch, `git rebase master topic` is a
> +shortcut for `git checkout topic && git rebase master`.
> +
> +------------
> + A'--B'--C' topic
> + /
> + D---E---F---G master
> +------------
> +
> If `<branch>` is specified, `git rebase` will perform an automatic
> `git switch <branch>` before doing anything else. Otherwise
> it remains on the current branch.
> @@ -58,32 +81,6 @@ that caused the merge failure with `git rebase --skip`. To check out the
> original `<branch>` and remove the `.git/rebase-apply` working files, use
> the command `git rebase --abort` instead.
>
> -Assume the following history exists and the current branch is "topic":
> -
> -------------
> - A---B---C topic
> - /
> - D---E---F---G master
> -------------
> -
> -From this point, the result of either of the following commands:
> -
> -
> - git rebase master
> - git rebase master topic
> -
> -would be:
> -
> -------------
> - A'--B'--C' topic
> - /
> - D---E---F---G master
> -------------
> -
> -*NOTE:* The latter form is just a short-hand of `git checkout topic`
> -followed by `git rebase master`. When rebase exits `topic` will
> -remain the checked-out branch.
> -
> 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
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [PATCH v4 5/5] doc: git-rebase: update discussion of internals
2025-08-09 1:14 ` [PATCH v4 5/5] doc: git-rebase: update discussion of internals Julia Evans via GitGitGadget
@ 2025-08-10 15:42 ` Phillip Wood
2025-08-13 18:55 ` symmetric difference with --left-only vs. range notation D. Ben Knoble
2025-08-11 8:46 ` [PATCH v4 5/5] doc: git-rebase: update discussion of internals Patrick Steinhardt
1 sibling, 1 reply; 103+ messages in thread
From: Phillip Wood @ 2025-08-10 15:42 UTC (permalink / raw)
To: Julia Evans via GitGitGadget, git; +Cc: Julia Evans
Hi Julia
On 09/08/2025 02:14, Julia Evans via GitGitGadget wrote:
> From: Julia Evans <julia@jvns.ca>
>
> +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`.
The existing text is not quite accurate here, it should really say `git
log --cherry-pick --right-only <upstream>...HEAD` as we drop any commits
from the branch that have already been cherry-picked to <upstream>.
> You can use `--fork-point` or `--root` to change how this
> +list of commits is constructed.
`--reapply-cherry-picks` also changes how the list is constructed so I
think it would be worth adding that option here as well.
Thanks for working on this, it makes the description section much more
readable.
Phillip
> +
> +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>`.
>
> [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]).
>
> -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
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [PATCH v4 1/5] doc: git-rebase: start with an example
2025-08-09 1:14 ` [PATCH v4 1/5] doc: git-rebase: start with an example Julia Evans via GitGitGadget
2025-08-10 15:41 ` Phillip Wood
@ 2025-08-11 8:46 ` Patrick Steinhardt
2025-08-11 9:13 ` Karthik Nayak
2 siblings, 0 replies; 103+ messages in thread
From: Patrick Steinhardt @ 2025-08-11 8:46 UTC (permalink / raw)
To: Julia Evans via GitGitGadget; +Cc: git, Julia Evans
On Sat, Aug 09, 2025 at 01:14:13AM +0000, Julia Evans via GitGitGadget wrote:
> From: Julia Evans <julia@jvns.ca>
>
> 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.
Makes sense.
> diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc
> index 956d3048f5a6..449f01fba560 100644
> --- a/Documentation/git-rebase.adoc
> +++ b/Documentation/git-rebase.adoc
> @@ -16,6 +16,29 @@ SYNOPSIS
>
> DESCRIPTION
> -----------
> +Transplant a series of commits onto a different starting point.
Nit: while this is one use case for git-rebase(1), I'd claim that
nowadays with interactive rebases there's the other use case where we
don't change the starting point but only edit the range of commits
itself.
So how about this instead:
Edit a series of commits and optionally transplant it onto a
different starting point.
We could also make the two different modes a bit more explicit by
pointing out both different use cases directly.
If you agree then we should probably also modernize the description in
the NAME section accordingly.
Patrick
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [PATCH v4 2/5] doc: git rebase: dedup merge conflict discussion
2025-08-09 1:14 ` [PATCH v4 2/5] doc: git rebase: dedup merge conflict discussion Julia Evans via GitGitGadget
@ 2025-08-11 8:46 ` Patrick Steinhardt
2025-08-11 13:02 ` Phillip Wood
0 siblings, 1 reply; 103+ messages in thread
From: Patrick Steinhardt @ 2025-08-11 8:46 UTC (permalink / raw)
To: Julia Evans via GitGitGadget; +Cc: git, Julia Evans
On Sat, Aug 09, 2025 at 01:14:14AM +0000, Julia Evans via GitGitGadget wrote:
> diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc
> index 449f01fba560..e30b9535fff1 100644
> --- a/Documentation/git-rebase.adoc
> +++ b/Documentation/git-rebase.adoc
> @@ -39,6 +39,27 @@ shortcut for `git checkout topic && git rebase master`.
> D---E---F---G master
> ------------
>
> +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
> +one of these things:
> +
> +1. Resolve the conflict. You can use `git diff` to find the markers (<<<<<<)
> + and make edits to resolve the conflict. For each file you edit, you need to
> + tell Git that the conflict has been resolved. You can mark the conflict as
> + resolved with `git add <filename>`. After resolving all of the conflicts,
> + you can continue the rebasing process with
> +
> + git rebase --continue
> +
> +2. Stop the `git rebase` and return your branch to its original state with
> +
> + git rebase --abort
> +
> +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
> it remains on the current branch.
Yup, this reads a lot nicer.
> @@ -74,13 +95,6 @@ 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).
>
> -It is possible that a merge failure will prevent this process from being
> -completely automatic. You will have to resolve any such merge failure
> -and run `git rebase --continue`. Another option is to bypass the commit
> -that caused the merge failure with `git rebase --skip`. To check out the
> -original `<branch>` and remove the `.git/rebase-apply` working files, use
> -the command `git rebase --abort` instead.
> -
> 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
We lose the bit about `.git/rebase-apply`, but I don't think that's a
bad thing. The user shouldn't have to care how exactly a rebase looks on
disk. All they should need to know is that `git rebase --abort` gets
them out of the state.
Patrick
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [PATCH v4 5/5] doc: git-rebase: update discussion of internals
2025-08-09 1:14 ` [PATCH v4 5/5] doc: git-rebase: update discussion of internals Julia Evans via GitGitGadget
2025-08-10 15:42 ` Phillip Wood
@ 2025-08-11 8:46 ` Patrick Steinhardt
2025-08-11 12:29 ` Ben Knoble
2025-08-11 19:34 ` Julia Evans
1 sibling, 2 replies; 103+ messages in thread
From: Patrick Steinhardt @ 2025-08-11 8:46 UTC (permalink / raw)
To: Julia Evans via GitGitGadget; +Cc: git, Julia Evans
On Sat, Aug 09, 2025 at 01:14:17AM +0000, Julia Evans via GitGitGadget wrote:
> diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc
> index 50c84f138212..c16ee37b46a7 100644
> --- a/Documentation/git-rebase.adoc
> +++ b/Documentation/git-rebase.adoc
> @@ -65,31 +65,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:
> +
> +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>`.
Would it make sense to convert this into a bulleted list to further
highlight this multi-step process?
> [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]).
This information feels somewhat contradictory. Should we maybe say
something like this:
When starting the rebase, `ORIG_HEAD` is set to point to at the tip
of the to-be-rebased branch. As `ORIG_HEAD` may be modified by
various operations during the rebase, it is not guaranteed to still
point to this branch at the end of the rebase. The previous branch
tip, however, is accessible using the reflog of the current branch
(i.e. `@{1}`, see linkgit:gitrevisions[7]).
Note that I'm also dropping the reference to "pseudo-ref". ORIG_HEAD is
not a pseudo-ref, as we have clarified in 6fd8037564
(Documentation/glossary: redefine pseudorefs as special refs,
2024-05-15).
Patrick
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [PATCH v4 1/5] doc: git-rebase: start with an example
2025-08-09 1:14 ` [PATCH v4 1/5] doc: git-rebase: start with an example Julia Evans via GitGitGadget
2025-08-10 15:41 ` Phillip Wood
2025-08-11 8:46 ` Patrick Steinhardt
@ 2025-08-11 9:13 ` Karthik Nayak
2025-08-11 12:27 ` Ben Knoble
2025-08-11 13:07 ` Phillip Wood
2 siblings, 2 replies; 103+ messages in thread
From: Karthik Nayak @ 2025-08-11 9:13 UTC (permalink / raw)
To: Julia Evans via GitGitGadget, git; +Cc: Julia Evans
[-- Attachment #1: Type: text/plain, Size: 1654 bytes --]
"Julia Evans via GitGitGadget" <gitgitgadget@gmail.com> writes:
> From: Julia Evans <julia@jvns.ca>
>
> 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.
>
Happy to see these changes.
> Signed-off-by: Julia Evans <julia@jvns.ca>
> ---
> Documentation/git-rebase.adoc | 49 ++++++++++++++++-------------------
> 1 file changed, 23 insertions(+), 26 deletions(-)
>
> diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc
> index 956d3048f5a6..449f01fba560 100644
> --- a/Documentation/git-rebase.adoc
> +++ b/Documentation/git-rebase.adoc
> @@ -16,6 +16,29 @@ SYNOPSIS
>
> DESCRIPTION
> -----------
> +Transplant a series of commits onto a different starting point.
> +
> +For example, imagine that you have been working on the `topic` branch in this
> +history, and you want to "catch up" to the work done on the `master` branch.
> +
> +------------
> + A---B---C topic
> + /
> + D---E---F---G master
> +------------
> +
> +You want to transplant the commits you made on `topic` since it diverged from
> +`master` (i.e. A, B, and C), on top of the current `master`. You can do this
> +by running `git rebase master` while the `topic` branch is checked out. If you
> +want to rebase `topic` while on another branch, `git rebase master topic` is a
> +shortcut for `git checkout topic && git rebase master`.
> +
Nit: now that `git-switch(1)` is no longer experimental, we should start
recommending it over `git-checkout(1)` as necessary. So perhaps, we
could s/checkout/switch here?
[snip]
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 690 bytes --]
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [PATCH v4 1/5] doc: git-rebase: start with an example
2025-08-11 9:13 ` Karthik Nayak
@ 2025-08-11 12:27 ` Ben Knoble
2025-08-12 9:05 ` Karthik Nayak
2025-08-11 13:07 ` Phillip Wood
1 sibling, 1 reply; 103+ messages in thread
From: Ben Knoble @ 2025-08-11 12:27 UTC (permalink / raw)
To: Karthik Nayak; +Cc: Julia Evans via GitGitGadget, git, Julia Evans
> Le 11 août 2025 à 05:29, Karthik Nayak <karthik.188@gmail.com> a écrit :
>
> "Julia Evans via GitGitGadget" <gitgitgadget@gmail.com> writes:
>>
>> Signed-off-by: Julia Evans <julia@jvns.ca>
>> ---
>> Documentation/git-rebase.adoc | 49 ++++++++++++++++-------------------
>> 1 file changed, 23 insertions(+), 26 deletions(-)
>>
>> diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc
>> index 956d3048f5a6..449f01fba560 100644
>> --- a/Documentation/git-rebase.adoc
>> +++ b/Documentation/git-rebase.adoc
>> @@ -16,6 +16,29 @@ SYNOPSIS
>>
>> DESCRIPTION
>> -----------
>> +Transplant a series of commits onto a different starting point.
>> +
>> +For example, imagine that you have been working on the `topic` branch in this
>> +history, and you want to "catch up" to the work done on the `master` branch.
>> +
>> +------------
>> + A---B---C topic
>> + /
>> + D---E---F---G master
>> +------------
>> +
>> +You want to transplant the commits you made on `topic` since it diverged from
>> +`master` (i.e. A, B, and C), on top of the current `master`. You can do this
>> +by running `git rebase master` while the `topic` branch is checked out. If you
>> +want to rebase `topic` while on another branch, `git rebase master topic` is a
>> +shortcut for `git checkout topic && git rebase master`.
>> +
>
> Nit: now that `git-switch(1)` is no longer experimental, we should start
> recommending it over `git-checkout(1)` as necessary. So perhaps, we
> could s/checkout/switch here?
Junio previously recommended checkout (a prior version used switch): I suspect because checkout will detach head without extra syntax (where switch will not)?
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [PATCH v4 5/5] doc: git-rebase: update discussion of internals
2025-08-11 8:46 ` [PATCH v4 5/5] doc: git-rebase: update discussion of internals Patrick Steinhardt
@ 2025-08-11 12:29 ` Ben Knoble
2025-08-11 13:45 ` Patrick Steinhardt
2025-08-11 19:34 ` Julia Evans
1 sibling, 1 reply; 103+ messages in thread
From: Ben Knoble @ 2025-08-11 12:29 UTC (permalink / raw)
To: Patrick Steinhardt; +Cc: Julia Evans via GitGitGadget, git, Julia Evans
> Le 11 août 2025 à 04:46, Patrick Steinhardt <ps@pks.im> a écrit :
>
> On Sat, Aug 09, 2025 at 01:14:17AM +0000, Julia Evans via GitGitGadget wrote:
>> diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc
>> index 50c84f138212..c16ee37b46a7 100644
>> --- a/Documentation/git-rebase.adoc
>> +++ b/Documentation/git-rebase.adoc
>> @@ -65,31 +65,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:
>> +
>> +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>`.
>
> Would it make sense to convert this into a bulleted list to further
> highlight this multi-step process?
Nit: ordered list, perhaps? Unless we don’t use those in our manuals (away from documentation at the moment).
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [PATCH v4 2/5] doc: git rebase: dedup merge conflict discussion
2025-08-11 8:46 ` Patrick Steinhardt
@ 2025-08-11 13:02 ` Phillip Wood
0 siblings, 0 replies; 103+ messages in thread
From: Phillip Wood @ 2025-08-11 13:02 UTC (permalink / raw)
To: Patrick Steinhardt, Julia Evans via GitGitGadget; +Cc: git, Julia Evans
On 11/08/2025 09:46, Patrick Steinhardt wrote:
> On Sat, Aug 09, 2025 at 01:14:14AM +0000, Julia Evans via GitGitGadget wrote:
>>
>> -It is possible that a merge failure will prevent this process from being
>> -completely automatic. You will have to resolve any such merge failure
>> -and run `git rebase --continue`. Another option is to bypass the commit
>> -that caused the merge failure with `git rebase --skip`. To check out the
>> -original `<branch>` and remove the `.git/rebase-apply` working files, use
>> -the command `git rebase --abort` instead.
>> -
>> 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
>
> We lose the bit about `.git/rebase-apply`, but I don't think that's a
> bad thing. The user shouldn't have to care how exactly a rebase looks on
> disk.
Exactly, we don't want to encourage the user to poke about in the state
directory. Also ".git/rebase-apply" wont exist unless the user requested
the apply backend so mentioning it is misleading (the default is
".git/rebase-merge" these days).
Thanks
Phillip
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [PATCH v4 1/5] doc: git-rebase: start with an example
2025-08-11 9:13 ` Karthik Nayak
2025-08-11 12:27 ` Ben Knoble
@ 2025-08-11 13:07 ` Phillip Wood
2025-08-12 9:07 ` Karthik Nayak
1 sibling, 1 reply; 103+ messages in thread
From: Phillip Wood @ 2025-08-11 13:07 UTC (permalink / raw)
To: Karthik Nayak, Julia Evans via GitGitGadget, git; +Cc: Julia Evans
On 11/08/2025 10:13, Karthik Nayak wrote:
> "Julia Evans via GitGitGadget" <gitgitgadget@gmail.com> writes:
>> +
>> +You want to transplant the commits you made on `topic` since it diverged from
>> +`master` (i.e. A, B, and C), on top of the current `master`. You can do this
>> +by running `git rebase master` while the `topic` branch is checked out. If you
>> +want to rebase `topic` while on another branch, `git rebase master topic` is a
>> +shortcut for `git checkout topic && git rebase master`.
>> +
>
> Nit: now that `git-switch(1)` is no longer experimental, we should start
> recommending it over `git-checkout(1)` as necessary. So perhaps, we
> could s/checkout/switch here?
Junio has already expressed a preference for "checkout" here c.f.
<xmqqldnte6h3.fsf@gitster.g>. I think that is technically correct as
"topic" can be a commitish and "git switch <object-id>" fails without
"--detach". Also rebase does not do any of the extra checks that "git
switch" does before switching branches (I'm not saying that is
necessarily a good thing).
Thanks
Phillip
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [PATCH v4 5/5] doc: git-rebase: update discussion of internals
2025-08-11 12:29 ` Ben Knoble
@ 2025-08-11 13:45 ` Patrick Steinhardt
0 siblings, 0 replies; 103+ messages in thread
From: Patrick Steinhardt @ 2025-08-11 13:45 UTC (permalink / raw)
To: Ben Knoble; +Cc: Julia Evans via GitGitGadget, git, Julia Evans
On Mon, Aug 11, 2025 at 08:29:42AM -0400, Ben Knoble wrote:
>
> > Le 11 août 2025 à 04:46, Patrick Steinhardt <ps@pks.im> a écrit :
> >
> > On Sat, Aug 09, 2025 at 01:14:17AM +0000, Julia Evans via GitGitGadget wrote:
> >> diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc
> >> index 50c84f138212..c16ee37b46a7 100644
> >> --- a/Documentation/git-rebase.adoc
> >> +++ b/Documentation/git-rebase.adoc
> >> @@ -65,31 +65,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:
> >> +
> >> +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>`.
> >
> > Would it make sense to convert this into a bulleted list to further
> > highlight this multi-step process?
>
> Nit: ordered list, perhaps? Unless we don’t use those in our manuals
> (away from documentation at the moment).
Ah, I actually wanted to propose using an ordered list, not bulleted list.
Thanks for correcting me.
Patrick
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [PATCH v4 5/5] doc: git-rebase: update discussion of internals
2025-08-11 8:46 ` [PATCH v4 5/5] doc: git-rebase: update discussion of internals Patrick Steinhardt
2025-08-11 12:29 ` Ben Knoble
@ 2025-08-11 19:34 ` Julia Evans
1 sibling, 0 replies; 103+ messages in thread
From: Julia Evans @ 2025-08-11 19:34 UTC (permalink / raw)
To: Patrick Steinhardt, Julia Evans; +Cc: git
> Would it make sense to convert this into a bulleted list to further
> highlight this multi-step process?
I like this idea. I think we can combine this with Phillip's point about
"--reapply-cherry-picks" to expand the list a little more and remove the
paragraph at the end about how duplicate commits are skipped. ("If the upstream
branch already contains a change you have made...") I think probably the diagram
can be removed too, I'm not sure how much value it's adding.
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>`.
I imagine actually #1 and #2 happen concurrently, but I split them up because
it felt unwieldy to explain them both the same point.
>
>> [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]).
>
> This information feels somewhat contradictory. Should we maybe say
> something like this:
>
> When starting the rebase, `ORIG_HEAD` is set to point to at the tip
> of the to-be-rebased branch. As `ORIG_HEAD` may be modified by
> various operations during the rebase, it is not guaranteed to still
> point to this branch at the end of the rebase. The previous branch
> tip, however, is accessible using the reflog of the current branch
> (i.e. `@{1}`, see linkgit:gitrevisions[7]).
>
> Note that I'm also dropping the reference to "pseudo-ref". ORIG_HEAD is
> not a pseudo-ref, as we have clarified in 6fd8037564
> (Documentation/glossary: redefine pseudorefs as special refs,
> 2024-05-15).
I like that! Also very happy to remove the word "pseudo-ref".
- Julia
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v5 0/5] doc: git-rebase: clarify DESCRIPTION section
2025-08-09 1:14 ` [PATCH v4 0/5] doc: git-rebase: clarify DESCRIPTION section Julia Evans via GitGitGadget
` (4 preceding siblings ...)
2025-08-09 1:14 ` [PATCH v4 5/5] doc: git-rebase: update discussion of internals Julia Evans via GitGitGadget
@ 2025-08-11 20:12 ` Julia Evans via GitGitGadget
2025-08-11 20:12 ` [PATCH v5 1/5] doc: git-rebase: start with an example Julia Evans via GitGitGadget
` (5 more replies)
5 siblings, 6 replies; 103+ messages in thread
From: Julia Evans via GitGitGadget @ 2025-08-11 20:12 UTC (permalink / raw)
To: git
Cc: D. Ben Knoble, Phillip Wood, Patrick Steinhardt, Karthik Nayak,
Julia Evans
* 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 <julia@jvns.ca>
@@ 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
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v5 1/5] doc: git-rebase: start with an example
2025-08-11 20:12 ` [PATCH v5 0/5] doc: git-rebase: clarify DESCRIPTION section Julia Evans via GitGitGadget
@ 2025-08-11 20:12 ` Julia Evans via GitGitGadget
2025-08-11 20:50 ` Junio C Hamano
2025-08-11 20:12 ` [PATCH v5 2/5] doc: git rebase: dedup merge conflict discussion Julia Evans via GitGitGadget
` (4 subsequent siblings)
5 siblings, 1 reply; 103+ messages in thread
From: Julia Evans via GitGitGadget @ 2025-08-11 20:12 UTC (permalink / raw)
To: git
Cc: D. Ben Knoble, Phillip Wood, Patrick Steinhardt, Karthik Nayak,
Julia Evans, Julia Evans
From: Julia Evans <julia@jvns.ca>
- 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 <julia@jvns.ca>
---
Documentation/git-rebase.adoc | 52 +++++++++++++++++------------------
1 file changed, 26 insertions(+), 26 deletions(-)
diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc
index 956d3048f5a6..03d1b74a9a09 100644
--- a/Documentation/git-rebase.adoc
+++ b/Documentation/git-rebase.adoc
@@ -16,6 +16,32 @@ SYNOPSIS
DESCRIPTION
-----------
+Transplant a series of commits onto a different starting point.
+
+For example, imagine that you have been working on the `topic` branch in this
+history, and you want to "catch up" to the work done on the `master` branch.
+
+------------
+ A---B---C topic
+ /
+ D---E---F---G master
+------------
+
+You want to transplant the commits you made on `topic` since it diverged from
+`master` (i.e. A, B, and C), on top of the current `master`. You can do this
+by running `git rebase master` while the `topic` branch is checked out. If you
+want to rebase `topic` while on another branch, `git rebase master topic` is a
+shortcut for `git checkout topic && git rebase master`.
+
+------------
+ A'--B'--C' topic
+ /
+ 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
it remains on the current branch.
@@ -58,32 +84,6 @@ that caused the merge failure with `git rebase --skip`. To check out the
original `<branch>` and remove the `.git/rebase-apply` working files, use
the command `git rebase --abort` instead.
-Assume the following history exists and the current branch is "topic":
-
-------------
- A---B---C topic
- /
- D---E---F---G master
-------------
-
-From this point, the result of either of the following commands:
-
-
- git rebase master
- git rebase master topic
-
-would be:
-
-------------
- A'--B'--C' topic
- /
- D---E---F---G master
-------------
-
-*NOTE:* The latter form is just a short-hand of `git checkout topic`
-followed by `git rebase master`. When rebase exits `topic` will
-remain the checked-out branch.
-
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
--
gitgitgadget
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v5 2/5] doc: git rebase: dedup merge conflict discussion
2025-08-11 20:12 ` [PATCH v5 0/5] doc: git-rebase: clarify DESCRIPTION section Julia Evans via GitGitGadget
2025-08-11 20:12 ` [PATCH v5 1/5] doc: git-rebase: start with an example Julia Evans via GitGitGadget
@ 2025-08-11 20:12 ` Julia Evans via GitGitGadget
2025-08-11 20:12 ` [PATCH v5 3/5] doc: git rebase: clarify arguments syntax Julia Evans via GitGitGadget
` (3 subsequent siblings)
5 siblings, 0 replies; 103+ messages in thread
From: Julia Evans via GitGitGadget @ 2025-08-11 20:12 UTC (permalink / raw)
To: git
Cc: D. Ben Knoble, Phillip Wood, Patrick Steinhardt, Karthik Nayak,
Julia Evans, Julia Evans
From: Julia Evans <julia@jvns.ca>
Previously there were two explanations, this combines them both into a
single explanation.
Signed-off-by: Julia Evans <julia@jvns.ca>
---
Documentation/git-rebase.adoc | 49 ++++++++++++++---------------------
1 file changed, 20 insertions(+), 29 deletions(-)
diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc
index 03d1b74a9a09..4ba74a8cf9ba 100644
--- a/Documentation/git-rebase.adoc
+++ b/Documentation/git-rebase.adoc
@@ -42,6 +42,26 @@ shortcut for `git checkout topic && git rebase 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
+one of these things:
+
+1. Resolve the conflict. You can use `git diff` to find the markers (<<<<<<)
+ and make edits to resolve the conflict. For each file you edit, you need to
+ tell Git that the conflict has been resolved. You can mark the conflict as
+ resolved with `git add <filename>`. After resolving all of the conflicts,
+ you can continue the rebasing process with
+
+ git rebase --continue
+
+2. Stop the `git rebase` and return your branch to its original state with
+
+ git rebase --abort
+
+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
it remains on the current branch.
@@ -77,13 +97,6 @@ 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).
-It is possible that a merge failure will prevent this process from being
-completely automatic. You will have to resolve any such merge failure
-and run `git rebase --continue`. Another option is to bypass the commit
-that caused the merge failure with `git rebase --skip`. To check out the
-original `<branch>` and remove the `.git/rebase-apply` working files, use
-the command `git rebase --abort` instead.
-
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
@@ -186,28 +199,6 @@ This is useful if F and G were flawed in some way, or should not be
part of topicA. Note that the argument to `--onto` and the `<upstream>`
parameter can be any valid commit-ish.
-In case of conflict, `git rebase` will stop at the first problematic commit
-and leave conflict markers in the tree. You can use `git diff` to locate
-the markers (<<<<<<) and make edits to resolve the conflict. For each
-file you edit, you need to tell Git that the conflict has been resolved,
-typically this would be done with
-
-
- git add <filename>
-
-
-After resolving the conflict manually and updating the index with the
-desired resolution, you can continue the rebasing process with
-
-
- git rebase --continue
-
-
-Alternatively, you can undo the 'git rebase' with
-
-
- git rebase --abort
-
MODE OPTIONS
------------
--
gitgitgadget
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v5 3/5] doc: git rebase: clarify arguments syntax
2025-08-11 20:12 ` [PATCH v5 0/5] doc: git-rebase: clarify DESCRIPTION section Julia Evans via GitGitGadget
2025-08-11 20:12 ` [PATCH v5 1/5] doc: git-rebase: start with an example Julia Evans via GitGitGadget
2025-08-11 20:12 ` [PATCH v5 2/5] doc: git rebase: dedup merge conflict discussion Julia Evans via GitGitGadget
@ 2025-08-11 20:12 ` Julia Evans via GitGitGadget
2025-08-11 20:12 ` [PATCH v5 4/5] doc: git-rebase: move --onto explanation down Julia Evans via GitGitGadget
` (2 subsequent siblings)
5 siblings, 0 replies; 103+ messages in thread
From: Julia Evans via GitGitGadget @ 2025-08-11 20:12 UTC (permalink / raw)
To: git
Cc: D. Ben Knoble, Phillip Wood, Patrick Steinhardt, Karthik Nayak,
Julia Evans, Julia Evans
From: Julia Evans <julia@jvns.ca>
Remove duplicate explanation of `git rebase <upstream> <branch>` which
is already explained above.
Signed-off-by: Julia Evans <julia@jvns.ca>
---
Documentation/git-rebase.adoc | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc
index 4ba74a8cf9ba..117c3f43719f 100644
--- a/Documentation/git-rebase.adoc
+++ b/Documentation/git-rebase.adoc
@@ -62,11 +62,7 @@ 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.
-
-If `<upstream>` is not specified, the upstream configured in
+If you don't specify an `<upstream>` to rebase onto, the upstream configured in
`branch.<name>.remote` and `branch.<name>.merge` options will be used (see
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
--
gitgitgadget
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v5 4/5] doc: git-rebase: move --onto explanation down
2025-08-11 20:12 ` [PATCH v5 0/5] doc: git-rebase: clarify DESCRIPTION section Julia Evans via GitGitGadget
` (2 preceding siblings ...)
2025-08-11 20:12 ` [PATCH v5 3/5] doc: git rebase: clarify arguments syntax Julia Evans via GitGitGadget
@ 2025-08-11 20:12 ` Julia Evans via GitGitGadget
2025-08-11 20:12 ` [PATCH v5 5/5] doc: git-rebase: update discussion of internals Julia Evans via GitGitGadget
2025-08-11 21:51 ` [PATCH v6 0/5] doc: git-rebase: clarify DESCRIPTION section Julia Evans via GitGitGadget
5 siblings, 0 replies; 103+ messages in thread
From: Julia Evans via GitGitGadget @ 2025-08-11 20:12 UTC (permalink / raw)
To: git
Cc: D. Ben Knoble, Phillip Wood, Patrick Steinhardt, Karthik Nayak,
Julia Evans, Julia Evans
From: Julia Evans <julia@jvns.ca>
There's a very clear explanation with examples of using --onto which is
currently buried in the very long DESCRIPTION section. This moves it to
its own section, so that we can reference the explanation from the
`--onto` option by name.
Signed-off-by: Julia Evans <julia@jvns.ca>
---
Documentation/git-rebase.adoc | 168 ++++++++++++++++++----------------
1 file changed, 87 insertions(+), 81 deletions(-)
diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc
index 117c3f43719f..750f5e67e4c3 100644
--- a/Documentation/git-rebase.adoc
+++ b/Documentation/git-rebase.adoc
@@ -114,87 +114,6 @@ will result in:
D---E---A'---F master
------------
-Here is how you would transplant a topic branch based on one
-branch to another, to pretend that you forked the topic branch
-from the latter branch, using `rebase --onto`.
-
-First let's assume your 'topic' is based on branch 'next'.
-For example, a feature developed in 'topic' depends on some
-functionality which is found in 'next'.
-
-------------
- o---o---o---o---o master
- \
- o---o---o---o---o next
- \
- o---o---o topic
-------------
-
-We want to make 'topic' forked from branch 'master'; for example,
-because the functionality on which 'topic' depends was merged into the
-more stable 'master' branch. We want our tree to look like this:
-
-------------
- o---o---o---o---o master
- | \
- | o'--o'--o' topic
- \
- o---o---o---o---o next
-------------
-
-We can get this using the following command:
-
- git rebase --onto master next topic
-
-
-Another example of --onto option is to rebase part of a
-branch. If we have the following situation:
-
-------------
- H---I---J topicB
- /
- E---F---G topicA
- /
- A---B---C---D master
-------------
-
-then the command
-
- git rebase --onto master topicA topicB
-
-would result in:
-
-------------
- H'--I'--J' topicB
- /
- | E---F---G topicA
- |/
- A---B---C---D master
-------------
-
-This is useful when topicB does not depend on topicA.
-
-A range of commits could also be removed with rebase. If we have
-the following situation:
-
-------------
- E---F---G---H---I---J topicA
-------------
-
-then the command
-
- git rebase --onto topicA~5 topicA~3 topicA
-
-would result in the removal of commits F and G:
-
-------------
- E---H'---I'---J' topicA
-------------
-
-This is useful if F and G were flawed in some way, or should not be
-part of topicA. Note that the argument to `--onto` and the `<upstream>`
-parameter can be any valid commit-ish.
-
MODE OPTIONS
------------
@@ -240,6 +159,8 @@ As a special case, you may use "A\...B" as a shortcut for the
merge base of A and B if there is exactly one merge base. You can
leave out at most one of A and B, in which case it defaults to HEAD.
+See TRANSPLANTING A TOPIC BRANCH WITH --ONTO below for examples.
+
--keep-base::
Set the starting point at which to create the new commits to the
merge base of `<upstream>` and `<branch>`. Running
@@ -1018,6 +939,91 @@ consistent (they compile, pass the testsuite, etc.) you should use
after each commit, test, and amend the commit if fixes are necessary.
+TRANSPLANTING A TOPIC BRANCH WITH --ONTO
+----------------------------------------
+
+Here is how you would transplant a topic branch based on one
+branch to another, to pretend that you forked the topic branch
+from the latter branch, using `rebase --onto`.
+
+First let's assume your 'topic' is based on branch 'next'.
+For example, a feature developed in 'topic' depends on some
+functionality which is found in 'next'.
+
+------------
+ o---o---o---o---o master
+ \
+ o---o---o---o---o next
+ \
+ o---o---o topic
+------------
+
+We want to make 'topic' forked from branch 'master'; for example,
+because the functionality on which 'topic' depends was merged into the
+more stable 'master' branch. We want our tree to look like this:
+
+------------
+ o---o---o---o---o master
+ | \
+ | o'--o'--o' topic
+ \
+ o---o---o---o---o next
+------------
+
+We can get this using the following command:
+
+ git rebase --onto master next topic
+
+
+Another example of --onto option is to rebase part of a
+branch. If we have the following situation:
+
+------------
+ H---I---J topicB
+ /
+ E---F---G topicA
+ /
+ A---B---C---D master
+------------
+
+then the command
+
+ git rebase --onto master topicA topicB
+
+would result in:
+
+------------
+ H'--I'--J' topicB
+ /
+ | E---F---G topicA
+ |/
+ A---B---C---D master
+------------
+
+This is useful when topicB does not depend on topicA.
+
+A range of commits could also be removed with rebase. If we have
+the following situation:
+
+------------
+ E---F---G---H---I---J topicA
+------------
+
+then the command
+
+ git rebase --onto topicA~5 topicA~3 topicA
+
+would result in the removal of commits F and G:
+
+------------
+ E---H'---I'---J' topicA
+------------
+
+This is useful if F and G were flawed in some way, or should not be
+part of topicA. Note that the argument to `--onto` and the `<upstream>`
+parameter can be any valid commit-ish.
+
+
RECOVERING FROM UPSTREAM REBASE
-------------------------------
--
gitgitgadget
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v5 5/5] doc: git-rebase: update discussion of internals
2025-08-11 20:12 ` [PATCH v5 0/5] doc: git-rebase: clarify DESCRIPTION section Julia Evans via GitGitGadget
` (3 preceding siblings ...)
2025-08-11 20:12 ` [PATCH v5 4/5] doc: git-rebase: move --onto explanation down Julia Evans via GitGitGadget
@ 2025-08-11 20:12 ` Julia Evans via GitGitGadget
2025-08-11 21:14 ` Junio C Hamano
2025-08-11 21:51 ` [PATCH v6 0/5] doc: git-rebase: clarify DESCRIPTION section Julia Evans via GitGitGadget
5 siblings, 1 reply; 103+ messages in thread
From: Julia Evans via GitGitGadget @ 2025-08-11 20:12 UTC (permalink / raw)
To: git
Cc: D. Ben Knoble, Phillip Wood, Patrick Steinhardt, Karthik Nayak,
Julia Evans, Julia Evans
From: Julia Evans <julia@jvns.ca>
- 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 <julia@jvns.ca>
---
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:
+
+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 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
-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
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [PATCH v5 1/5] doc: git-rebase: start with an example
2025-08-11 20:12 ` [PATCH v5 1/5] doc: git-rebase: start with an example Julia Evans via GitGitGadget
@ 2025-08-11 20:50 ` Junio C Hamano
0 siblings, 0 replies; 103+ messages in thread
From: Junio C Hamano @ 2025-08-11 20:50 UTC (permalink / raw)
To: Julia Evans via GitGitGadget
Cc: git, D. Ben Knoble, Phillip Wood, Patrick Steinhardt,
Karthik Nayak, Julia Evans
"Julia Evans via GitGitGadget" <gitgitgadget@gmail.com> writes:
> From: Julia Evans <julia@jvns.ca>
>
> - 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
The new comment added by this second point looks somewhat out of
place. With this patch as-is, the text talks only about the best
case of the basic usage, tell the reader to go elsewhere if they are
not interested in learning the basic usage, and then switches back
to the basic usage topic and talks about conflict resolution.
It may be easier to read if you covered the fact that there are two
major use cases upfront, perhaps like:
DESCRIPTION
-----------
Transplant a series of commits onto a different starting point.
You can also use `git rebase` to reorder or combine commits: see
INTERACTIVE MODE below for how to do that.
For example, imagine ...
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [PATCH v5 5/5] doc: git-rebase: update discussion of internals
2025-08-11 20:12 ` [PATCH v5 5/5] doc: git-rebase: update discussion of internals Julia Evans via GitGitGadget
@ 2025-08-11 21:14 ` Junio C Hamano
0 siblings, 0 replies; 103+ messages in thread
From: Junio C Hamano @ 2025-08-11 21:14 UTC (permalink / raw)
To: Julia Evans via GitGitGadget
Cc: git, D. Ben Knoble, Phillip Wood, Patrick Steinhardt,
Karthik Nayak, Julia Evans
"Julia Evans via GitGitGadget" <gitgitgadget@gmail.com> writes:
> From: Julia Evans <julia@jvns.ca>
>
> - 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 <julia@jvns.ca>
> ---
> 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.
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v6 0/5] doc: git-rebase: clarify DESCRIPTION section
2025-08-11 20:12 ` [PATCH v5 0/5] doc: git-rebase: clarify DESCRIPTION section Julia Evans via GitGitGadget
` (4 preceding siblings ...)
2025-08-11 20:12 ` [PATCH v5 5/5] doc: git-rebase: update discussion of internals Julia Evans via GitGitGadget
@ 2025-08-11 21:51 ` Julia Evans via GitGitGadget
2025-08-11 21:51 ` [PATCH v6 1/5] doc: git-rebase: start with an example Julia Evans via GitGitGadget
` (7 more replies)
5 siblings, 8 replies; 103+ messages in thread
From: Julia Evans via GitGitGadget @ 2025-08-11 21:51 UTC (permalink / raw)
To: git
Cc: D. Ben Knoble, Phillip Wood, Patrick Steinhardt, Karthik Nayak,
Julia Evans
* move "You can also use git rebase to reorder or combine commits:" to the
beginning
* replace "detailed description" with "simplified description" -- I thought
that I could write something that was relatively readable and also
accurate, but as usual Git has proven me wrong :). I tried to leave in
the details that I think seem relevant to using git: for example git
checkout --detach is relevant because it explains why git reflog works
well after a rebase.
* replace the git switch with git checkout that I'd missed previously
I didn't use the git log --cherry-pick option in the explanation because I
had personally never heard of that option before today, and I don't want
people to have to read the git log man page to be able to understand the
explanation. I also left out --reapply-cherry-picks just because I don't
understand the use case so I couldn't evaluate how likely it is to be
relevant to the person reading.
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 | 302 +++++++++++++++-------------------
1 file changed, 136 insertions(+), 166 deletions(-)
base-commit: 2c2ba49d55ff26c1082b8137b1ec5eeccb4337d1
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1949%2Fjvns%2Fclarify-rebase-v6
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1949/jvns/clarify-rebase-v6
Pull-Request: https://github.com/gitgitgadget/git/pull/1949
Range-diff vs v5:
1: c2f2e05078f ! 1: e7a8fbbe53c doc: git-rebase: start with an example
@@ Documentation/git-rebase.adoc: SYNOPSIS
DESCRIPTION
-----------
+Transplant a series of commits onto a different starting point.
++You can also use `git rebase` to reorder or combine commits: see INTERACTIVE
++MODE below for how to do that.
+
+For example, imagine that you have been working on the `topic` branch in this
+history, and you want to "catch up" to the work done on the `master` branch.
@@ 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: 5459b7ff560 ! 2: ad63f69918d 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`.
- 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
3: 948c205f1e6 = 3: 7ee6b0afe88 doc: git rebase: clarify arguments syntax
4: e229b9fccb2 = 4: 4686417b28e doc: git-rebase: move --onto explanation down
5: 5ab235b067b ! 5: 9c7f2716bc8 doc: git-rebase: update discussion of internals
@@ Documentation/git-rebase.adoc: linkgit:git-config[1] for details) and the `--for
-`--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:
++Here is a simplified description of what `git rebase <upstream>` does:
+
-+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.
++1. Make a list of all new commits on your current branch since it branched
++ off from `<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>`.
++ in `<upstream>` and remove them from the list.
++3. Check out `<upstream>` 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>`.
++ of `git checkout -C <branch>`.
[NOTE]
-`ORIG_HEAD` is not guaranteed to still point to the previous branch tip
--
gitgitgadget
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v6 1/5] doc: git-rebase: start with an example
2025-08-11 21:51 ` [PATCH v6 0/5] doc: git-rebase: clarify DESCRIPTION section Julia Evans via GitGitGadget
@ 2025-08-11 21:51 ` Julia Evans via GitGitGadget
2025-08-11 21:51 ` [PATCH v6 2/5] doc: git rebase: dedup merge conflict discussion Julia Evans via GitGitGadget
` (6 subsequent siblings)
7 siblings, 0 replies; 103+ messages in thread
From: Julia Evans via GitGitGadget @ 2025-08-11 21:51 UTC (permalink / raw)
To: git
Cc: D. Ben Knoble, Phillip Wood, Patrick Steinhardt, Karthik Nayak,
Julia Evans, Julia Evans
From: Julia Evans <julia@jvns.ca>
- 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 <julia@jvns.ca>
---
Documentation/git-rebase.adoc | 52 +++++++++++++++++------------------
1 file changed, 26 insertions(+), 26 deletions(-)
diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc
index 956d3048f5a6..bb5a3ff7f828 100644
--- a/Documentation/git-rebase.adoc
+++ b/Documentation/git-rebase.adoc
@@ -16,6 +16,32 @@ SYNOPSIS
DESCRIPTION
-----------
+Transplant a series of commits onto a different starting point.
+You can also use `git rebase` to reorder or combine commits: see INTERACTIVE
+MODE below for how to do that.
+
+For example, imagine that you have been working on the `topic` branch in this
+history, and you want to "catch up" to the work done on the `master` branch.
+
+------------
+ A---B---C topic
+ /
+ D---E---F---G master
+------------
+
+You want to transplant the commits you made on `topic` since it diverged from
+`master` (i.e. A, B, and C), on top of the current `master`. You can do this
+by running `git rebase master` while the `topic` branch is checked out. If you
+want to rebase `topic` while on another branch, `git rebase master topic` is a
+shortcut for `git checkout topic && git rebase master`.
+
+------------
+ A'--B'--C' topic
+ /
+ D---E---F---G master
+------------
+
+
If `<branch>` is specified, `git rebase` will perform an automatic
`git switch <branch>` before doing anything else. Otherwise
it remains on the current branch.
@@ -58,32 +84,6 @@ that caused the merge failure with `git rebase --skip`. To check out the
original `<branch>` and remove the `.git/rebase-apply` working files, use
the command `git rebase --abort` instead.
-Assume the following history exists and the current branch is "topic":
-
-------------
- A---B---C topic
- /
- D---E---F---G master
-------------
-
-From this point, the result of either of the following commands:
-
-
- git rebase master
- git rebase master topic
-
-would be:
-
-------------
- A'--B'--C' topic
- /
- D---E---F---G master
-------------
-
-*NOTE:* The latter form is just a short-hand of `git checkout topic`
-followed by `git rebase master`. When rebase exits `topic` will
-remain the checked-out branch.
-
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
--
gitgitgadget
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v6 2/5] doc: git rebase: dedup merge conflict discussion
2025-08-11 21:51 ` [PATCH v6 0/5] doc: git-rebase: clarify DESCRIPTION section Julia Evans via GitGitGadget
2025-08-11 21:51 ` [PATCH v6 1/5] doc: git-rebase: start with an example Julia Evans via GitGitGadget
@ 2025-08-11 21:51 ` Julia Evans via GitGitGadget
2025-08-11 21:51 ` [PATCH v6 3/5] doc: git rebase: clarify arguments syntax Julia Evans via GitGitGadget
` (5 subsequent siblings)
7 siblings, 0 replies; 103+ messages in thread
From: Julia Evans via GitGitGadget @ 2025-08-11 21:51 UTC (permalink / raw)
To: git
Cc: D. Ben Knoble, Phillip Wood, Patrick Steinhardt, Karthik Nayak,
Julia Evans, Julia Evans
From: Julia Evans <julia@jvns.ca>
Previously there were two explanations, this combines them both into a
single explanation.
Signed-off-by: Julia Evans <julia@jvns.ca>
---
Documentation/git-rebase.adoc | 49 ++++++++++++++---------------------
1 file changed, 20 insertions(+), 29 deletions(-)
diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc
index bb5a3ff7f828..e82ceb9cbfce 100644
--- a/Documentation/git-rebase.adoc
+++ b/Documentation/git-rebase.adoc
@@ -42,6 +42,26 @@ shortcut for `git checkout topic && git rebase master`.
------------
+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
+one of these things:
+
+1. Resolve the conflict. You can use `git diff` to find the markers (<<<<<<)
+ and make edits to resolve the conflict. For each file you edit, you need to
+ tell Git that the conflict has been resolved. You can mark the conflict as
+ resolved with `git add <filename>`. After resolving all of the conflicts,
+ you can continue the rebasing process with
+
+ git rebase --continue
+
+2. Stop the `git rebase` and return your branch to its original state with
+
+ git rebase --abort
+
+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
it remains on the current branch.
@@ -77,13 +97,6 @@ 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).
-It is possible that a merge failure will prevent this process from being
-completely automatic. You will have to resolve any such merge failure
-and run `git rebase --continue`. Another option is to bypass the commit
-that caused the merge failure with `git rebase --skip`. To check out the
-original `<branch>` and remove the `.git/rebase-apply` working files, use
-the command `git rebase --abort` instead.
-
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
@@ -186,28 +199,6 @@ This is useful if F and G were flawed in some way, or should not be
part of topicA. Note that the argument to `--onto` and the `<upstream>`
parameter can be any valid commit-ish.
-In case of conflict, `git rebase` will stop at the first problematic commit
-and leave conflict markers in the tree. You can use `git diff` to locate
-the markers (<<<<<<) and make edits to resolve the conflict. For each
-file you edit, you need to tell Git that the conflict has been resolved,
-typically this would be done with
-
-
- git add <filename>
-
-
-After resolving the conflict manually and updating the index with the
-desired resolution, you can continue the rebasing process with
-
-
- git rebase --continue
-
-
-Alternatively, you can undo the 'git rebase' with
-
-
- git rebase --abort
-
MODE OPTIONS
------------
--
gitgitgadget
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v6 3/5] doc: git rebase: clarify arguments syntax
2025-08-11 21:51 ` [PATCH v6 0/5] doc: git-rebase: clarify DESCRIPTION section Julia Evans via GitGitGadget
2025-08-11 21:51 ` [PATCH v6 1/5] doc: git-rebase: start with an example Julia Evans via GitGitGadget
2025-08-11 21:51 ` [PATCH v6 2/5] doc: git rebase: dedup merge conflict discussion Julia Evans via GitGitGadget
@ 2025-08-11 21:51 ` Julia Evans via GitGitGadget
2025-08-11 21:51 ` [PATCH v6 4/5] doc: git-rebase: move --onto explanation down Julia Evans via GitGitGadget
` (4 subsequent siblings)
7 siblings, 0 replies; 103+ messages in thread
From: Julia Evans via GitGitGadget @ 2025-08-11 21:51 UTC (permalink / raw)
To: git
Cc: D. Ben Knoble, Phillip Wood, Patrick Steinhardt, Karthik Nayak,
Julia Evans, Julia Evans
From: Julia Evans <julia@jvns.ca>
Remove duplicate explanation of `git rebase <upstream> <branch>` which
is already explained above.
Signed-off-by: Julia Evans <julia@jvns.ca>
---
Documentation/git-rebase.adoc | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc
index e82ceb9cbfce..6d02648a9b3c 100644
--- a/Documentation/git-rebase.adoc
+++ b/Documentation/git-rebase.adoc
@@ -62,11 +62,7 @@ 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.
-
-If `<upstream>` is not specified, the upstream configured in
+If you don't specify an `<upstream>` to rebase onto, the upstream configured in
`branch.<name>.remote` and `branch.<name>.merge` options will be used (see
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
--
gitgitgadget
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v6 4/5] doc: git-rebase: move --onto explanation down
2025-08-11 21:51 ` [PATCH v6 0/5] doc: git-rebase: clarify DESCRIPTION section Julia Evans via GitGitGadget
` (2 preceding siblings ...)
2025-08-11 21:51 ` [PATCH v6 3/5] doc: git rebase: clarify arguments syntax Julia Evans via GitGitGadget
@ 2025-08-11 21:51 ` Julia Evans via GitGitGadget
2025-08-11 21:51 ` [PATCH v6 5/5] doc: git-rebase: update discussion of internals Julia Evans via GitGitGadget
` (3 subsequent siblings)
7 siblings, 0 replies; 103+ messages in thread
From: Julia Evans via GitGitGadget @ 2025-08-11 21:51 UTC (permalink / raw)
To: git
Cc: D. Ben Knoble, Phillip Wood, Patrick Steinhardt, Karthik Nayak,
Julia Evans, Julia Evans
From: Julia Evans <julia@jvns.ca>
There's a very clear explanation with examples of using --onto which is
currently buried in the very long DESCRIPTION section. This moves it to
its own section, so that we can reference the explanation from the
`--onto` option by name.
Signed-off-by: Julia Evans <julia@jvns.ca>
---
Documentation/git-rebase.adoc | 168 ++++++++++++++++++----------------
1 file changed, 87 insertions(+), 81 deletions(-)
diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc
index 6d02648a9b3c..d041d87f270b 100644
--- a/Documentation/git-rebase.adoc
+++ b/Documentation/git-rebase.adoc
@@ -114,87 +114,6 @@ will result in:
D---E---A'---F master
------------
-Here is how you would transplant a topic branch based on one
-branch to another, to pretend that you forked the topic branch
-from the latter branch, using `rebase --onto`.
-
-First let's assume your 'topic' is based on branch 'next'.
-For example, a feature developed in 'topic' depends on some
-functionality which is found in 'next'.
-
-------------
- o---o---o---o---o master
- \
- o---o---o---o---o next
- \
- o---o---o topic
-------------
-
-We want to make 'topic' forked from branch 'master'; for example,
-because the functionality on which 'topic' depends was merged into the
-more stable 'master' branch. We want our tree to look like this:
-
-------------
- o---o---o---o---o master
- | \
- | o'--o'--o' topic
- \
- o---o---o---o---o next
-------------
-
-We can get this using the following command:
-
- git rebase --onto master next topic
-
-
-Another example of --onto option is to rebase part of a
-branch. If we have the following situation:
-
-------------
- H---I---J topicB
- /
- E---F---G topicA
- /
- A---B---C---D master
-------------
-
-then the command
-
- git rebase --onto master topicA topicB
-
-would result in:
-
-------------
- H'--I'--J' topicB
- /
- | E---F---G topicA
- |/
- A---B---C---D master
-------------
-
-This is useful when topicB does not depend on topicA.
-
-A range of commits could also be removed with rebase. If we have
-the following situation:
-
-------------
- E---F---G---H---I---J topicA
-------------
-
-then the command
-
- git rebase --onto topicA~5 topicA~3 topicA
-
-would result in the removal of commits F and G:
-
-------------
- E---H'---I'---J' topicA
-------------
-
-This is useful if F and G were flawed in some way, or should not be
-part of topicA. Note that the argument to `--onto` and the `<upstream>`
-parameter can be any valid commit-ish.
-
MODE OPTIONS
------------
@@ -240,6 +159,8 @@ As a special case, you may use "A\...B" as a shortcut for the
merge base of A and B if there is exactly one merge base. You can
leave out at most one of A and B, in which case it defaults to HEAD.
+See TRANSPLANTING A TOPIC BRANCH WITH --ONTO below for examples.
+
--keep-base::
Set the starting point at which to create the new commits to the
merge base of `<upstream>` and `<branch>`. Running
@@ -1018,6 +939,91 @@ consistent (they compile, pass the testsuite, etc.) you should use
after each commit, test, and amend the commit if fixes are necessary.
+TRANSPLANTING A TOPIC BRANCH WITH --ONTO
+----------------------------------------
+
+Here is how you would transplant a topic branch based on one
+branch to another, to pretend that you forked the topic branch
+from the latter branch, using `rebase --onto`.
+
+First let's assume your 'topic' is based on branch 'next'.
+For example, a feature developed in 'topic' depends on some
+functionality which is found in 'next'.
+
+------------
+ o---o---o---o---o master
+ \
+ o---o---o---o---o next
+ \
+ o---o---o topic
+------------
+
+We want to make 'topic' forked from branch 'master'; for example,
+because the functionality on which 'topic' depends was merged into the
+more stable 'master' branch. We want our tree to look like this:
+
+------------
+ o---o---o---o---o master
+ | \
+ | o'--o'--o' topic
+ \
+ o---o---o---o---o next
+------------
+
+We can get this using the following command:
+
+ git rebase --onto master next topic
+
+
+Another example of --onto option is to rebase part of a
+branch. If we have the following situation:
+
+------------
+ H---I---J topicB
+ /
+ E---F---G topicA
+ /
+ A---B---C---D master
+------------
+
+then the command
+
+ git rebase --onto master topicA topicB
+
+would result in:
+
+------------
+ H'--I'--J' topicB
+ /
+ | E---F---G topicA
+ |/
+ A---B---C---D master
+------------
+
+This is useful when topicB does not depend on topicA.
+
+A range of commits could also be removed with rebase. If we have
+the following situation:
+
+------------
+ E---F---G---H---I---J topicA
+------------
+
+then the command
+
+ git rebase --onto topicA~5 topicA~3 topicA
+
+would result in the removal of commits F and G:
+
+------------
+ E---H'---I'---J' topicA
+------------
+
+This is useful if F and G were flawed in some way, or should not be
+part of topicA. Note that the argument to `--onto` and the `<upstream>`
+parameter can be any valid commit-ish.
+
+
RECOVERING FROM UPSTREAM REBASE
-------------------------------
--
gitgitgadget
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v6 5/5] doc: git-rebase: update discussion of internals
2025-08-11 21:51 ` [PATCH v6 0/5] doc: git-rebase: clarify DESCRIPTION section Julia Evans via GitGitGadget
` (3 preceding siblings ...)
2025-08-11 21:51 ` [PATCH v6 4/5] doc: git-rebase: move --onto explanation down Julia Evans via GitGitGadget
@ 2025-08-11 21:51 ` Julia Evans via GitGitGadget
2025-08-11 22:10 ` Junio C Hamano
2025-08-11 21:59 ` [PATCH v6 0/5] doc: git-rebase: clarify DESCRIPTION section Junio C Hamano
` (2 subsequent siblings)
7 siblings, 1 reply; 103+ messages in thread
From: Julia Evans via GitGitGadget @ 2025-08-11 21:51 UTC (permalink / raw)
To: git
Cc: D. Ben Knoble, Phillip Wood, Patrick Steinhardt, Karthik Nayak,
Julia Evans, Julia Evans
From: Julia Evans <julia@jvns.ca>
- 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 <julia@jvns.ca>
---
Documentation/git-rebase.adoc | 63 +++++++++++------------------------
1 file changed, 20 insertions(+), 43 deletions(-)
diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc
index d041d87f270b..d4fc80ebb20c 100644
--- a/Documentation/git-rebase.adoc
+++ b/Documentation/git-rebase.adoc
@@ -68,51 +68,28 @@ 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 simplified description of what `git rebase <upstream>` does:
+
+1. Make a list of all new commits on your current branch since it branched
+ off from `<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>` and remove them from the list.
+3. Check out `<upstream>` 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 checkout -C <branch>`.
[NOTE]
-`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
-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
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [PATCH v6 0/5] doc: git-rebase: clarify DESCRIPTION section
2025-08-11 21:51 ` [PATCH v6 0/5] doc: git-rebase: clarify DESCRIPTION section Julia Evans via GitGitGadget
` (4 preceding siblings ...)
2025-08-11 21:51 ` [PATCH v6 5/5] doc: git-rebase: update discussion of internals Julia Evans via GitGitGadget
@ 2025-08-11 21:59 ` Junio C Hamano
2025-08-12 13:49 ` [PATCH v7 " Julia Evans via GitGitGadget
2025-08-13 13:31 ` [PATCH v6 0/5] doc: git-rebase: clarify DESCRIPTION section Phillip Wood
7 siblings, 0 replies; 103+ messages in thread
From: Junio C Hamano @ 2025-08-11 21:59 UTC (permalink / raw)
To: Julia Evans via GitGitGadget
Cc: git, D. Ben Knoble, Phillip Wood, Patrick Steinhardt,
Karthik Nayak, Julia Evans
"Julia Evans via GitGitGadget" <gitgitgadget@gmail.com> writes:
> * move "You can also use git rebase to reorder or combine commits:" to the
> beginning
> * replace "detailed description" with "simplified description" -- I thought
> that I could write something that was relatively readable and also
> accurate, but as usual Git has proven me wrong :). I tried to leave in
> the details that I think seem relevant to using git: for example git
> checkout --detach is relevant because it explains why git reflog works
> well after a rebase.
> * replace the git switch with git checkout that I'd missed previously
>
> I didn't use the git log --cherry-pick option in the explanation because I
> had personally never heard of that option before today, and I don't want
> people to have to read the git log man page to be able to understand the
> explanation. I also left out --reapply-cherry-picks just because I don't
> understand the use case so I couldn't evaluate how likely it is to be
> relevant to the person reading.
I agree with the above decision to leave unnecessary implementation
details out, and I also agree with the decision to talk about
rebasing done on the detached HEAD. I will find out if I agree with
the remainder of details that are kept (and left out) later by
reading the patches ;-)
Thanks.
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [PATCH v6 5/5] doc: git-rebase: update discussion of internals
2025-08-11 21:51 ` [PATCH v6 5/5] doc: git-rebase: update discussion of internals Julia Evans via GitGitGadget
@ 2025-08-11 22:10 ` Junio C Hamano
2025-08-11 22:42 ` Julia Evans
0 siblings, 1 reply; 103+ messages in thread
From: Junio C Hamano @ 2025-08-11 22:10 UTC (permalink / raw)
To: Julia Evans via GitGitGadget
Cc: git, D. Ben Knoble, Phillip Wood, Patrick Steinhardt,
Karthik Nayak, Julia Evans
"Julia Evans via GitGitGadget" <gitgitgadget@gmail.com> writes:
> +Here is a simplified description of what `git rebase <upstream>` does:
Now this is a "this is roughly how it works", we can afford to give
a simplified picture that may not exactly match the implementation,
which is great freedom to have while writing documentation for first
time users.
> +1. Make a list of all new commits on your current branch since it branched
> + off from `<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>` and remove them from the list.
So, I do not mind #2 described as a separate step. Conceptually, it
is between "create a list of all commits in the range and filter out
what have already been applied" and "create a list of all commits
that are not in the upstream yet". We may be able to rephrase "all
new commits on your current branch" somewhat to make it unnecessary
to describe #2, though. If we are willing to stop talking about
"This is the same set of ...", then the description becomes very
simple:
Make a list of all commits on your current branch since it
branched off from `<upstream>` that do not have equivalent
change in `<upstream>`.
> +3. Check out `<upstream>` with the equivalent of `git checkout --detach <upstream>`.
The line is getting overly long here and a few lines below. If your
editor has the feature, tell it to auto-wrap at around 66-72 column.
> +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 checkout -C <branch>`.
Force-create-branch while checking out is `git checkout -B
<branch>`, not -C.
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [PATCH v6 5/5] doc: git-rebase: update discussion of internals
2025-08-11 22:10 ` Junio C Hamano
@ 2025-08-11 22:42 ` Julia Evans
0 siblings, 0 replies; 103+ messages in thread
From: Julia Evans @ 2025-08-11 22:42 UTC (permalink / raw)
To: Junio C Hamano, Julia Evans
Cc: git, D. Ben Knoble, Phillip Wood, Patrick Steinhardt,
Karthik Nayak
> So, I do not mind #2 described as a separate step. Conceptually, it
> is between "create a list of all commits in the range and filter out
> what have already been applied" and "create a list of all commits
> that are not in the upstream yet". We may be able to rephrase "all
> new commits on your current branch" somewhat to make it unnecessary
> to describe #2, though. If we are willing to stop talking about
> "This is the same set of ...", then the description becomes very
> simple:
To me it feels relevant that `git rebase` is using two separate mechanisms to
compare commits: the sha and (I think?) what `git patch-id` does. As a user
it feels like an important distinction because normally when I look at my git
commits I only use the sha (via something like `git log --graph`) to see what
the new commits on a branch are.
Maybe the second part can be rephrased like this to emphasize that it's using a
different mechanism than the SHA:
> 2. Check whether any of those commits contain the same changes (according to
`git patch-id`) as a commit already in `<upstream>` and remove them from
the list.
> The line is getting overly long here and a few lines below. If your
> editor has the feature, tell it to auto-wrap at around 66-72 column.
Will fix, and I'll add a pre-commit hook to check for that.
> Force-create-branch while checking out is `git checkout -B
> <branch>`, not -C.
Will fix.
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [PATCH v4 1/5] doc: git-rebase: start with an example
2025-08-11 12:27 ` Ben Knoble
@ 2025-08-12 9:05 ` Karthik Nayak
2025-08-12 14:30 ` Junio C Hamano
0 siblings, 1 reply; 103+ messages in thread
From: Karthik Nayak @ 2025-08-12 9:05 UTC (permalink / raw)
To: Ben Knoble; +Cc: Julia Evans via GitGitGadget, git, Julia Evans
[-- Attachment #1: Type: text/plain, Size: 1857 bytes --]
Ben Knoble <ben.knoble@gmail.com> writes:
>> Le 11 août 2025 à 05:29, Karthik Nayak <karthik.188@gmail.com> a écrit :
>>
>> "Julia Evans via GitGitGadget" <gitgitgadget@gmail.com> writes:
>>>
>>> Signed-off-by: Julia Evans <julia@jvns.ca>
>>> ---
>>> Documentation/git-rebase.adoc | 49 ++++++++++++++++-------------------
>>> 1 file changed, 23 insertions(+), 26 deletions(-)
>>>
>>> diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc
>>> index 956d3048f5a6..449f01fba560 100644
>>> --- a/Documentation/git-rebase.adoc
>>> +++ b/Documentation/git-rebase.adoc
>>> @@ -16,6 +16,29 @@ SYNOPSIS
>>>
>>> DESCRIPTION
>>> -----------
>>> +Transplant a series of commits onto a different starting point.
>>> +
>>> +For example, imagine that you have been working on the `topic` branch in this
>>> +history, and you want to "catch up" to the work done on the `master` branch.
>>> +
>>> +------------
>>> + A---B---C topic
>>> + /
>>> + D---E---F---G master
>>> +------------
>>> +
>>> +You want to transplant the commits you made on `topic` since it diverged from
>>> +`master` (i.e. A, B, and C), on top of the current `master`. You can do this
>>> +by running `git rebase master` while the `topic` branch is checked out. If you
>>> +want to rebase `topic` while on another branch, `git rebase master topic` is a
>>> +shortcut for `git checkout topic && git rebase master`.
>>> +
>>
>> Nit: now that `git-switch(1)` is no longer experimental, we should start
>> recommending it over `git-checkout(1)` as necessary. So perhaps, we
>> could s/checkout/switch here?
>
> Junio previously recommended checkout (a prior version used switch): I suspect because checkout will detach head without extra syntax (where switch will not)?
I totally missed that, that makes sense!
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 690 bytes --]
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [PATCH v4 1/5] doc: git-rebase: start with an example
2025-08-11 13:07 ` Phillip Wood
@ 2025-08-12 9:07 ` Karthik Nayak
2025-08-12 17:07 ` D. Ben Knoble
0 siblings, 1 reply; 103+ messages in thread
From: Karthik Nayak @ 2025-08-12 9:07 UTC (permalink / raw)
To: Phillip Wood, Julia Evans via GitGitGadget, git; +Cc: Julia Evans
[-- Attachment #1: Type: text/plain, Size: 1292 bytes --]
Phillip Wood <phillip.wood123@gmail.com> writes:
> On 11/08/2025 10:13, Karthik Nayak wrote:
>> "Julia Evans via GitGitGadget" <gitgitgadget@gmail.com> writes:
>>> +
>>> +You want to transplant the commits you made on `topic` since it diverged from
>>> +`master` (i.e. A, B, and C), on top of the current `master`. You can do this
>>> +by running `git rebase master` while the `topic` branch is checked out. If you
>>> +want to rebase `topic` while on another branch, `git rebase master topic` is a
>>> +shortcut for `git checkout topic && git rebase master`.
>>> +
>>
>> Nit: now that `git-switch(1)` is no longer experimental, we should start
>> recommending it over `git-checkout(1)` as necessary. So perhaps, we
>> could s/checkout/switch here?
>
> Junio has already expressed a preference for "checkout" here c.f.
> <xmqqldnte6h3.fsf@gitster.g>. I think that is technically correct as
> "topic" can be a commitish and "git switch <object-id>" fails without
> "--detach". Also rebase does not do any of the extra checks that "git
> switch" does before switching branches (I'm not saying that is
> necessarily a good thing).
>
I missed that, but since we do mention that `topic` is a branch, it
still makes sense to use 'git switch'. But either way this is okay.
> Thanks
>
> Phillip
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 690 bytes --]
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v7 0/5] doc: git-rebase: clarify DESCRIPTION section
2025-08-11 21:51 ` [PATCH v6 0/5] doc: git-rebase: clarify DESCRIPTION section Julia Evans via GitGitGadget
` (5 preceding siblings ...)
2025-08-11 21:59 ` [PATCH v6 0/5] doc: git-rebase: clarify DESCRIPTION section Junio C Hamano
@ 2025-08-12 13:49 ` Julia Evans via GitGitGadget
2025-08-12 13:49 ` [PATCH v7 1/5] doc: git-rebase: start with an example Julia Evans via GitGitGadget
` (5 more replies)
2025-08-13 13:31 ` [PATCH v6 0/5] doc: git-rebase: clarify DESCRIPTION section Phillip Wood
7 siblings, 6 replies; 103+ messages in thread
From: Julia Evans via GitGitGadget @ 2025-08-12 13:49 UTC (permalink / raw)
To: git
Cc: D. Ben Knoble, Phillip Wood, Patrick Steinhardt, Karthik Nayak,
Julia Evans
* Rephrase "duplicates of commits" to clarify that in step 2, rebase is
using git patch-id (or the equivalent) to compare commits instead of
using the SHA.
* wrap some text correctly
* s/git checkout -C/git checkout -B/
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 | 304 +++++++++++++++-------------------
1 file changed, 138 insertions(+), 166 deletions(-)
base-commit: 2c2ba49d55ff26c1082b8137b1ec5eeccb4337d1
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1949%2Fjvns%2Fclarify-rebase-v7
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1949/jvns/clarify-rebase-v7
Pull-Request: https://github.com/gitgitgadget/git/pull/1949
Range-diff vs v6:
1: e7a8fbbe53c = 1: e7a8fbbe53c doc: git-rebase: start with an example
2: ad63f69918d = 2: ad63f69918d doc: git rebase: dedup merge conflict discussion
3: 7ee6b0afe88 = 3: 7ee6b0afe88 doc: git rebase: clarify arguments syntax
4: 4686417b28e = 4: 4686417b28e doc: git-rebase: move --onto explanation down
5: 9c7f2716bc8 ! 5: 79f29ad1e68 doc: git-rebase: update discussion of internals
@@ Documentation/git-rebase.adoc: linkgit:git-config[1] for details) and the `--for
+ off from `<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>` and remove them from the list.
-+3. Check out `<upstream>` with the equivalent of `git checkout --detach <upstream>`.
++2. Check whether any of those commits contain the same changes (according to
++ `git patch-id`) as a commit already in `<upstream>` and remove them from
++ the list.
++3. Check out `<upstream>` 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 checkout -C <branch>`.
++ of `git checkout -B <branch>`.
[NOTE]
-`ORIG_HEAD` is not guaranteed to still point to the previous branch tip
--
gitgitgadget
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v7 1/5] doc: git-rebase: start with an example
2025-08-12 13:49 ` [PATCH v7 " Julia Evans via GitGitGadget
@ 2025-08-12 13:49 ` Julia Evans via GitGitGadget
2025-08-12 13:49 ` [PATCH v7 2/5] doc: git rebase: dedup merge conflict discussion Julia Evans via GitGitGadget
` (4 subsequent siblings)
5 siblings, 0 replies; 103+ messages in thread
From: Julia Evans via GitGitGadget @ 2025-08-12 13:49 UTC (permalink / raw)
To: git
Cc: D. Ben Knoble, Phillip Wood, Patrick Steinhardt, Karthik Nayak,
Julia Evans, Julia Evans
From: Julia Evans <julia@jvns.ca>
- 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 <julia@jvns.ca>
---
Documentation/git-rebase.adoc | 52 +++++++++++++++++------------------
1 file changed, 26 insertions(+), 26 deletions(-)
diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc
index 956d3048f5a6..bb5a3ff7f828 100644
--- a/Documentation/git-rebase.adoc
+++ b/Documentation/git-rebase.adoc
@@ -16,6 +16,32 @@ SYNOPSIS
DESCRIPTION
-----------
+Transplant a series of commits onto a different starting point.
+You can also use `git rebase` to reorder or combine commits: see INTERACTIVE
+MODE below for how to do that.
+
+For example, imagine that you have been working on the `topic` branch in this
+history, and you want to "catch up" to the work done on the `master` branch.
+
+------------
+ A---B---C topic
+ /
+ D---E---F---G master
+------------
+
+You want to transplant the commits you made on `topic` since it diverged from
+`master` (i.e. A, B, and C), on top of the current `master`. You can do this
+by running `git rebase master` while the `topic` branch is checked out. If you
+want to rebase `topic` while on another branch, `git rebase master topic` is a
+shortcut for `git checkout topic && git rebase master`.
+
+------------
+ A'--B'--C' topic
+ /
+ D---E---F---G master
+------------
+
+
If `<branch>` is specified, `git rebase` will perform an automatic
`git switch <branch>` before doing anything else. Otherwise
it remains on the current branch.
@@ -58,32 +84,6 @@ that caused the merge failure with `git rebase --skip`. To check out the
original `<branch>` and remove the `.git/rebase-apply` working files, use
the command `git rebase --abort` instead.
-Assume the following history exists and the current branch is "topic":
-
-------------
- A---B---C topic
- /
- D---E---F---G master
-------------
-
-From this point, the result of either of the following commands:
-
-
- git rebase master
- git rebase master topic
-
-would be:
-
-------------
- A'--B'--C' topic
- /
- D---E---F---G master
-------------
-
-*NOTE:* The latter form is just a short-hand of `git checkout topic`
-followed by `git rebase master`. When rebase exits `topic` will
-remain the checked-out branch.
-
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
--
gitgitgadget
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v7 2/5] doc: git rebase: dedup merge conflict discussion
2025-08-12 13:49 ` [PATCH v7 " Julia Evans via GitGitGadget
2025-08-12 13:49 ` [PATCH v7 1/5] doc: git-rebase: start with an example Julia Evans via GitGitGadget
@ 2025-08-12 13:49 ` Julia Evans via GitGitGadget
2025-08-12 13:49 ` [PATCH v7 3/5] doc: git rebase: clarify arguments syntax Julia Evans via GitGitGadget
` (3 subsequent siblings)
5 siblings, 0 replies; 103+ messages in thread
From: Julia Evans via GitGitGadget @ 2025-08-12 13:49 UTC (permalink / raw)
To: git
Cc: D. Ben Knoble, Phillip Wood, Patrick Steinhardt, Karthik Nayak,
Julia Evans, Julia Evans
From: Julia Evans <julia@jvns.ca>
Previously there were two explanations, this combines them both into a
single explanation.
Signed-off-by: Julia Evans <julia@jvns.ca>
---
Documentation/git-rebase.adoc | 49 ++++++++++++++---------------------
1 file changed, 20 insertions(+), 29 deletions(-)
diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc
index bb5a3ff7f828..e82ceb9cbfce 100644
--- a/Documentation/git-rebase.adoc
+++ b/Documentation/git-rebase.adoc
@@ -42,6 +42,26 @@ shortcut for `git checkout topic && git rebase master`.
------------
+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
+one of these things:
+
+1. Resolve the conflict. You can use `git diff` to find the markers (<<<<<<)
+ and make edits to resolve the conflict. For each file you edit, you need to
+ tell Git that the conflict has been resolved. You can mark the conflict as
+ resolved with `git add <filename>`. After resolving all of the conflicts,
+ you can continue the rebasing process with
+
+ git rebase --continue
+
+2. Stop the `git rebase` and return your branch to its original state with
+
+ git rebase --abort
+
+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
it remains on the current branch.
@@ -77,13 +97,6 @@ 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).
-It is possible that a merge failure will prevent this process from being
-completely automatic. You will have to resolve any such merge failure
-and run `git rebase --continue`. Another option is to bypass the commit
-that caused the merge failure with `git rebase --skip`. To check out the
-original `<branch>` and remove the `.git/rebase-apply` working files, use
-the command `git rebase --abort` instead.
-
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
@@ -186,28 +199,6 @@ This is useful if F and G were flawed in some way, or should not be
part of topicA. Note that the argument to `--onto` and the `<upstream>`
parameter can be any valid commit-ish.
-In case of conflict, `git rebase` will stop at the first problematic commit
-and leave conflict markers in the tree. You can use `git diff` to locate
-the markers (<<<<<<) and make edits to resolve the conflict. For each
-file you edit, you need to tell Git that the conflict has been resolved,
-typically this would be done with
-
-
- git add <filename>
-
-
-After resolving the conflict manually and updating the index with the
-desired resolution, you can continue the rebasing process with
-
-
- git rebase --continue
-
-
-Alternatively, you can undo the 'git rebase' with
-
-
- git rebase --abort
-
MODE OPTIONS
------------
--
gitgitgadget
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v7 3/5] doc: git rebase: clarify arguments syntax
2025-08-12 13:49 ` [PATCH v7 " Julia Evans via GitGitGadget
2025-08-12 13:49 ` [PATCH v7 1/5] doc: git-rebase: start with an example Julia Evans via GitGitGadget
2025-08-12 13:49 ` [PATCH v7 2/5] doc: git rebase: dedup merge conflict discussion Julia Evans via GitGitGadget
@ 2025-08-12 13:49 ` Julia Evans via GitGitGadget
2025-08-12 13:49 ` [PATCH v7 4/5] doc: git-rebase: move --onto explanation down Julia Evans via GitGitGadget
` (2 subsequent siblings)
5 siblings, 0 replies; 103+ messages in thread
From: Julia Evans via GitGitGadget @ 2025-08-12 13:49 UTC (permalink / raw)
To: git
Cc: D. Ben Knoble, Phillip Wood, Patrick Steinhardt, Karthik Nayak,
Julia Evans, Julia Evans
From: Julia Evans <julia@jvns.ca>
Remove duplicate explanation of `git rebase <upstream> <branch>` which
is already explained above.
Signed-off-by: Julia Evans <julia@jvns.ca>
---
Documentation/git-rebase.adoc | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc
index e82ceb9cbfce..6d02648a9b3c 100644
--- a/Documentation/git-rebase.adoc
+++ b/Documentation/git-rebase.adoc
@@ -62,11 +62,7 @@ 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.
-
-If `<upstream>` is not specified, the upstream configured in
+If you don't specify an `<upstream>` to rebase onto, the upstream configured in
`branch.<name>.remote` and `branch.<name>.merge` options will be used (see
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
--
gitgitgadget
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v7 4/5] doc: git-rebase: move --onto explanation down
2025-08-12 13:49 ` [PATCH v7 " Julia Evans via GitGitGadget
` (2 preceding siblings ...)
2025-08-12 13:49 ` [PATCH v7 3/5] doc: git rebase: clarify arguments syntax Julia Evans via GitGitGadget
@ 2025-08-12 13:49 ` Julia Evans via GitGitGadget
2025-08-12 13:49 ` [PATCH v7 5/5] doc: git-rebase: update discussion of internals Julia Evans via GitGitGadget
2025-08-15 16:52 ` [PATCH v8 0/5] doc: git-rebase: clarify DESCRIPTION section Julia Evans via GitGitGadget
5 siblings, 0 replies; 103+ messages in thread
From: Julia Evans via GitGitGadget @ 2025-08-12 13:49 UTC (permalink / raw)
To: git
Cc: D. Ben Knoble, Phillip Wood, Patrick Steinhardt, Karthik Nayak,
Julia Evans, Julia Evans
From: Julia Evans <julia@jvns.ca>
There's a very clear explanation with examples of using --onto which is
currently buried in the very long DESCRIPTION section. This moves it to
its own section, so that we can reference the explanation from the
`--onto` option by name.
Signed-off-by: Julia Evans <julia@jvns.ca>
---
Documentation/git-rebase.adoc | 168 ++++++++++++++++++----------------
1 file changed, 87 insertions(+), 81 deletions(-)
diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc
index 6d02648a9b3c..d041d87f270b 100644
--- a/Documentation/git-rebase.adoc
+++ b/Documentation/git-rebase.adoc
@@ -114,87 +114,6 @@ will result in:
D---E---A'---F master
------------
-Here is how you would transplant a topic branch based on one
-branch to another, to pretend that you forked the topic branch
-from the latter branch, using `rebase --onto`.
-
-First let's assume your 'topic' is based on branch 'next'.
-For example, a feature developed in 'topic' depends on some
-functionality which is found in 'next'.
-
-------------
- o---o---o---o---o master
- \
- o---o---o---o---o next
- \
- o---o---o topic
-------------
-
-We want to make 'topic' forked from branch 'master'; for example,
-because the functionality on which 'topic' depends was merged into the
-more stable 'master' branch. We want our tree to look like this:
-
-------------
- o---o---o---o---o master
- | \
- | o'--o'--o' topic
- \
- o---o---o---o---o next
-------------
-
-We can get this using the following command:
-
- git rebase --onto master next topic
-
-
-Another example of --onto option is to rebase part of a
-branch. If we have the following situation:
-
-------------
- H---I---J topicB
- /
- E---F---G topicA
- /
- A---B---C---D master
-------------
-
-then the command
-
- git rebase --onto master topicA topicB
-
-would result in:
-
-------------
- H'--I'--J' topicB
- /
- | E---F---G topicA
- |/
- A---B---C---D master
-------------
-
-This is useful when topicB does not depend on topicA.
-
-A range of commits could also be removed with rebase. If we have
-the following situation:
-
-------------
- E---F---G---H---I---J topicA
-------------
-
-then the command
-
- git rebase --onto topicA~5 topicA~3 topicA
-
-would result in the removal of commits F and G:
-
-------------
- E---H'---I'---J' topicA
-------------
-
-This is useful if F and G were flawed in some way, or should not be
-part of topicA. Note that the argument to `--onto` and the `<upstream>`
-parameter can be any valid commit-ish.
-
MODE OPTIONS
------------
@@ -240,6 +159,8 @@ As a special case, you may use "A\...B" as a shortcut for the
merge base of A and B if there is exactly one merge base. You can
leave out at most one of A and B, in which case it defaults to HEAD.
+See TRANSPLANTING A TOPIC BRANCH WITH --ONTO below for examples.
+
--keep-base::
Set the starting point at which to create the new commits to the
merge base of `<upstream>` and `<branch>`. Running
@@ -1018,6 +939,91 @@ consistent (they compile, pass the testsuite, etc.) you should use
after each commit, test, and amend the commit if fixes are necessary.
+TRANSPLANTING A TOPIC BRANCH WITH --ONTO
+----------------------------------------
+
+Here is how you would transplant a topic branch based on one
+branch to another, to pretend that you forked the topic branch
+from the latter branch, using `rebase --onto`.
+
+First let's assume your 'topic' is based on branch 'next'.
+For example, a feature developed in 'topic' depends on some
+functionality which is found in 'next'.
+
+------------
+ o---o---o---o---o master
+ \
+ o---o---o---o---o next
+ \
+ o---o---o topic
+------------
+
+We want to make 'topic' forked from branch 'master'; for example,
+because the functionality on which 'topic' depends was merged into the
+more stable 'master' branch. We want our tree to look like this:
+
+------------
+ o---o---o---o---o master
+ | \
+ | o'--o'--o' topic
+ \
+ o---o---o---o---o next
+------------
+
+We can get this using the following command:
+
+ git rebase --onto master next topic
+
+
+Another example of --onto option is to rebase part of a
+branch. If we have the following situation:
+
+------------
+ H---I---J topicB
+ /
+ E---F---G topicA
+ /
+ A---B---C---D master
+------------
+
+then the command
+
+ git rebase --onto master topicA topicB
+
+would result in:
+
+------------
+ H'--I'--J' topicB
+ /
+ | E---F---G topicA
+ |/
+ A---B---C---D master
+------------
+
+This is useful when topicB does not depend on topicA.
+
+A range of commits could also be removed with rebase. If we have
+the following situation:
+
+------------
+ E---F---G---H---I---J topicA
+------------
+
+then the command
+
+ git rebase --onto topicA~5 topicA~3 topicA
+
+would result in the removal of commits F and G:
+
+------------
+ E---H'---I'---J' topicA
+------------
+
+This is useful if F and G were flawed in some way, or should not be
+part of topicA. Note that the argument to `--onto` and the `<upstream>`
+parameter can be any valid commit-ish.
+
+
RECOVERING FROM UPSTREAM REBASE
-------------------------------
--
gitgitgadget
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v7 5/5] doc: git-rebase: update discussion of internals
2025-08-12 13:49 ` [PATCH v7 " Julia Evans via GitGitGadget
` (3 preceding siblings ...)
2025-08-12 13:49 ` [PATCH v7 4/5] doc: git-rebase: move --onto explanation down Julia Evans via GitGitGadget
@ 2025-08-12 13:49 ` Julia Evans via GitGitGadget
2025-08-14 21:28 ` Junio C Hamano
2025-08-15 16:52 ` [PATCH v8 0/5] doc: git-rebase: clarify DESCRIPTION section Julia Evans via GitGitGadget
5 siblings, 1 reply; 103+ messages in thread
From: Julia Evans via GitGitGadget @ 2025-08-12 13:49 UTC (permalink / raw)
To: git
Cc: D. Ben Knoble, Phillip Wood, Patrick Steinhardt, Karthik Nayak,
Julia Evans, Julia Evans
From: Julia Evans <julia@jvns.ca>
- 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 <julia@jvns.ca>
---
Documentation/git-rebase.adoc | 65 ++++++++++++-----------------------
1 file changed, 22 insertions(+), 43 deletions(-)
diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc
index d041d87f270b..cce2577a8ade 100644
--- a/Documentation/git-rebase.adoc
+++ b/Documentation/git-rebase.adoc
@@ -68,51 +68,30 @@ 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 simplified description of what `git rebase <upstream>` does:
+
+1. Make a list of all new commits on your current branch since it branched
+ off from `<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 contain the same changes (according to
+ `git patch-id`) as a commit already in `<upstream>` and remove them from
+ the list.
+3. Check out `<upstream>` 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 checkout -B <branch>`.
[NOTE]
-`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
-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
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [PATCH v4 1/5] doc: git-rebase: start with an example
2025-08-12 9:05 ` Karthik Nayak
@ 2025-08-12 14:30 ` Junio C Hamano
0 siblings, 0 replies; 103+ messages in thread
From: Junio C Hamano @ 2025-08-12 14:30 UTC (permalink / raw)
To: Karthik Nayak; +Cc: Ben Knoble, Julia Evans via GitGitGadget, git, Julia Evans
Karthik Nayak <karthik.188@gmail.com> writes:
>>> Nit: now that `git-switch(1)` is no longer experimental, we should start
>>> recommending it over `git-checkout(1)` as necessary. So perhaps, we
>>> could s/checkout/switch here?
Besides, the reason why it is no longer experimental is *not*
because it has proved to be so much better than "checkout" and the
users are encouraged to use it.
It is no longer experimental only because it and its set of options
are now engraved in users' mustle memory deep enough that we can no
longer change it without disrupting users. We were hoping to
improve its end-user experience relative to "checkout", and allowed
it to deviate from the precendent that was set by "git checkout",
and that was the reason why "this is experimental. UI and behaviour
is subject to change" label was on it.
The experiment unfortunately was not a great success. There were
only a few meaningful differences invented during the experiment.
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [PATCH v4 1/5] doc: git-rebase: start with an example
2025-08-12 9:07 ` Karthik Nayak
@ 2025-08-12 17:07 ` D. Ben Knoble
2025-08-12 18:07 ` Junio C Hamano
0 siblings, 1 reply; 103+ messages in thread
From: D. Ben Knoble @ 2025-08-12 17:07 UTC (permalink / raw)
To: Karthik Nayak
Cc: Phillip Wood, Julia Evans via GitGitGadget, git, Julia Evans
On Tue, Aug 12, 2025 at 5:11 AM Karthik Nayak <karthik.188@gmail.com> wrote:
>
> Phillip Wood <phillip.wood123@gmail.com> writes:
>
> > On 11/08/2025 10:13, Karthik Nayak wrote:
> >> "Julia Evans via GitGitGadget" <gitgitgadget@gmail.com> writes:
> >>> +
> >>> +You want to transplant the commits you made on `topic` since it diverged from
> >>> +`master` (i.e. A, B, and C), on top of the current `master`. You can do this
> >>> +by running `git rebase master` while the `topic` branch is checked out. If you
> >>> +want to rebase `topic` while on another branch, `git rebase master topic` is a
> >>> +shortcut for `git checkout topic && git rebase master`.
> >>> +
> >>
> >> Nit: now that `git-switch(1)` is no longer experimental, we should start
> >> recommending it over `git-checkout(1)` as necessary. So perhaps, we
> >> could s/checkout/switch here?
> >
> > Junio has already expressed a preference for "checkout" here c.f.
> > <xmqqldnte6h3.fsf@gitster.g>. I think that is technically correct as
> > "topic" can be a commitish and "git switch <object-id>" fails without
> > "--detach". Also rebase does not do any of the extra checks that "git
> > switch" does before switching branches (I'm not saying that is
> > necessarily a good thing).
> >
>
> I missed that, but since we do mention that `topic` is a branch, it
> still makes sense to use 'git switch'. But either way this is okay.
In the general case, it may not be a branch though. (Of course, that's
too confusing a detail for this section anyway.)
--
D. Ben Knoble
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [PATCH v4 1/5] doc: git-rebase: start with an example
2025-08-12 17:07 ` D. Ben Knoble
@ 2025-08-12 18:07 ` Junio C Hamano
2025-08-14 7:23 ` Karthik Nayak
0 siblings, 1 reply; 103+ messages in thread
From: Junio C Hamano @ 2025-08-12 18:07 UTC (permalink / raw)
To: D. Ben Knoble
Cc: Karthik Nayak, Phillip Wood, Julia Evans via GitGitGadget, git,
Julia Evans
"D. Ben Knoble" <ben.knoble@gmail.com> writes:
>> > Junio has already expressed a preference for "checkout" here c.f.
>> > <xmqqldnte6h3.fsf@gitster.g>. I think that is technically correct as
>> > "topic" can be a commitish and "git switch <object-id>" fails without
>> > "--detach".
I wanted the new documentation text to use what was already used in
the parts of the document that are not touched; otherwise we end up
with text that uses checkout in some places and switch in others,
which would invite confusions among uninitiated readers, who
rightfully would wonder what criteria were used to decide which one
among these two different commands to use. And teaching that these
two commands are quasi-equivalent with possibly subtle differences
is not what the documentation of "git rebase" needs to do---it is a
distraction.
I do not mind a new proposal to do a documentation sweep, aiming for
Git 3.0 timeframe, to examine all mentions of "git checkout" in the
documentation and replace them with "git switch" or "git restore"
when appropriate (there are of course ones that are not for obvious
reasons, like the ones in "git checkout" documentation itself, and
possibly in "git switch" and "git restore" documentation pages that
may say things like "'git switch X' is similar to 'git checkout Y'").
But let's leave that outside this topic.
Thanks.
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [PATCH v6 0/5] doc: git-rebase: clarify DESCRIPTION section
2025-08-11 21:51 ` [PATCH v6 0/5] doc: git-rebase: clarify DESCRIPTION section Julia Evans via GitGitGadget
` (6 preceding siblings ...)
2025-08-12 13:49 ` [PATCH v7 " Julia Evans via GitGitGadget
@ 2025-08-13 13:31 ` Phillip Wood
2025-08-13 15:33 ` Julia Evans
7 siblings, 1 reply; 103+ messages in thread
From: Phillip Wood @ 2025-08-13 13:31 UTC (permalink / raw)
To: Julia Evans via GitGitGadget, git
Cc: D. Ben Knoble, Patrick Steinhardt, Karthik Nayak, Julia Evans
Hi Julia
On 11/08/2025 22:51, Julia Evans via GitGitGadget wrote:
> * move "You can also use git rebase to reorder or combine commits:" to the
> beginning
Great
> * replace "detailed description" with "simplified description" -- I thought
> that I could write something that was relatively readable and also
> accurate, but as usual Git has proven me wrong :). I tried to leave in
> the details that I think seem relevant to using git: for example git
> checkout --detach is relevant because it explains why git reflog works
> well after a rebase.
> * replace the git switch with git checkout that I'd missed previously
>
> I didn't use the git log --cherry-pick option in the explanation because I
> had personally never heard of that option before today, and I don't want
> people to have to read the git log man page to be able to understand the
> explanation. I also left out --reapply-cherry-picks just because I don't
> understand the use case so I couldn't evaluate how likely it is to be
> relevant to the person reading.
The use case for --reapply-cherry-picks is mostly that it is faster to
try picking a commit and then drop it if it results in a empty change
than it is to do the patch-id comparisons to avoid picking the commit in
the first place. This is especially true on partial clones where the
cherry-pick detection is really slow. I'm happy to leave it out but I
wonder if we should drop the references to --fork-point and --root as
well given they're also both pretty niche. I'd also be very happy to go
with Junio's suggestion to replace steps 1 & 2 with a general
description that does not mention 'git log' at all.
Thanks
Phillip
>
> 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 | 302 +++++++++++++++-------------------
> 1 file changed, 136 insertions(+), 166 deletions(-)
>
>
> base-commit: 2c2ba49d55ff26c1082b8137b1ec5eeccb4337d1
> Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1949%2Fjvns%2Fclarify-rebase-v6
> Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1949/jvns/clarify-rebase-v6
> Pull-Request: https://github.com/gitgitgadget/git/pull/1949
>
> Range-diff vs v5:
>
> 1: c2f2e05078f ! 1: e7a8fbbe53c doc: git-rebase: start with an example
> @@ Documentation/git-rebase.adoc: SYNOPSIS
> DESCRIPTION
> -----------
> +Transplant a series of commits onto a different starting point.
> ++You can also use `git rebase` to reorder or combine commits: see INTERACTIVE
> ++MODE below for how to do that.
> +
> +For example, imagine that you have been working on the `topic` branch in this
> +history, and you want to "catch up" to the work done on the `master` branch.
> @@ 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: 5459b7ff560 ! 2: ad63f69918d 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`.
> - 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
> 3: 948c205f1e6 = 3: 7ee6b0afe88 doc: git rebase: clarify arguments syntax
> 4: e229b9fccb2 = 4: 4686417b28e doc: git-rebase: move --onto explanation down
> 5: 5ab235b067b ! 5: 9c7f2716bc8 doc: git-rebase: update discussion of internals
> @@ Documentation/git-rebase.adoc: linkgit:git-config[1] for details) and the `--for
> -`--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:
> ++Here is a simplified description of what `git rebase <upstream>` does:
> +
> -+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.
> ++1. Make a list of all new commits on your current branch since it branched
> ++ off from `<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>`.
> ++ in `<upstream>` and remove them from the list.
> ++3. Check out `<upstream>` 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>`.
> ++ of `git checkout -C <branch>`.
>
> [NOTE]
> -`ORIG_HEAD` is not guaranteed to still point to the previous branch tip
>
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [PATCH v6 0/5] doc: git-rebase: clarify DESCRIPTION section
2025-08-13 13:31 ` [PATCH v6 0/5] doc: git-rebase: clarify DESCRIPTION section Phillip Wood
@ 2025-08-13 15:33 ` Julia Evans
2025-08-14 21:18 ` Junio C Hamano
2025-08-15 10:25 ` Phillip Wood
0 siblings, 2 replies; 103+ messages in thread
From: Julia Evans @ 2025-08-13 15:33 UTC (permalink / raw)
To: phillip.wood, Julia Evans, git
Cc: D. Ben Knoble, Patrick Steinhardt, Karthik Nayak
> The use case for --reapply-cherry-picks is mostly that it is faster to
> try picking a commit and then drop it if it results in a empty change
> than it is to do the patch-id comparisons to avoid picking the commit in
> the first place. This is especially true on partial clones where the
> cherry-pick detection is really slow.
That makes sense, thank you!
> I'm happy to leave it out but I
> wonder if we should drop the references to --fork-point and --root as
> well given they're also both pretty niche. I'd also be very happy to go
> with Junio's suggestion to replace steps 1 & 2 with a general
> description that does not mention 'git log' at all.
I like the idea of leaving out `--fork-point` and `--root`.
Now that I know the use case for `--reapply-cherry-picks`: what I like about
leaving in the `git log` description is that I think it makes it easier for
folks to build a mental model of why a `git rebase` might be slow: there's a
"fast step" (the `git log` step) and a "slow step" (the `git patch-id` step).
Then even if we don't mention `--reapply-cherry-picks` in this section, a user
could infer that there might be a way to speed up the "slow step", and find the
`--reapply-cherry-picks` option to speed it up. Maybe we could mention that the
`git patch-id` step can be slow in some cases.
(also I might have misunderstood the "fast step" and the "slow step" thing,
I'd be interested to know if so)
^ permalink raw reply [flat|nested] 103+ messages in thread
* symmetric difference with --left-only vs. range notation
2025-08-10 15:42 ` Phillip Wood
@ 2025-08-13 18:55 ` D. Ben Knoble
2025-08-13 21:40 ` Junio C Hamano
0 siblings, 1 reply; 103+ messages in thread
From: D. Ben Knoble @ 2025-08-13 18:55 UTC (permalink / raw)
To: Phillip Wood; +Cc: Julia Evans via GitGitGadget, Git, Julia Evans
On Sun, Aug 10, 2025 at 11:42 AM Phillip Wood <phillip.wood123@gmail.com> wrote:
>
> Hi Julia
>
> On 09/08/2025 02:14, Julia Evans via GitGitGadget wrote:
> > From: Julia Evans <julia@jvns.ca>
> >
> > +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`.
>
> The existing text is not quite accurate here, it should really say `git
> log --cherry-pick --right-only <upstream>...HEAD` as we drop any commits
> from the branch that have already been cherry-picked to <upstream>.
This reminds me, I've been meaning to ask: is there a meaningful
difference between the following 2 commands?
git rev-list --count --left-only @{u}...
git rev-list --count ..@{u}
In my estimation, since we're not using --cherry-pick here, the first
says "list (count) the commits on upstream but not in HEAD, since the
merge-base (which is reachable from both)" while the second says "list
(count) the commits on upstream but not in HEAD." Is there ever a
situation where those sets aren't the same?
Of course the symmetric difference is not always the same as the range
notation, but when we add --left-only [or --right-only, by symmetry
;)], does this collapse to the 2-dot notation?
I've been assuming the latter is more performant, too, but if that's
not the case, that's also good to know.
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: symmetric difference with --left-only vs. range notation
2025-08-13 18:55 ` symmetric difference with --left-only vs. range notation D. Ben Knoble
@ 2025-08-13 21:40 ` Junio C Hamano
0 siblings, 0 replies; 103+ messages in thread
From: Junio C Hamano @ 2025-08-13 21:40 UTC (permalink / raw)
To: D. Ben Knoble
Cc: Phillip Wood, Julia Evans via GitGitGadget, Git, Julia Evans
"D. Ben Knoble" <ben.knoble@gmail.com> writes:
> git rev-list --count --left-only @{u}...
> git rev-list --count ..@{u}
>
> In my estimation, since we're not using --cherry-pick here, the first
> says "list (count) the commits on upstream but not in HEAD, since the
> merge-base (which is reachable from both)" while the second says "list
> (count) the commits on upstream but not in HEAD." Is there ever a
> situation where those sets aren't the same?
I don't think of any; let us know when you find a case that the
above does not hold true ;-).
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [PATCH v4 1/5] doc: git-rebase: start with an example
2025-08-12 18:07 ` Junio C Hamano
@ 2025-08-14 7:23 ` Karthik Nayak
0 siblings, 0 replies; 103+ messages in thread
From: Karthik Nayak @ 2025-08-14 7:23 UTC (permalink / raw)
To: Junio C Hamano, D. Ben Knoble
Cc: Phillip Wood, Julia Evans via GitGitGadget, git, Julia Evans
[-- Attachment #1: Type: text/plain, Size: 1509 bytes --]
Junio C Hamano <gitster@pobox.com> writes:
> "D. Ben Knoble" <ben.knoble@gmail.com> writes:
>
>>> > Junio has already expressed a preference for "checkout" here c.f.
>>> > <xmqqldnte6h3.fsf@gitster.g>. I think that is technically correct as
>>> > "topic" can be a commitish and "git switch <object-id>" fails without
>>> > "--detach".
>
> I wanted the new documentation text to use what was already used in
> the parts of the document that are not touched; otherwise we end up
> with text that uses checkout in some places and switch in others,
> which would invite confusions among uninitiated readers, who
> rightfully would wonder what criteria were used to decide which one
> among these two different commands to use. And teaching that these
> two commands are quasi-equivalent with possibly subtle differences
> is not what the documentation of "git rebase" needs to do---it is a
> distraction.
>
> I do not mind a new proposal to do a documentation sweep, aiming for
> Git 3.0 timeframe, to examine all mentions of "git checkout" in the
> documentation and replace them with "git switch" or "git restore"
> when appropriate (there are of course ones that are not for obvious
> reasons, like the ones in "git checkout" documentation itself, and
> possibly in "git switch" and "git restore" documentation pages that
> may say things like "'git switch X' is similar to 'git checkout Y'").
>
I think this is the best way to tackle this.
> But let's leave that outside this topic.
>
Agreed.
> Thanks.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 690 bytes --]
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [PATCH v6 0/5] doc: git-rebase: clarify DESCRIPTION section
2025-08-13 15:33 ` Julia Evans
@ 2025-08-14 21:18 ` Junio C Hamano
2025-08-15 10:25 ` Phillip Wood
2025-08-15 10:25 ` Phillip Wood
1 sibling, 1 reply; 103+ messages in thread
From: Junio C Hamano @ 2025-08-14 21:18 UTC (permalink / raw)
To: Julia Evans
Cc: phillip.wood, Julia Evans, git, D. Ben Knoble, Patrick Steinhardt,
Karthik Nayak
"Julia Evans" <julia@jvns.ca> writes:
>> well given they're also both pretty niche. I'd also be very happy to go
>> with Junio's suggestion to replace steps 1 & 2 with a general
>> description that does not mention 'git log' at all.
>
> I like the idea of leaving out `--fork-point` and `--root`.
>
> Now that I know the use case for `--reapply-cherry-picks`: what I like about
> leaving in the `git log` description is that I think it makes it easier for
> folks to build a mental model of why a `git rebase` might be slow: there's a
> "fast step" (the `git log` step) and a "slow step" (the `git patch-id` step).
But that is not what goes on, is it? What you wrote as if they were
two separate steps (1 to enumerate, 2 to filter) is not what happens
in practice. Whether it is done via the "format-patch --stdout | am"
pipeline in run_am(), or via the "rev-list --reverse | xargs -n1
cherry-pick" pipeline in run_sequencer_rebase(), the upstream of
these conceptual pipelines that enumerates what is to be replayed is
run just once, i.e. there is only one step that "enumerates what is
to be replayed", without a separate filtering step.
In other words, there is no "a fast step followed by a slow step".
Perhaps squashing the first two steps into one and phrasing them as
a single step is sufficient to give a conceptual overview (what you
have in v7 as "a simplified description of what the command does").
1. Make a list of all commits on your current branch since it
branched off from `<upstream>` that do not have equivalent
change in `<upstream>`.
If you want to keep 1 & 2 separate, then rephrase the introductory
sentence to clarify that we are giving a white lie for the sake of
easier understanding, e.g.
Here is what conceptually happens in "git rebase":
or something.
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [PATCH v7 5/5] doc: git-rebase: update discussion of internals
2025-08-12 13:49 ` [PATCH v7 5/5] doc: git-rebase: update discussion of internals Julia Evans via GitGitGadget
@ 2025-08-14 21:28 ` Junio C Hamano
0 siblings, 0 replies; 103+ messages in thread
From: Junio C Hamano @ 2025-08-14 21:28 UTC (permalink / raw)
To: Julia Evans via GitGitGadget
Cc: git, D. Ben Knoble, Phillip Wood, Patrick Steinhardt,
Karthik Nayak, Julia Evans
"Julia Evans via GitGitGadget" <gitgitgadget@gmail.com> writes:
> +Here is a simplified description of what `git rebase <upstream>` does:
> +
> +1. Make a list of all new commits on your current branch since it branched
> + off from `<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 contain the same changes (according to
> + `git patch-id`) as a commit already in `<upstream>` and remove them from
> + the list.
I'd suggest three things
* Rewrite the introductory text to
Here is what "git rebase <upstream> [<branch>]" conceptually does:
* Add step 0. to make "your current branch" in the next step valid.
0. When <branch> is given, check it out and make it your current
branch.
* Combine the steps 1 & 2. and stop talking about "git log" whose
invocation cannot be precisely described here anyway.
Other than that, the remainder of the series (v7 [1-4/5]) looked
good.
THanks.
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [PATCH v6 0/5] doc: git-rebase: clarify DESCRIPTION section
2025-08-13 15:33 ` Julia Evans
2025-08-14 21:18 ` Junio C Hamano
@ 2025-08-15 10:25 ` Phillip Wood
1 sibling, 0 replies; 103+ messages in thread
From: Phillip Wood @ 2025-08-15 10:25 UTC (permalink / raw)
To: Julia Evans, phillip.wood, Julia Evans, git
Cc: D. Ben Knoble, Patrick Steinhardt, Karthik Nayak
On 13/08/2025 16:33, Julia Evans wrote:
>
>> I'm happy to leave it out but I
>> wonder if we should drop the references to --fork-point and --root as
>> well given they're also both pretty niche. I'd also be very happy to go
>> with Junio's suggestion to replace steps 1 & 2 with a general
>> description that does not mention 'git log' at all.
>
> I like the idea of leaving out `--fork-point` and `--root`.
>
> Now that I know the use case for `--reapply-cherry-picks`: what I like about
> leaving in the `git log` description is that I think it makes it easier for
> folks to build a mental model of why a `git rebase` might be slow: there's a
> "fast step" (the `git log` step) and a "slow step" (the `git patch-id` step).
> Then even if we don't mention `--reapply-cherry-picks` in this section, a user
> could infer that there might be a way to speed up the "slow step", and find the
> `--reapply-cherry-picks` option to speed it up.
Possibly though I think they'd need a reasonably good understanding of
how the cherry-pick detection works - do most folks really know what a
patch-id is and that detecting cherry-picks means generating a diff for
each commit on either side of the merge base?
> Maybe we could mention that the
> `git patch-id` step can be slow in some cases.
That might be worth it depending on how much detail we want. I think it
is only really a problem on large fast-moving repositories where a lot
of upstream commits get added between rebases and on partial clones. The
latter is due to a sub-optimal implementation that does not batch the
fetches for missing blobs, though I guess if your repository is big
enough to warrant a partial clone you'd be likely to hit the first issue
even if the fetching was more efficient. If we say it can be slow we
should perhaps mention that this step can be skipped
> (also I might have misunderstood the "fast step" and the "slow step" thing,
> I'd be interested to know if so)
I've commented on this in my reply to Junio - I think it depends where
you draw the stop boundaries.
Thanks
Phillip
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [PATCH v6 0/5] doc: git-rebase: clarify DESCRIPTION section
2025-08-14 21:18 ` Junio C Hamano
@ 2025-08-15 10:25 ` Phillip Wood
2025-08-15 15:45 ` Junio C Hamano
0 siblings, 1 reply; 103+ messages in thread
From: Phillip Wood @ 2025-08-15 10:25 UTC (permalink / raw)
To: Junio C Hamano, Julia Evans
Cc: phillip.wood, Julia Evans, git, D. Ben Knoble, Patrick Steinhardt,
Karthik Nayak
On 14/08/2025 22:18, Junio C Hamano wrote:
> "Julia Evans" <julia@jvns.ca> writes:
>
>>> well given they're also both pretty niche. I'd also be very happy to go
>>> with Junio's suggestion to replace steps 1 & 2 with a general
>>> description that does not mention 'git log' at all.
>>
>> I like the idea of leaving out `--fork-point` and `--root`.
>>
>> Now that I know the use case for `--reapply-cherry-picks`: what I like about
>> leaving in the `git log` description is that I think it makes it easier for
>> folks to build a mental model of why a `git rebase` might be slow: there's a
>> "fast step" (the `git log` step) and a "slow step" (the `git patch-id` step).
>
> But that is not what goes on, is it? What you wrote as if they were
> two separate steps (1 to enumerate, 2 to filter) is not what happens
> in practice. Whether it is done via the "format-patch --stdout | am"
> pipeline in run_am(), or via the "rev-list --reverse | xargs -n1
> cherry-pick" pipeline in run_sequencer_rebase(), the upstream of
> these conceptual pipelines that enumerates what is to be replayed is
> run just once, i.e. there is only one step that "enumerates what is
> to be replayed", without a separate filtering step.
>
> In other words, there is no "a fast step followed by a slow step".
Although the cherry-pick detection happens inside "git log" that command
has a fast step (find the commits on both sides of the merge base) and a
slow step (detect cherry-picks) so I think it depends where one draws
the step boundaries. The cherry-pick detection is known to be slow when
there are a lot of new upstream commits which was the motivation for
adding --reapply-cherry-picks in 0fcb4f6b62 (rebase --merge: optionally
skip upstreamed commits, 2020-04-11)
> Perhaps squashing the first two steps into one and phrasing them as
> a single step is sufficient to give a conceptual overview (what you
> have in v7 as "a simplified description of what the command does").
>
> 1. Make a list of all commits on your current branch since it
> branched off from `<upstream>` that do not have equivalent
> change in `<upstream>`.
>
> If you want to keep 1 & 2 separate, then rephrase the introductory
> sentence to clarify that we are giving a white lie for the sake of
> easier understanding, e.g.
>
> Here is what conceptually happens in "git rebase":
Either of those sounds reasonable to me
Thanks
Phillip
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [PATCH v6 0/5] doc: git-rebase: clarify DESCRIPTION section
2025-08-15 10:25 ` Phillip Wood
@ 2025-08-15 15:45 ` Junio C Hamano
2025-08-15 15:54 ` Phillip Wood
0 siblings, 1 reply; 103+ messages in thread
From: Junio C Hamano @ 2025-08-15 15:45 UTC (permalink / raw)
To: Phillip Wood
Cc: Julia Evans, phillip.wood, Julia Evans, git, D. Ben Knoble,
Patrick Steinhardt, Karthik Nayak
Phillip Wood <phillip.wood123@gmail.com> writes:
> Although the cherry-pick detection happens inside "git log" that
> command has a fast step (find the commits on both sides of the merge
> base) and a slow step (detect cherry-picks) so I think it depends
> where one draws the step boundaries. The cherry-pick detection is
> known to be slow when there are a lot of new upstream commits which
> was the motivation for adding --reapply-cherry-picks in 0fcb4f6b62
> (rebase --merge: optionally skip upstreamed commits, 2020-04-11)
Correct, in the description of "reapply-cherry-picks", it may need
to be discussed to guide the readers decide when to use the option.
But would it really help understanding of readers to give such level
of detail in "here is roughly how it works" description? I am not
sure about that.
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [PATCH v6 0/5] doc: git-rebase: clarify DESCRIPTION section
2025-08-15 15:45 ` Junio C Hamano
@ 2025-08-15 15:54 ` Phillip Wood
2025-08-15 15:56 ` Julia Evans
0 siblings, 1 reply; 103+ messages in thread
From: Phillip Wood @ 2025-08-15 15:54 UTC (permalink / raw)
To: Junio C Hamano
Cc: Julia Evans, phillip.wood, Julia Evans, git, D. Ben Knoble,
Patrick Steinhardt, Karthik Nayak
On 15/08/2025 16:45, Junio C Hamano wrote:
> Phillip Wood <phillip.wood123@gmail.com> writes:
>
>> Although the cherry-pick detection happens inside "git log" that
>> command has a fast step (find the commits on both sides of the merge
>> base) and a slow step (detect cherry-picks) so I think it depends
>> where one draws the step boundaries. The cherry-pick detection is
>> known to be slow when there are a lot of new upstream commits which
>> was the motivation for adding --reapply-cherry-picks in 0fcb4f6b62
>> (rebase --merge: optionally skip upstreamed commits, 2020-04-11)
>
> Correct, in the description of "reapply-cherry-picks", it may need
> to be discussed to guide the readers decide when to use the option.
>
> But would it really help understanding of readers to give such level
> of detail in "here is roughly how it works" description? I am not
> sure about that.
I'd certainly be happy to see these two steps in the description
simplified and combined as you've suggested elsewhere.
Thanks
Phillip
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [PATCH v6 0/5] doc: git-rebase: clarify DESCRIPTION section
2025-08-15 15:54 ` Phillip Wood
@ 2025-08-15 15:56 ` Julia Evans
0 siblings, 0 replies; 103+ messages in thread
From: Julia Evans @ 2025-08-15 15:56 UTC (permalink / raw)
To: phillip.wood, Junio C Hamano
Cc: Julia Evans, git, D. Ben Knoble, Patrick Steinhardt,
Karthik Nayak
>>> Although the cherry-pick detection happens inside "git log" that
>>> command has a fast step (find the commits on both sides of the merge
>>> base) and a slow step (detect cherry-picks) so I think it depends
>>> where one draws the step boundaries. The cherry-pick detection is
>>> known to be slow when there are a lot of new upstream commits which
>>> was the motivation for adding --reapply-cherry-picks in 0fcb4f6b62
>>> (rebase --merge: optionally skip upstreamed commits, 2020-04-11)
>>
>> Correct, in the description of "reapply-cherry-picks", it may need
>> to be discussed to guide the readers decide when to use the option.
>>
>> But would it really help understanding of readers to give such level
>> of detail in "here is roughly how it works" description? I am not
>> sure about that.
>
> I'd certainly be happy to see these two steps in the description
> simplified and combined as you've suggested elsewhere.
I'll combine them then: that seems like the simplest solution.
best,
- Julia
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v8 0/5] doc: git-rebase: clarify DESCRIPTION section
2025-08-12 13:49 ` [PATCH v7 " Julia Evans via GitGitGadget
` (4 preceding siblings ...)
2025-08-12 13:49 ` [PATCH v7 5/5] doc: git-rebase: update discussion of internals Julia Evans via GitGitGadget
@ 2025-08-15 16:52 ` Julia Evans via GitGitGadget
2025-08-15 16:52 ` [PATCH v8 1/5] doc: git-rebase: start with an example Julia Evans via GitGitGadget
` (6 more replies)
5 siblings, 7 replies; 103+ messages in thread
From: Julia Evans via GitGitGadget @ 2025-08-15 16:52 UTC (permalink / raw)
To: git
Cc: D. Ben Knoble, Phillip Wood, Patrick Steinhardt, Karthik Nayak,
Julia Evans
Combine point 1 and 2 in "a simplified description of what git rebase
<upstream> does:" into a shorter summary.
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 | 298 +++++++++++++++-------------------
1 file changed, 133 insertions(+), 165 deletions(-)
base-commit: 2c2ba49d55ff26c1082b8137b1ec5eeccb4337d1
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1949%2Fjvns%2Fclarify-rebase-v8
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1949/jvns/clarify-rebase-v8
Pull-Request: https://github.com/gitgitgadget/git/pull/1949
Range-diff vs v7:
1: e7a8fbbe53c = 1: e7a8fbbe53c doc: git-rebase: start with an example
2: ad63f69918d = 2: ad63f69918d doc: git rebase: dedup merge conflict discussion
3: 7ee6b0afe88 = 3: 7ee6b0afe88 doc: git rebase: clarify arguments syntax
4: 4686417b28e = 4: 4686417b28e doc: git-rebase: move --onto explanation down
5: 79f29ad1e68 ! 5: cb85642bb9d doc: git-rebase: update discussion of internals
@@ 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 simplified description of what `git rebase <upstream>` does:
+
-+1. Make a list of all new commits on your current branch since it branched
-+ off from `<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 contain the same changes (according to
-+ `git patch-id`) as a commit already in `<upstream>` and remove them from
-+ the list.
-+3. Check out `<upstream>` with the equivalent of
++1. Make a list of all commits on your current branch since it branched
++ off from `<upstream>` that do not have an equivalent commit in
++ `<upstream>`.
++2. Check out `<upstream>` with the equivalent of
+ `git checkout --detach <upstream>`.
-+4. Replay the commits, one by one, in order. This is similar to running
++3. 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
++4. Update your branch to point to the final commit with the equivalent
+ of `git checkout -B <branch>`.
[NOTE]
--
gitgitgadget
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v8 1/5] doc: git-rebase: start with an example
2025-08-15 16:52 ` [PATCH v8 0/5] doc: git-rebase: clarify DESCRIPTION section Julia Evans via GitGitGadget
@ 2025-08-15 16:52 ` Julia Evans via GitGitGadget
2025-08-15 16:52 ` [PATCH v8 2/5] doc: git rebase: dedup merge conflict discussion Julia Evans via GitGitGadget
` (5 subsequent siblings)
6 siblings, 0 replies; 103+ messages in thread
From: Julia Evans via GitGitGadget @ 2025-08-15 16:52 UTC (permalink / raw)
To: git
Cc: D. Ben Knoble, Phillip Wood, Patrick Steinhardt, Karthik Nayak,
Julia Evans, Julia Evans
From: Julia Evans <julia@jvns.ca>
- 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 <julia@jvns.ca>
---
Documentation/git-rebase.adoc | 52 +++++++++++++++++------------------
1 file changed, 26 insertions(+), 26 deletions(-)
diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc
index 956d3048f5a6..bb5a3ff7f828 100644
--- a/Documentation/git-rebase.adoc
+++ b/Documentation/git-rebase.adoc
@@ -16,6 +16,32 @@ SYNOPSIS
DESCRIPTION
-----------
+Transplant a series of commits onto a different starting point.
+You can also use `git rebase` to reorder or combine commits: see INTERACTIVE
+MODE below for how to do that.
+
+For example, imagine that you have been working on the `topic` branch in this
+history, and you want to "catch up" to the work done on the `master` branch.
+
+------------
+ A---B---C topic
+ /
+ D---E---F---G master
+------------
+
+You want to transplant the commits you made on `topic` since it diverged from
+`master` (i.e. A, B, and C), on top of the current `master`. You can do this
+by running `git rebase master` while the `topic` branch is checked out. If you
+want to rebase `topic` while on another branch, `git rebase master topic` is a
+shortcut for `git checkout topic && git rebase master`.
+
+------------
+ A'--B'--C' topic
+ /
+ D---E---F---G master
+------------
+
+
If `<branch>` is specified, `git rebase` will perform an automatic
`git switch <branch>` before doing anything else. Otherwise
it remains on the current branch.
@@ -58,32 +84,6 @@ that caused the merge failure with `git rebase --skip`. To check out the
original `<branch>` and remove the `.git/rebase-apply` working files, use
the command `git rebase --abort` instead.
-Assume the following history exists and the current branch is "topic":
-
-------------
- A---B---C topic
- /
- D---E---F---G master
-------------
-
-From this point, the result of either of the following commands:
-
-
- git rebase master
- git rebase master topic
-
-would be:
-
-------------
- A'--B'--C' topic
- /
- D---E---F---G master
-------------
-
-*NOTE:* The latter form is just a short-hand of `git checkout topic`
-followed by `git rebase master`. When rebase exits `topic` will
-remain the checked-out branch.
-
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
--
gitgitgadget
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v8 2/5] doc: git rebase: dedup merge conflict discussion
2025-08-15 16:52 ` [PATCH v8 0/5] doc: git-rebase: clarify DESCRIPTION section Julia Evans via GitGitGadget
2025-08-15 16:52 ` [PATCH v8 1/5] doc: git-rebase: start with an example Julia Evans via GitGitGadget
@ 2025-08-15 16:52 ` Julia Evans via GitGitGadget
2025-08-15 16:52 ` [PATCH v8 3/5] doc: git rebase: clarify arguments syntax Julia Evans via GitGitGadget
` (4 subsequent siblings)
6 siblings, 0 replies; 103+ messages in thread
From: Julia Evans via GitGitGadget @ 2025-08-15 16:52 UTC (permalink / raw)
To: git
Cc: D. Ben Knoble, Phillip Wood, Patrick Steinhardt, Karthik Nayak,
Julia Evans, Julia Evans
From: Julia Evans <julia@jvns.ca>
Previously there were two explanations, this combines them both into a
single explanation.
Signed-off-by: Julia Evans <julia@jvns.ca>
---
Documentation/git-rebase.adoc | 49 ++++++++++++++---------------------
1 file changed, 20 insertions(+), 29 deletions(-)
diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc
index bb5a3ff7f828..e82ceb9cbfce 100644
--- a/Documentation/git-rebase.adoc
+++ b/Documentation/git-rebase.adoc
@@ -42,6 +42,26 @@ shortcut for `git checkout topic && git rebase master`.
------------
+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
+one of these things:
+
+1. Resolve the conflict. You can use `git diff` to find the markers (<<<<<<)
+ and make edits to resolve the conflict. For each file you edit, you need to
+ tell Git that the conflict has been resolved. You can mark the conflict as
+ resolved with `git add <filename>`. After resolving all of the conflicts,
+ you can continue the rebasing process with
+
+ git rebase --continue
+
+2. Stop the `git rebase` and return your branch to its original state with
+
+ git rebase --abort
+
+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
it remains on the current branch.
@@ -77,13 +97,6 @@ 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).
-It is possible that a merge failure will prevent this process from being
-completely automatic. You will have to resolve any such merge failure
-and run `git rebase --continue`. Another option is to bypass the commit
-that caused the merge failure with `git rebase --skip`. To check out the
-original `<branch>` and remove the `.git/rebase-apply` working files, use
-the command `git rebase --abort` instead.
-
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
@@ -186,28 +199,6 @@ This is useful if F and G were flawed in some way, or should not be
part of topicA. Note that the argument to `--onto` and the `<upstream>`
parameter can be any valid commit-ish.
-In case of conflict, `git rebase` will stop at the first problematic commit
-and leave conflict markers in the tree. You can use `git diff` to locate
-the markers (<<<<<<) and make edits to resolve the conflict. For each
-file you edit, you need to tell Git that the conflict has been resolved,
-typically this would be done with
-
-
- git add <filename>
-
-
-After resolving the conflict manually and updating the index with the
-desired resolution, you can continue the rebasing process with
-
-
- git rebase --continue
-
-
-Alternatively, you can undo the 'git rebase' with
-
-
- git rebase --abort
-
MODE OPTIONS
------------
--
gitgitgadget
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v8 3/5] doc: git rebase: clarify arguments syntax
2025-08-15 16:52 ` [PATCH v8 0/5] doc: git-rebase: clarify DESCRIPTION section Julia Evans via GitGitGadget
2025-08-15 16:52 ` [PATCH v8 1/5] doc: git-rebase: start with an example Julia Evans via GitGitGadget
2025-08-15 16:52 ` [PATCH v8 2/5] doc: git rebase: dedup merge conflict discussion Julia Evans via GitGitGadget
@ 2025-08-15 16:52 ` Julia Evans via GitGitGadget
2025-08-15 16:52 ` [PATCH v8 4/5] doc: git-rebase: move --onto explanation down Julia Evans via GitGitGadget
` (3 subsequent siblings)
6 siblings, 0 replies; 103+ messages in thread
From: Julia Evans via GitGitGadget @ 2025-08-15 16:52 UTC (permalink / raw)
To: git
Cc: D. Ben Knoble, Phillip Wood, Patrick Steinhardt, Karthik Nayak,
Julia Evans, Julia Evans
From: Julia Evans <julia@jvns.ca>
Remove duplicate explanation of `git rebase <upstream> <branch>` which
is already explained above.
Signed-off-by: Julia Evans <julia@jvns.ca>
---
Documentation/git-rebase.adoc | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc
index e82ceb9cbfce..6d02648a9b3c 100644
--- a/Documentation/git-rebase.adoc
+++ b/Documentation/git-rebase.adoc
@@ -62,11 +62,7 @@ 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.
-
-If `<upstream>` is not specified, the upstream configured in
+If you don't specify an `<upstream>` to rebase onto, the upstream configured in
`branch.<name>.remote` and `branch.<name>.merge` options will be used (see
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
--
gitgitgadget
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v8 4/5] doc: git-rebase: move --onto explanation down
2025-08-15 16:52 ` [PATCH v8 0/5] doc: git-rebase: clarify DESCRIPTION section Julia Evans via GitGitGadget
` (2 preceding siblings ...)
2025-08-15 16:52 ` [PATCH v8 3/5] doc: git rebase: clarify arguments syntax Julia Evans via GitGitGadget
@ 2025-08-15 16:52 ` Julia Evans via GitGitGadget
2025-08-15 21:05 ` Junio C Hamano
2025-08-15 16:52 ` [PATCH v8 5/5] doc: git-rebase: update discussion of internals Julia Evans via GitGitGadget
` (2 subsequent siblings)
6 siblings, 1 reply; 103+ messages in thread
From: Julia Evans via GitGitGadget @ 2025-08-15 16:52 UTC (permalink / raw)
To: git
Cc: D. Ben Knoble, Phillip Wood, Patrick Steinhardt, Karthik Nayak,
Julia Evans, Julia Evans
From: Julia Evans <julia@jvns.ca>
There's a very clear explanation with examples of using --onto which is
currently buried in the very long DESCRIPTION section. This moves it to
its own section, so that we can reference the explanation from the
`--onto` option by name.
Signed-off-by: Julia Evans <julia@jvns.ca>
---
Documentation/git-rebase.adoc | 168 ++++++++++++++++++----------------
1 file changed, 87 insertions(+), 81 deletions(-)
diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc
index 6d02648a9b3c..d041d87f270b 100644
--- a/Documentation/git-rebase.adoc
+++ b/Documentation/git-rebase.adoc
@@ -114,87 +114,6 @@ will result in:
D---E---A'---F master
------------
-Here is how you would transplant a topic branch based on one
-branch to another, to pretend that you forked the topic branch
-from the latter branch, using `rebase --onto`.
-
-First let's assume your 'topic' is based on branch 'next'.
-For example, a feature developed in 'topic' depends on some
-functionality which is found in 'next'.
-
-------------
- o---o---o---o---o master
- \
- o---o---o---o---o next
- \
- o---o---o topic
-------------
-
-We want to make 'topic' forked from branch 'master'; for example,
-because the functionality on which 'topic' depends was merged into the
-more stable 'master' branch. We want our tree to look like this:
-
-------------
- o---o---o---o---o master
- | \
- | o'--o'--o' topic
- \
- o---o---o---o---o next
-------------
-
-We can get this using the following command:
-
- git rebase --onto master next topic
-
-
-Another example of --onto option is to rebase part of a
-branch. If we have the following situation:
-
-------------
- H---I---J topicB
- /
- E---F---G topicA
- /
- A---B---C---D master
-------------
-
-then the command
-
- git rebase --onto master topicA topicB
-
-would result in:
-
-------------
- H'--I'--J' topicB
- /
- | E---F---G topicA
- |/
- A---B---C---D master
-------------
-
-This is useful when topicB does not depend on topicA.
-
-A range of commits could also be removed with rebase. If we have
-the following situation:
-
-------------
- E---F---G---H---I---J topicA
-------------
-
-then the command
-
- git rebase --onto topicA~5 topicA~3 topicA
-
-would result in the removal of commits F and G:
-
-------------
- E---H'---I'---J' topicA
-------------
-
-This is useful if F and G were flawed in some way, or should not be
-part of topicA. Note that the argument to `--onto` and the `<upstream>`
-parameter can be any valid commit-ish.
-
MODE OPTIONS
------------
@@ -240,6 +159,8 @@ As a special case, you may use "A\...B" as a shortcut for the
merge base of A and B if there is exactly one merge base. You can
leave out at most one of A and B, in which case it defaults to HEAD.
+See TRANSPLANTING A TOPIC BRANCH WITH --ONTO below for examples.
+
--keep-base::
Set the starting point at which to create the new commits to the
merge base of `<upstream>` and `<branch>`. Running
@@ -1018,6 +939,91 @@ consistent (they compile, pass the testsuite, etc.) you should use
after each commit, test, and amend the commit if fixes are necessary.
+TRANSPLANTING A TOPIC BRANCH WITH --ONTO
+----------------------------------------
+
+Here is how you would transplant a topic branch based on one
+branch to another, to pretend that you forked the topic branch
+from the latter branch, using `rebase --onto`.
+
+First let's assume your 'topic' is based on branch 'next'.
+For example, a feature developed in 'topic' depends on some
+functionality which is found in 'next'.
+
+------------
+ o---o---o---o---o master
+ \
+ o---o---o---o---o next
+ \
+ o---o---o topic
+------------
+
+We want to make 'topic' forked from branch 'master'; for example,
+because the functionality on which 'topic' depends was merged into the
+more stable 'master' branch. We want our tree to look like this:
+
+------------
+ o---o---o---o---o master
+ | \
+ | o'--o'--o' topic
+ \
+ o---o---o---o---o next
+------------
+
+We can get this using the following command:
+
+ git rebase --onto master next topic
+
+
+Another example of --onto option is to rebase part of a
+branch. If we have the following situation:
+
+------------
+ H---I---J topicB
+ /
+ E---F---G topicA
+ /
+ A---B---C---D master
+------------
+
+then the command
+
+ git rebase --onto master topicA topicB
+
+would result in:
+
+------------
+ H'--I'--J' topicB
+ /
+ | E---F---G topicA
+ |/
+ A---B---C---D master
+------------
+
+This is useful when topicB does not depend on topicA.
+
+A range of commits could also be removed with rebase. If we have
+the following situation:
+
+------------
+ E---F---G---H---I---J topicA
+------------
+
+then the command
+
+ git rebase --onto topicA~5 topicA~3 topicA
+
+would result in the removal of commits F and G:
+
+------------
+ E---H'---I'---J' topicA
+------------
+
+This is useful if F and G were flawed in some way, or should not be
+part of topicA. Note that the argument to `--onto` and the `<upstream>`
+parameter can be any valid commit-ish.
+
+
RECOVERING FROM UPSTREAM REBASE
-------------------------------
--
gitgitgadget
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v8 5/5] doc: git-rebase: update discussion of internals
2025-08-15 16:52 ` [PATCH v8 0/5] doc: git-rebase: clarify DESCRIPTION section Julia Evans via GitGitGadget
` (3 preceding siblings ...)
2025-08-15 16:52 ` [PATCH v8 4/5] doc: git-rebase: move --onto explanation down Julia Evans via GitGitGadget
@ 2025-08-15 16:52 ` Julia Evans via GitGitGadget
2025-08-18 13:43 ` [PATCH v8 0/5] doc: git-rebase: clarify DESCRIPTION section Phillip Wood
2025-08-23 0:42 ` [PATCH v9 " Julia Evans via GitGitGadget
6 siblings, 0 replies; 103+ messages in thread
From: Julia Evans via GitGitGadget @ 2025-08-15 16:52 UTC (permalink / raw)
To: git
Cc: D. Ben Knoble, Phillip Wood, Patrick Steinhardt, Karthik Nayak,
Julia Evans, Julia Evans
From: Julia Evans <julia@jvns.ca>
- 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 <julia@jvns.ca>
---
Documentation/git-rebase.adoc | 61 +++++++++++------------------------
1 file changed, 18 insertions(+), 43 deletions(-)
diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc
index d041d87f270b..2a44f8a0ceda 100644
--- a/Documentation/git-rebase.adoc
+++ b/Documentation/git-rebase.adoc
@@ -68,51 +68,26 @@ 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 simplified description of what `git rebase <upstream>` does:
+
+1. Make a list of all commits on your current branch since it branched
+ off from `<upstream>` that do not have an equivalent commit in
+ `<upstream>`.
+2. Check out `<upstream>` with the equivalent of
+ `git checkout --detach <upstream>`.
+3. 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.
+4. Update your branch to point to the final commit with the equivalent
+ of `git checkout -B <branch>`.
[NOTE]
-`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
-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
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [PATCH v8 4/5] doc: git-rebase: move --onto explanation down
2025-08-15 16:52 ` [PATCH v8 4/5] doc: git-rebase: move --onto explanation down Julia Evans via GitGitGadget
@ 2025-08-15 21:05 ` Junio C Hamano
2025-08-18 13:42 ` Phillip Wood
0 siblings, 1 reply; 103+ messages in thread
From: Junio C Hamano @ 2025-08-15 21:05 UTC (permalink / raw)
To: Julia Evans via GitGitGadget
Cc: git, D. Ben Knoble, Phillip Wood, Patrick Steinhardt,
Karthik Nayak, Julia Evans
"Julia Evans via GitGitGadget" <gitgitgadget@gmail.com> writes:
> From: Julia Evans <julia@jvns.ca>
>
> There's a very clear explanation with examples of using --onto which is
> currently buried in the very long DESCRIPTION section. This moves it to
> its own section, so that we can reference the explanation from the
> `--onto` option by name.
>
> Signed-off-by: Julia Evans <julia@jvns.ca>
> ---
> Documentation/git-rebase.adoc | 168 ++++++++++++++++++----------------
> 1 file changed, 87 insertions(+), 81 deletions(-)
Deduplicating is very good idea.
I gave a read-through over the result of the entire series,
including the parts that did not change, to see if the new
organization is easy to read and coherently tells the story
we want to tell, and what I saw was mostly very pleasing, except for
one thing.
The new location of this section on "--onto" felt a bit off.
Perhaps it is just me, but in case others have different opinions,
I'd raise it here.
The overall structure of the document with these patches becomes:
- description that gives a simplified "what is achieved".
- "mode options" that control what to do during a rebase once the
user is given control back
- "options" that is given upfront
- notes about incompatible options
- discussions about apply/merge backends and how they differ
- overall notes on advanced topics
- interactive mode basics
- splitting commits
- use of --onto
- dealing with rebased upstream
- rebasing merges
Is it so exotic to use "--onto" to replay a topic to somewhere other
than the direct descendant of the fork point, to make it a part of
advanced topics? I somehow doubt it. It is a very basic and common
thing to do while correcting a mistake of choosing a wrong base
commit. You often realize that your topic is basically good but has
to work well with a different base commit.
I wonder if it gives the same understanding with a much shorter text
and illustration if we get rid of that section, and mention --onto
as a part of the early examples in the description section. That
way, we can reuse the "set up" of user's brain and context we
already made with the existing example.
For example, after showing the rebase of A..C on top of G, we can
mention that the range can be transplanted on top of commit other
than G, say D. Perhaps we can say that 'D' is still part of the
maintenance track, and the topic being a fix for a bug that happened
before D, it should not have forked from E that is a feature
enhancement commit that is not eligible for being on the maintenance
track. That would be a good reason why the user may want to move
A..C on top of D instead of E.
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [PATCH v8 4/5] doc: git-rebase: move --onto explanation down
2025-08-15 21:05 ` Junio C Hamano
@ 2025-08-18 13:42 ` Phillip Wood
2025-08-18 17:06 ` Junio C Hamano
0 siblings, 1 reply; 103+ messages in thread
From: Phillip Wood @ 2025-08-18 13:42 UTC (permalink / raw)
To: Junio C Hamano, Julia Evans via GitGitGadget
Cc: git, D. Ben Knoble, Patrick Steinhardt, Karthik Nayak,
Julia Evans
On 15/08/2025 22:05, Junio C Hamano wrote:
> "Julia Evans via GitGitGadget" <gitgitgadget@gmail.com> writes:
>
>> From: Julia Evans <julia@jvns.ca>
>>
>> There's a very clear explanation with examples of using --onto which is
>> currently buried in the very long DESCRIPTION section. This moves it to
>> its own section, so that we can reference the explanation from the
>> `--onto` option by name.
>>
>> Signed-off-by: Julia Evans <julia@jvns.ca>
>> ---
>> Documentation/git-rebase.adoc | 168 ++++++++++++++++++----------------
>> 1 file changed, 87 insertions(+), 81 deletions(-)
>
> Deduplicating is very good idea.
>
> I gave a read-through over the result of the entire series,
> including the parts that did not change, to see if the new
> organization is easy to read and coherently tells the story
> we want to tell, and what I saw was mostly very pleasing, except for
> one thing.
Yes the reworked DESCRIPTION section is very good.
> The new location of this section on "--onto" felt a bit off.
> Perhaps it is just me, but in case others have different opinions,
> I'd raise it here.
I agree that "--onto" is a fairly commonly used option and so it might
be nice to mention it in the general description. The existing examples
are all good reasons why one might want to use "--onto" so I'm slightly
wary of replacing them with a single example in the description. Maybe
we could just add a sentence to the description explaining that it is
possible to transplant the commits to a different base using "--onto".
That would also keep the description fairly concise.
I've just built the html version and it would be nice if we could add a
link to the TRANSPLANTING A TOPIC BRANCH WITH --ONTO when we mention it
in the description of "--onto". The same goes for the mention of
INTERACTIVE MODE in the DESCRIPTION section.
Thanks
Phillip
> The overall structure of the document with these patches becomes:
>
> - description that gives a simplified "what is achieved".
>
> - "mode options" that control what to do during a rebase once the
> user is given control back
>
> - "options" that is given upfront
>
> - notes about incompatible options
>
> - discussions about apply/merge backends and how they differ
>
> - overall notes on advanced topics
>
> - interactive mode basics
>
> - splitting commits
>
> - use of --onto
>
> - dealing with rebased upstream
>
> - rebasing merges
>
> Is it so exotic to use "--onto" to replay a topic to somewhere other
> than the direct descendant of the fork point, to make it a part of
> advanced topics? I somehow doubt it. It is a very basic and common
> thing to do while correcting a mistake of choosing a wrong base
> commit. You often realize that your topic is basically good but has
> to work well with a different base commit.
>
> I wonder if it gives the same understanding with a much shorter text
> and illustration if we get rid of that section, and mention --onto
> as a part of the early examples in the description section. That
> way, we can reuse the "set up" of user's brain and context we
> already made with the existing example.
>
> For example, after showing the rebase of A..C on top of G, we can
> mention that the range can be transplanted on top of commit other
> than G, say D. Perhaps we can say that 'D' is still part of the
> maintenance track, and the topic being a fix for a bug that happened
> before D, it should not have forked from E that is a feature
> enhancement commit that is not eligible for being on the maintenance
> track. That would be a good reason why the user may want to move
> A..C on top of D instead of E.
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [PATCH v8 0/5] doc: git-rebase: clarify DESCRIPTION section
2025-08-15 16:52 ` [PATCH v8 0/5] doc: git-rebase: clarify DESCRIPTION section Julia Evans via GitGitGadget
` (4 preceding siblings ...)
2025-08-15 16:52 ` [PATCH v8 5/5] doc: git-rebase: update discussion of internals Julia Evans via GitGitGadget
@ 2025-08-18 13:43 ` Phillip Wood
2025-08-23 0:42 ` [PATCH v9 " Julia Evans via GitGitGadget
6 siblings, 0 replies; 103+ messages in thread
From: Phillip Wood @ 2025-08-18 13:43 UTC (permalink / raw)
To: Julia Evans via GitGitGadget, git
Cc: D. Ben Knoble, Patrick Steinhardt, Karthik Nayak, Julia Evans
On 15/08/2025 17:52, Julia Evans via GitGitGadget wrote:
> Combine point 1 and 2 in "a simplified description of what git rebase
> <upstream> does:" into a shorter summary.
This looks great, I've left a couple of comments in reply to Junio but
I'd be happy enough to see this merged as-is.
I'm going to be off the list for a week from tomorrow so I wont be
commenting any more this week.
Thanks for working on this
Phillip
> 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 | 298 +++++++++++++++-------------------
> 1 file changed, 133 insertions(+), 165 deletions(-)
>
>
> base-commit: 2c2ba49d55ff26c1082b8137b1ec5eeccb4337d1
> Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1949%2Fjvns%2Fclarify-rebase-v8
> Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1949/jvns/clarify-rebase-v8
> Pull-Request: https://github.com/gitgitgadget/git/pull/1949
>
> Range-diff vs v7:
>
> 1: e7a8fbbe53c = 1: e7a8fbbe53c doc: git-rebase: start with an example
> 2: ad63f69918d = 2: ad63f69918d doc: git rebase: dedup merge conflict discussion
> 3: 7ee6b0afe88 = 3: 7ee6b0afe88 doc: git rebase: clarify arguments syntax
> 4: 4686417b28e = 4: 4686417b28e doc: git-rebase: move --onto explanation down
> 5: 79f29ad1e68 ! 5: cb85642bb9d doc: git-rebase: update discussion of internals
> @@ 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 simplified description of what `git rebase <upstream>` does:
> +
> -+1. Make a list of all new commits on your current branch since it branched
> -+ off from `<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 contain the same changes (according to
> -+ `git patch-id`) as a commit already in `<upstream>` and remove them from
> -+ the list.
> -+3. Check out `<upstream>` with the equivalent of
> ++1. Make a list of all commits on your current branch since it branched
> ++ off from `<upstream>` that do not have an equivalent commit in
> ++ `<upstream>`.
> ++2. Check out `<upstream>` with the equivalent of
> + `git checkout --detach <upstream>`.
> -+4. Replay the commits, one by one, in order. This is similar to running
> ++3. 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
> ++4. Update your branch to point to the final commit with the equivalent
> + of `git checkout -B <branch>`.
>
> [NOTE]
>
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [PATCH v8 4/5] doc: git-rebase: move --onto explanation down
2025-08-18 13:42 ` Phillip Wood
@ 2025-08-18 17:06 ` Junio C Hamano
2025-08-19 15:03 ` Julia Evans
0 siblings, 1 reply; 103+ messages in thread
From: Junio C Hamano @ 2025-08-18 17:06 UTC (permalink / raw)
To: Phillip Wood
Cc: Julia Evans via GitGitGadget, git, D. Ben Knoble,
Patrick Steinhardt, Karthik Nayak, Julia Evans
Phillip Wood <phillip.wood123@gmail.com> writes:
>> The new location of this section on "--onto" felt a bit off.
>> Perhaps it is just me, but in case others have different opinions,
>> I'd raise it here.
>
> I agree that "--onto" is a fairly commonly used option and so it might
> be nice to mention it in the general description.
That would independently be a good idea.
> The existing
> examples are all good reasons why one might want to use "--onto" so
> I'm slightly wary of replacing them with a single example in the
> description.
Then perhaps we should find a better place to put it. The section
on advanced topics notes are mostly about operations using sequencer
machinery, except for the onto section. Perhaps immediately after
the apply/merge comparison?
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [PATCH v8 4/5] doc: git-rebase: move --onto explanation down
2025-08-18 17:06 ` Junio C Hamano
@ 2025-08-19 15:03 ` Julia Evans
2025-08-19 19:45 ` Junio C Hamano
0 siblings, 1 reply; 103+ messages in thread
From: Julia Evans @ 2025-08-19 15:03 UTC (permalink / raw)
To: Junio C Hamano, Phillip Wood
Cc: Julia Evans, git, D. Ben Knoble, Patrick Steinhardt,
Karthik Nayak
>> The existing
>> examples are all good reasons why one might want to use "--onto" so
>> I'm slightly wary of replacing them with a single example in the
>> description.
>
> Then perhaps we should find a better place to put it. The section
> on advanced topics notes are mostly about operations using sequencer
> machinery, except for the onto section. Perhaps immediately after
> the apply/merge comparison?
I'm happy to move it anywhere: I couldn't figure out how the sections
were meant to be organized (I didn't know that "operations about
sequencer machinery" was meant to be a theme) so I chose where
to put it pretty arbitrarily.
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [PATCH v8 4/5] doc: git-rebase: move --onto explanation down
2025-08-19 15:03 ` Julia Evans
@ 2025-08-19 19:45 ` Junio C Hamano
0 siblings, 0 replies; 103+ messages in thread
From: Junio C Hamano @ 2025-08-19 19:45 UTC (permalink / raw)
To: Julia Evans
Cc: Phillip Wood, Julia Evans, git, D. Ben Knoble, Patrick Steinhardt,
Karthik Nayak
"Julia Evans" <julia@jvns.ca> writes:
>>> The existing
>>> examples are all good reasons why one might want to use "--onto" so
>>> I'm slightly wary of replacing them with a single example in the
>>> description.
>>
>> Then perhaps we should find a better place to put it. The section
>> on advanced topics notes are mostly about operations using sequencer
>> machinery, except for the onto section. Perhaps immediately after
>> the apply/merge comparison?
>
> I'm happy to move it anywhere: I couldn't figure out how the sections
> were meant to be organized (I didn't know that "operations about
> sequencer machinery" was meant to be a theme) so I chose where
> to put it pretty arbitrarily.
I do not think it was meant to be a theme, but the topics there
ended up being around it as they were placed there organically.
If we were moving it, how about somewhere fairly early, like before
we start talking about mode options, where we teach the very basic
concept "rebase is to transplant a range history on top of a commit
that is different from where that history currently builds on"? The
primary difference with and without "--onto" is if you explicitly
specify where to transplant your history, independent from how you
specify the range of history to be transplanted, or a single
<upstream> implicitly specifies both.
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v9 0/5] doc: git-rebase: clarify DESCRIPTION section
2025-08-15 16:52 ` [PATCH v8 0/5] doc: git-rebase: clarify DESCRIPTION section Julia Evans via GitGitGadget
` (5 preceding siblings ...)
2025-08-18 13:43 ` [PATCH v8 0/5] doc: git-rebase: clarify DESCRIPTION section Phillip Wood
@ 2025-08-23 0:42 ` Julia Evans via GitGitGadget
2025-08-23 0:42 ` [PATCH v9 1/5] doc: git-rebase: start with an example Julia Evans via GitGitGadget
` (4 more replies)
6 siblings, 5 replies; 103+ messages in thread
From: Julia Evans via GitGitGadget @ 2025-08-23 0:42 UTC (permalink / raw)
To: git
Cc: D. Ben Knoble, Phillip Wood, Patrick Steinhardt, Karthik Nayak,
Julia Evans
Move the "TRANSPLANTING A TOPIC BRANCH WITH --ONTO" back up: now it's in the
exact same place it was before, just now with a section heading.
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 | 149 +++++++++++++---------------------
1 file changed, 58 insertions(+), 91 deletions(-)
base-commit: 64cbe5e2e8a7b0f92c780b210e602496bd5cad0f
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1949%2Fjvns%2Fclarify-rebase-v9
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1949/jvns/clarify-rebase-v9
Pull-Request: https://github.com/gitgitgadget/git/pull/1949
Range-diff vs v8:
1: e7a8fbbe53c = 1: ea1438e094e doc: git-rebase: start with an example
2: ad63f69918d = 2: 339b7a1bc5b doc: git rebase: dedup merge conflict discussion
3: 7ee6b0afe88 = 3: f42c2c794a9 doc: git rebase: clarify arguments syntax
4: 4686417b28e ! 4: 9c2a54ab9fa doc: git-rebase: move --onto explanation down
@@ Documentation/git-rebase.adoc: will result in:
D---E---A'---F master
------------
--Here is how you would transplant a topic branch based on one
--branch to another, to pretend that you forked the topic branch
--from the latter branch, using `rebase --onto`.
--
--First let's assume your 'topic' is based on branch 'next'.
--For example, a feature developed in 'topic' depends on some
--functionality which is found in 'next'.
--
--------------
-- o---o---o---o---o master
-- \
-- o---o---o---o---o next
-- \
-- o---o---o topic
--------------
--
--We want to make 'topic' forked from branch 'master'; for example,
--because the functionality on which 'topic' depends was merged into the
--more stable 'master' branch. We want our tree to look like this:
--
--------------
-- o---o---o---o---o master
-- | \
-- | o'--o'--o' topic
-- \
-- o---o---o---o---o next
--------------
--
--We can get this using the following command:
--
-- git rebase --onto master next topic
--
--
--Another example of --onto option is to rebase part of a
--branch. If we have the following situation:
--
--------------
-- H---I---J topicB
-- /
-- E---F---G topicA
-- /
-- A---B---C---D master
--------------
--
--then the command
--
-- git rebase --onto master topicA topicB
--
--would result in:
--
--------------
-- H'--I'--J' topicB
-- /
-- | E---F---G topicA
-- |/
-- A---B---C---D master
--------------
--
--This is useful when topicB does not depend on topicA.
--
--A range of commits could also be removed with rebase. If we have
--the following situation:
--
--------------
-- E---F---G---H---I---J topicA
--------------
--
--then the command
--
-- git rebase --onto topicA~5 topicA~3 topicA
--
--would result in the removal of commits F and G:
--
--------------
-- E---H'---I'---J' topicA
--------------
--
--This is useful if F and G were flawed in some way, or should not be
--part of topicA. Note that the argument to `--onto` and the `<upstream>`
--parameter can be any valid commit-ish.
--
- MODE OPTIONS
- ------------
-
++TRANSPLANTING A TOPIC BRANCH WITH --ONTO
++----------------------------------------
++
+ Here is how you would transplant a topic branch based on one
+ branch to another, to pretend that you forked the topic branch
+ from the latter branch, using `rebase --onto`.
@@ Documentation/git-rebase.adoc: As a special case, you may use "A\...B" as a shortcut for the
merge base of A and B if there is exactly one merge base. You can
leave out at most one of A and B, in which case it defaults to HEAD.
-+See TRANSPLANTING A TOPIC BRANCH WITH --ONTO below for examples.
++See TRANSPLANTING A TOPIC BRANCH WITH --ONTO above for examples.
+
--keep-base::
Set the starting point at which to create the new commits to the
merge base of `<upstream>` and `<branch>`. Running
-@@ Documentation/git-rebase.adoc: consistent (they compile, pass the testsuite, etc.) you should use
- after each commit, test, and amend the commit if fixes are necessary.
-
-
-+TRANSPLANTING A TOPIC BRANCH WITH --ONTO
-+----------------------------------------
-+
-+Here is how you would transplant a topic branch based on one
-+branch to another, to pretend that you forked the topic branch
-+from the latter branch, using `rebase --onto`.
-+
-+First let's assume your 'topic' is based on branch 'next'.
-+For example, a feature developed in 'topic' depends on some
-+functionality which is found in 'next'.
-+
-+------------
-+ o---o---o---o---o master
-+ \
-+ o---o---o---o---o next
-+ \
-+ o---o---o topic
-+------------
-+
-+We want to make 'topic' forked from branch 'master'; for example,
-+because the functionality on which 'topic' depends was merged into the
-+more stable 'master' branch. We want our tree to look like this:
-+
-+------------
-+ o---o---o---o---o master
-+ | \
-+ | o'--o'--o' topic
-+ \
-+ o---o---o---o---o next
-+------------
-+
-+We can get this using the following command:
-+
-+ git rebase --onto master next topic
-+
-+
-+Another example of --onto option is to rebase part of a
-+branch. If we have the following situation:
-+
-+------------
-+ H---I---J topicB
-+ /
-+ E---F---G topicA
-+ /
-+ A---B---C---D master
-+------------
-+
-+then the command
-+
-+ git rebase --onto master topicA topicB
-+
-+would result in:
-+
-+------------
-+ H'--I'--J' topicB
-+ /
-+ | E---F---G topicA
-+ |/
-+ A---B---C---D master
-+------------
-+
-+This is useful when topicB does not depend on topicA.
-+
-+A range of commits could also be removed with rebase. If we have
-+the following situation:
-+
-+------------
-+ E---F---G---H---I---J topicA
-+------------
-+
-+then the command
-+
-+ git rebase --onto topicA~5 topicA~3 topicA
-+
-+would result in the removal of commits F and G:
-+
-+------------
-+ E---H'---I'---J' topicA
-+------------
-+
-+This is useful if F and G were flawed in some way, or should not be
-+part of topicA. Note that the argument to `--onto` and the `<upstream>`
-+parameter can be any valid commit-ish.
-+
-+
- RECOVERING FROM UPSTREAM REBASE
- -------------------------------
-
5: cb85642bb9d ! 5: 5a1dd8df29b doc: git-rebase: update discussion of internals
@@ Documentation/git-rebase.adoc: linkgit:git-config[1] for details) and the `--for
+tip, however, is accessible using the reflog of the current branch (i.e. `@{1}`,
+see linkgit:gitrevisions[7].
- MODE OPTIONS
- ------------
+ TRANSPLANTING A TOPIC BRANCH WITH --ONTO
+ ----------------------------------------
--
gitgitgadget
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v9 1/5] doc: git-rebase: start with an example
2025-08-23 0:42 ` [PATCH v9 " Julia Evans via GitGitGadget
@ 2025-08-23 0:42 ` Julia Evans via GitGitGadget
2025-08-23 0:42 ` [PATCH v9 2/5] doc: git rebase: dedup merge conflict discussion Julia Evans via GitGitGadget
` (3 subsequent siblings)
4 siblings, 0 replies; 103+ messages in thread
From: Julia Evans via GitGitGadget @ 2025-08-23 0:42 UTC (permalink / raw)
To: git
Cc: D. Ben Knoble, Phillip Wood, Patrick Steinhardt, Karthik Nayak,
Julia Evans, Julia Evans
From: Julia Evans <julia@jvns.ca>
- 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 <julia@jvns.ca>
---
Documentation/git-rebase.adoc | 52 +++++++++++++++++------------------
1 file changed, 26 insertions(+), 26 deletions(-)
diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc
index 956d3048f5a6..bb5a3ff7f828 100644
--- a/Documentation/git-rebase.adoc
+++ b/Documentation/git-rebase.adoc
@@ -16,6 +16,32 @@ SYNOPSIS
DESCRIPTION
-----------
+Transplant a series of commits onto a different starting point.
+You can also use `git rebase` to reorder or combine commits: see INTERACTIVE
+MODE below for how to do that.
+
+For example, imagine that you have been working on the `topic` branch in this
+history, and you want to "catch up" to the work done on the `master` branch.
+
+------------
+ A---B---C topic
+ /
+ D---E---F---G master
+------------
+
+You want to transplant the commits you made on `topic` since it diverged from
+`master` (i.e. A, B, and C), on top of the current `master`. You can do this
+by running `git rebase master` while the `topic` branch is checked out. If you
+want to rebase `topic` while on another branch, `git rebase master topic` is a
+shortcut for `git checkout topic && git rebase master`.
+
+------------
+ A'--B'--C' topic
+ /
+ D---E---F---G master
+------------
+
+
If `<branch>` is specified, `git rebase` will perform an automatic
`git switch <branch>` before doing anything else. Otherwise
it remains on the current branch.
@@ -58,32 +84,6 @@ that caused the merge failure with `git rebase --skip`. To check out the
original `<branch>` and remove the `.git/rebase-apply` working files, use
the command `git rebase --abort` instead.
-Assume the following history exists and the current branch is "topic":
-
-------------
- A---B---C topic
- /
- D---E---F---G master
-------------
-
-From this point, the result of either of the following commands:
-
-
- git rebase master
- git rebase master topic
-
-would be:
-
-------------
- A'--B'--C' topic
- /
- D---E---F---G master
-------------
-
-*NOTE:* The latter form is just a short-hand of `git checkout topic`
-followed by `git rebase master`. When rebase exits `topic` will
-remain the checked-out branch.
-
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
--
gitgitgadget
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v9 2/5] doc: git rebase: dedup merge conflict discussion
2025-08-23 0:42 ` [PATCH v9 " Julia Evans via GitGitGadget
2025-08-23 0:42 ` [PATCH v9 1/5] doc: git-rebase: start with an example Julia Evans via GitGitGadget
@ 2025-08-23 0:42 ` Julia Evans via GitGitGadget
2025-08-23 0:43 ` [PATCH v9 3/5] doc: git rebase: clarify arguments syntax Julia Evans via GitGitGadget
` (2 subsequent siblings)
4 siblings, 0 replies; 103+ messages in thread
From: Julia Evans via GitGitGadget @ 2025-08-23 0:42 UTC (permalink / raw)
To: git
Cc: D. Ben Knoble, Phillip Wood, Patrick Steinhardt, Karthik Nayak,
Julia Evans, Julia Evans
From: Julia Evans <julia@jvns.ca>
Previously there were two explanations, this combines them both into a
single explanation.
Signed-off-by: Julia Evans <julia@jvns.ca>
---
Documentation/git-rebase.adoc | 49 ++++++++++++++---------------------
1 file changed, 20 insertions(+), 29 deletions(-)
diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc
index bb5a3ff7f828..e82ceb9cbfce 100644
--- a/Documentation/git-rebase.adoc
+++ b/Documentation/git-rebase.adoc
@@ -42,6 +42,26 @@ shortcut for `git checkout topic && git rebase master`.
------------
+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
+one of these things:
+
+1. Resolve the conflict. You can use `git diff` to find the markers (<<<<<<)
+ and make edits to resolve the conflict. For each file you edit, you need to
+ tell Git that the conflict has been resolved. You can mark the conflict as
+ resolved with `git add <filename>`. After resolving all of the conflicts,
+ you can continue the rebasing process with
+
+ git rebase --continue
+
+2. Stop the `git rebase` and return your branch to its original state with
+
+ git rebase --abort
+
+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
it remains on the current branch.
@@ -77,13 +97,6 @@ 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).
-It is possible that a merge failure will prevent this process from being
-completely automatic. You will have to resolve any such merge failure
-and run `git rebase --continue`. Another option is to bypass the commit
-that caused the merge failure with `git rebase --skip`. To check out the
-original `<branch>` and remove the `.git/rebase-apply` working files, use
-the command `git rebase --abort` instead.
-
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
@@ -186,28 +199,6 @@ This is useful if F and G were flawed in some way, or should not be
part of topicA. Note that the argument to `--onto` and the `<upstream>`
parameter can be any valid commit-ish.
-In case of conflict, `git rebase` will stop at the first problematic commit
-and leave conflict markers in the tree. You can use `git diff` to locate
-the markers (<<<<<<) and make edits to resolve the conflict. For each
-file you edit, you need to tell Git that the conflict has been resolved,
-typically this would be done with
-
-
- git add <filename>
-
-
-After resolving the conflict manually and updating the index with the
-desired resolution, you can continue the rebasing process with
-
-
- git rebase --continue
-
-
-Alternatively, you can undo the 'git rebase' with
-
-
- git rebase --abort
-
MODE OPTIONS
------------
--
gitgitgadget
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v9 3/5] doc: git rebase: clarify arguments syntax
2025-08-23 0:42 ` [PATCH v9 " Julia Evans via GitGitGadget
2025-08-23 0:42 ` [PATCH v9 1/5] doc: git-rebase: start with an example Julia Evans via GitGitGadget
2025-08-23 0:42 ` [PATCH v9 2/5] doc: git rebase: dedup merge conflict discussion Julia Evans via GitGitGadget
@ 2025-08-23 0:43 ` Julia Evans via GitGitGadget
2025-08-23 0:43 ` [PATCH v9 4/5] doc: git-rebase: move --onto explanation down Julia Evans via GitGitGadget
2025-08-23 0:43 ` [PATCH v9 5/5] doc: git-rebase: update discussion of internals Julia Evans via GitGitGadget
4 siblings, 0 replies; 103+ messages in thread
From: Julia Evans via GitGitGadget @ 2025-08-23 0:43 UTC (permalink / raw)
To: git
Cc: D. Ben Knoble, Phillip Wood, Patrick Steinhardt, Karthik Nayak,
Julia Evans, Julia Evans
From: Julia Evans <julia@jvns.ca>
Remove duplicate explanation of `git rebase <upstream> <branch>` which
is already explained above.
Signed-off-by: Julia Evans <julia@jvns.ca>
---
Documentation/git-rebase.adoc | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc
index e82ceb9cbfce..6d02648a9b3c 100644
--- a/Documentation/git-rebase.adoc
+++ b/Documentation/git-rebase.adoc
@@ -62,11 +62,7 @@ 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.
-
-If `<upstream>` is not specified, the upstream configured in
+If you don't specify an `<upstream>` to rebase onto, the upstream configured in
`branch.<name>.remote` and `branch.<name>.merge` options will be used (see
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
--
gitgitgadget
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v9 4/5] doc: git-rebase: move --onto explanation down
2025-08-23 0:42 ` [PATCH v9 " Julia Evans via GitGitGadget
` (2 preceding siblings ...)
2025-08-23 0:43 ` [PATCH v9 3/5] doc: git rebase: clarify arguments syntax Julia Evans via GitGitGadget
@ 2025-08-23 0:43 ` Julia Evans via GitGitGadget
2025-08-23 0:43 ` [PATCH v9 5/5] doc: git-rebase: update discussion of internals Julia Evans via GitGitGadget
4 siblings, 0 replies; 103+ messages in thread
From: Julia Evans via GitGitGadget @ 2025-08-23 0:43 UTC (permalink / raw)
To: git
Cc: D. Ben Knoble, Phillip Wood, Patrick Steinhardt, Karthik Nayak,
Julia Evans, Julia Evans
From: Julia Evans <julia@jvns.ca>
There's a very clear explanation with examples of using --onto which is
currently buried in the very long DESCRIPTION section. This moves it to
its own section, so that we can reference the explanation from the
`--onto` option by name.
Signed-off-by: Julia Evans <julia@jvns.ca>
---
Documentation/git-rebase.adoc | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc
index 6d02648a9b3c..b3354e0e4f82 100644
--- a/Documentation/git-rebase.adoc
+++ b/Documentation/git-rebase.adoc
@@ -114,6 +114,9 @@ will result in:
D---E---A'---F master
------------
+TRANSPLANTING A TOPIC BRANCH WITH --ONTO
+----------------------------------------
+
Here is how you would transplant a topic branch based on one
branch to another, to pretend that you forked the topic branch
from the latter branch, using `rebase --onto`.
@@ -240,6 +243,8 @@ As a special case, you may use "A\...B" as a shortcut for the
merge base of A and B if there is exactly one merge base. You can
leave out at most one of A and B, in which case it defaults to HEAD.
+See TRANSPLANTING A TOPIC BRANCH WITH --ONTO above for examples.
+
--keep-base::
Set the starting point at which to create the new commits to the
merge base of `<upstream>` and `<branch>`. Running
--
gitgitgadget
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v9 5/5] doc: git-rebase: update discussion of internals
2025-08-23 0:42 ` [PATCH v9 " Julia Evans via GitGitGadget
` (3 preceding siblings ...)
2025-08-23 0:43 ` [PATCH v9 4/5] doc: git-rebase: move --onto explanation down Julia Evans via GitGitGadget
@ 2025-08-23 0:43 ` Julia Evans via GitGitGadget
4 siblings, 0 replies; 103+ messages in thread
From: Julia Evans via GitGitGadget @ 2025-08-23 0:43 UTC (permalink / raw)
To: git
Cc: D. Ben Knoble, Phillip Wood, Patrick Steinhardt, Karthik Nayak,
Julia Evans, Julia Evans
From: Julia Evans <julia@jvns.ca>
- 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 <julia@jvns.ca>
---
Documentation/git-rebase.adoc | 61 +++++++++++------------------------
1 file changed, 18 insertions(+), 43 deletions(-)
diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc
index b3354e0e4f82..d2f760af6866 100644
--- a/Documentation/git-rebase.adoc
+++ b/Documentation/git-rebase.adoc
@@ -68,51 +68,26 @@ 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 simplified description of what `git rebase <upstream>` does:
+
+1. Make a list of all commits on your current branch since it branched
+ off from `<upstream>` that do not have an equivalent commit in
+ `<upstream>`.
+2. Check out `<upstream>` with the equivalent of
+ `git checkout --detach <upstream>`.
+3. 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.
+4. Update your branch to point to the final commit with the equivalent
+ of `git checkout -B <branch>`.
[NOTE]
-`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
-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].
TRANSPLANTING A TOPIC BRANCH WITH --ONTO
----------------------------------------
--
gitgitgadget
^ permalink raw reply related [flat|nested] 103+ messages in thread
end of thread, other threads:[~2025-08-23 0:43 UTC | newest]
Thread overview: 103+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-08-08 15:24 [PATCH 0/5] doc: git-rebase: clarify DESCRIPTION section Julia Evans via GitGitGadget
2025-08-08 15:24 ` [PATCH 1/5] doc: git-rebase: start with an example Julia Evans via GitGitGadget
2025-08-08 16:30 ` Junio C Hamano
2025-08-08 17:13 ` Julia Evans
2025-08-08 18:11 ` Junio C Hamano
2025-08-08 15:24 ` [PATCH 2/5] doc: git rebase: dedup merge conflict discussion Julia Evans via GitGitGadget
2025-08-08 17:48 ` Junio C Hamano
2025-08-08 15:24 ` [PATCH 3/5] doc: git rebase: clarify arguments syntax Julia Evans via GitGitGadget
2025-08-08 15:24 ` [PATCH 4/5] doc: git-rebase: move --onto explanation down Julia Evans via GitGitGadget
2025-08-08 15:24 ` [PATCH 5/5] doc: git-rebase: update discussion of internals Julia Evans via GitGitGadget
2025-08-08 19:15 ` [PATCH v2 0/5] doc: git-rebase: clarify DESCRIPTION section Julia Evans via GitGitGadget
2025-08-08 19:15 ` [PATCH v2 1/5] doc: git-rebase: start with an example Julia Evans via GitGitGadget
2025-08-08 23:31 ` Junio C Hamano
2025-08-08 19:15 ` [PATCH v2 2/5] doc: git rebase: dedup merge conflict discussion Julia Evans via GitGitGadget
2025-08-08 19:15 ` [PATCH v2 3/5] doc: git rebase: clarify arguments syntax Julia Evans via GitGitGadget
2025-08-08 21:09 ` Junio C Hamano
2025-08-08 19:15 ` [PATCH v2 4/5] doc: git-rebase: move --onto explanation down Julia Evans via GitGitGadget
2025-08-08 19:15 ` [PATCH v2 5/5] doc: git-rebase: update discussion of internals Julia Evans via GitGitGadget
2025-08-08 21:54 ` Junio C Hamano
2025-08-08 22:52 ` [PATCH v3 0/5] doc: git-rebase: clarify DESCRIPTION section Julia Evans via GitGitGadget
2025-08-08 22:52 ` [PATCH v3 1/5] doc: git-rebase: start with an example Julia Evans via GitGitGadget
2025-08-08 22:52 ` [PATCH v3 2/5] doc: git rebase: dedup merge conflict discussion Julia Evans via GitGitGadget
2025-08-08 22:52 ` [PATCH v3 3/5] doc: git rebase: clarify arguments syntax Julia Evans via GitGitGadget
2025-08-08 22:52 ` [PATCH v3 4/5] doc: git-rebase: move --onto explanation down Julia Evans via GitGitGadget
2025-08-08 22:52 ` [PATCH v3 5/5] doc: git-rebase: update discussion of internals Julia Evans via GitGitGadget
2025-08-09 1:14 ` [PATCH v4 0/5] doc: git-rebase: clarify DESCRIPTION section Julia Evans via GitGitGadget
2025-08-09 1:14 ` [PATCH v4 1/5] doc: git-rebase: start with an example Julia Evans via GitGitGadget
2025-08-10 15:41 ` Phillip Wood
2025-08-11 8:46 ` Patrick Steinhardt
2025-08-11 9:13 ` Karthik Nayak
2025-08-11 12:27 ` Ben Knoble
2025-08-12 9:05 ` Karthik Nayak
2025-08-12 14:30 ` Junio C Hamano
2025-08-11 13:07 ` Phillip Wood
2025-08-12 9:07 ` Karthik Nayak
2025-08-12 17:07 ` D. Ben Knoble
2025-08-12 18:07 ` Junio C Hamano
2025-08-14 7:23 ` Karthik Nayak
2025-08-09 1:14 ` [PATCH v4 2/5] doc: git rebase: dedup merge conflict discussion Julia Evans via GitGitGadget
2025-08-11 8:46 ` Patrick Steinhardt
2025-08-11 13:02 ` Phillip Wood
2025-08-09 1:14 ` [PATCH v4 3/5] doc: git rebase: clarify arguments syntax Julia Evans via GitGitGadget
2025-08-09 1:14 ` [PATCH v4 4/5] doc: git-rebase: move --onto explanation down Julia Evans via GitGitGadget
2025-08-09 14:55 ` D. Ben Knoble
2025-08-09 1:14 ` [PATCH v4 5/5] doc: git-rebase: update discussion of internals Julia Evans via GitGitGadget
2025-08-10 15:42 ` Phillip Wood
2025-08-13 18:55 ` symmetric difference with --left-only vs. range notation D. Ben Knoble
2025-08-13 21:40 ` Junio C Hamano
2025-08-11 8:46 ` [PATCH v4 5/5] doc: git-rebase: update discussion of internals Patrick Steinhardt
2025-08-11 12:29 ` Ben Knoble
2025-08-11 13:45 ` Patrick Steinhardt
2025-08-11 19:34 ` Julia Evans
2025-08-11 20:12 ` [PATCH v5 0/5] doc: git-rebase: clarify DESCRIPTION section Julia Evans via GitGitGadget
2025-08-11 20:12 ` [PATCH v5 1/5] doc: git-rebase: start with an example Julia Evans via GitGitGadget
2025-08-11 20:50 ` Junio C Hamano
2025-08-11 20:12 ` [PATCH v5 2/5] doc: git rebase: dedup merge conflict discussion Julia Evans via GitGitGadget
2025-08-11 20:12 ` [PATCH v5 3/5] doc: git rebase: clarify arguments syntax Julia Evans via GitGitGadget
2025-08-11 20:12 ` [PATCH v5 4/5] doc: git-rebase: move --onto explanation down Julia Evans via GitGitGadget
2025-08-11 20:12 ` [PATCH v5 5/5] doc: git-rebase: update discussion of internals Julia Evans via GitGitGadget
2025-08-11 21:14 ` Junio C Hamano
2025-08-11 21:51 ` [PATCH v6 0/5] doc: git-rebase: clarify DESCRIPTION section Julia Evans via GitGitGadget
2025-08-11 21:51 ` [PATCH v6 1/5] doc: git-rebase: start with an example Julia Evans via GitGitGadget
2025-08-11 21:51 ` [PATCH v6 2/5] doc: git rebase: dedup merge conflict discussion Julia Evans via GitGitGadget
2025-08-11 21:51 ` [PATCH v6 3/5] doc: git rebase: clarify arguments syntax Julia Evans via GitGitGadget
2025-08-11 21:51 ` [PATCH v6 4/5] doc: git-rebase: move --onto explanation down Julia Evans via GitGitGadget
2025-08-11 21:51 ` [PATCH v6 5/5] doc: git-rebase: update discussion of internals Julia Evans via GitGitGadget
2025-08-11 22:10 ` Junio C Hamano
2025-08-11 22:42 ` Julia Evans
2025-08-11 21:59 ` [PATCH v6 0/5] doc: git-rebase: clarify DESCRIPTION section Junio C Hamano
2025-08-12 13:49 ` [PATCH v7 " Julia Evans via GitGitGadget
2025-08-12 13:49 ` [PATCH v7 1/5] doc: git-rebase: start with an example Julia Evans via GitGitGadget
2025-08-12 13:49 ` [PATCH v7 2/5] doc: git rebase: dedup merge conflict discussion Julia Evans via GitGitGadget
2025-08-12 13:49 ` [PATCH v7 3/5] doc: git rebase: clarify arguments syntax Julia Evans via GitGitGadget
2025-08-12 13:49 ` [PATCH v7 4/5] doc: git-rebase: move --onto explanation down Julia Evans via GitGitGadget
2025-08-12 13:49 ` [PATCH v7 5/5] doc: git-rebase: update discussion of internals Julia Evans via GitGitGadget
2025-08-14 21:28 ` Junio C Hamano
2025-08-15 16:52 ` [PATCH v8 0/5] doc: git-rebase: clarify DESCRIPTION section Julia Evans via GitGitGadget
2025-08-15 16:52 ` [PATCH v8 1/5] doc: git-rebase: start with an example Julia Evans via GitGitGadget
2025-08-15 16:52 ` [PATCH v8 2/5] doc: git rebase: dedup merge conflict discussion Julia Evans via GitGitGadget
2025-08-15 16:52 ` [PATCH v8 3/5] doc: git rebase: clarify arguments syntax Julia Evans via GitGitGadget
2025-08-15 16:52 ` [PATCH v8 4/5] doc: git-rebase: move --onto explanation down Julia Evans via GitGitGadget
2025-08-15 21:05 ` Junio C Hamano
2025-08-18 13:42 ` Phillip Wood
2025-08-18 17:06 ` Junio C Hamano
2025-08-19 15:03 ` Julia Evans
2025-08-19 19:45 ` Junio C Hamano
2025-08-15 16:52 ` [PATCH v8 5/5] doc: git-rebase: update discussion of internals Julia Evans via GitGitGadget
2025-08-18 13:43 ` [PATCH v8 0/5] doc: git-rebase: clarify DESCRIPTION section Phillip Wood
2025-08-23 0:42 ` [PATCH v9 " Julia Evans via GitGitGadget
2025-08-23 0:42 ` [PATCH v9 1/5] doc: git-rebase: start with an example Julia Evans via GitGitGadget
2025-08-23 0:42 ` [PATCH v9 2/5] doc: git rebase: dedup merge conflict discussion Julia Evans via GitGitGadget
2025-08-23 0:43 ` [PATCH v9 3/5] doc: git rebase: clarify arguments syntax Julia Evans via GitGitGadget
2025-08-23 0:43 ` [PATCH v9 4/5] doc: git-rebase: move --onto explanation down Julia Evans via GitGitGadget
2025-08-23 0:43 ` [PATCH v9 5/5] doc: git-rebase: update discussion of internals Julia Evans via GitGitGadget
2025-08-13 13:31 ` [PATCH v6 0/5] doc: git-rebase: clarify DESCRIPTION section Phillip Wood
2025-08-13 15:33 ` Julia Evans
2025-08-14 21:18 ` Junio C Hamano
2025-08-15 10:25 ` Phillip Wood
2025-08-15 15:45 ` Junio C Hamano
2025-08-15 15:54 ` Phillip Wood
2025-08-15 15:56 ` Julia Evans
2025-08-15 10:25 ` Phillip Wood
2025-08-09 15:04 ` [PATCH v2 " D. Ben Knoble
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).