{"thread":{"id":"63930","subject":"[PATCH 0/5] doc: git-rebase: clarify DESCRIPTION section","startedAt":"2025-08-08T15:24:28Z","lastAt":"2025-08-23T00:43:10Z","messageCount":103,"participants":["Julia Evans via GitGitGadget","Junio C Hamano","Julia Evans","D. Ben Knoble","Phillip Wood","Patrick Steinhardt","Karthik Nayak","Ben Knoble"],"isPatch":true,"patchVersion":1,"patchTotal":5},"messages":[{"id":"523822","messageId":"pull.1949.git.1754666665.gitgitgadget@gmail.com","threadId":"63930","inReplyTo":null,"subject":"[PATCH 0/5] doc: git-rebase: clarify DESCRIPTION section","fromName":"Julia Evans via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-08-08T15:24:20Z","receivedAt":"2025-08-08T15:24:28Z","isPatch":true,"sender":{"key":"julia@jvns.ca","avatar":"https://avatars.githubusercontent.com/u/817739?v=4"},"body":"This patch series reorganizes the DESCRIPTION section of the git rebase man\npage. My goal is to make the page more accessible to git newcomers (who from\nmy experience have an extremely difficult time understanding git man pages)\nwhile keeping the exact same information available for more advanced users.\nThis series:\n\n * puts more commonly used information first (a basic example of a rebase\n   and \"how to fix merge conflicts\" are moved to before \"how rebase modifies\n   ORIG_HEAD\" and \"what git rebase <upstream> <branch> does\")\n * removes duplication\n * more closely parallels the git merge man page's structure by starting it\n   with the same example history\n * moves the --onto examples to their own section\n\nI've never contributed to Git before so I'd appreciate any pointers to past\ndiscussions of Git's documentation philosophy or who the target audience for\nGit documentation is.\n\nJulia Evans (5):\n  doc: git-rebase: start with an example\n  doc: git rebase: dedup merge conflict discussion\n  doc: git rebase: clarify arguments syntax\n  doc: git-rebase: move --onto explanation down\n  doc: git-rebase: update discussion of internals\n\n Documentation/git-rebase.adoc | 287 ++++++++++++++++------------------\n 1 file changed, 139 insertions(+), 148 deletions(-)\n\n\nbase-commit: 64cbe5e2e8a7b0f92c780b210e602496bd5cad0f\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-1949%2Fjvns%2Fclarify-rebase-v1\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1949/jvns/clarify-rebase-v1\nPull-Request: https://github.com/gitgitgadget/git/pull/1949\n-- \ngitgitgadget\n"},{"id":"523824","messageId":"ac3a91c04bfa5ab2b0e479c0bfeb2ba275fe1d56.1754666665.git.gitgitgadget@gmail.com","threadId":"63930","inReplyTo":"pull.1949.git.1754666665.gitgitgadget@gmail.com","subject":"[PATCH 1/5] doc: git-rebase: start with an example","fromName":"Julia Evans via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-08-08T15:24:21Z","receivedAt":"2025-08-08T15:24:28Z","isPatch":true,"sender":{"key":"julia@jvns.ca","avatar":"https://avatars.githubusercontent.com/u/817739?v=4"},"body":"From: Julia Evans <julia@jvns.ca>\n\nStart with an example that mirrors the example in the `git-merge` man\npage, to make it easier for folks to understand the difference between a\nrebase and a merge.\n\nSigned-off-by: Julia Evans <julia@jvns.ca>\n---\n Documentation/git-rebase.adoc | 46 +++++++++++++++--------------------\n 1 file changed, 20 insertions(+), 26 deletions(-)\n\ndiff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc\nindex 956d3048f5a6..fee73623990d 100644\n--- a/Documentation/git-rebase.adoc\n+++ b/Documentation/git-rebase.adoc\n@@ -16,6 +16,26 @@ SYNOPSIS\n \n DESCRIPTION\n -----------\n+Transplant a series of commits onto a different starting point.\n+\n+For example, assume the following history exists and the current branch is `topic`:\n+\n+------------\n+          A---B---C topic\n+         /\n+    D---E---F---G master\n+------------\n+\n+Then `git rebase master` will find all of the commits since `topic` diverged\n+from `master` and copy the changes in each of those commits on top of the\n+`master` branch.\n+\n+------------\n+                  A'--B'--C' topic\n+                 /\n+    D---E---F---G master\n+------------\n+\n If `<branch>` is specified, `git rebase` will perform an automatic\n `git switch <branch>` before doing anything else.  Otherwise\n it remains on the current branch.\n@@ -58,32 +78,6 @@ that caused the merge failure with `git rebase --skip`.  To check out the\n original `<branch>` and remove the `.git/rebase-apply` working files, use\n the command `git rebase --abort` instead.\n \n-Assume the following history exists and the current branch is \"topic\":\n-\n-------------\n-          A---B---C topic\n-         /\n-    D---E---F---G master\n-------------\n-\n-From this point, the result of either of the following commands:\n-\n-\n-    git rebase master\n-    git rebase master topic\n-\n-would be:\n-\n-------------\n-                  A'--B'--C' topic\n-                 /\n-    D---E---F---G master\n-------------\n-\n-*NOTE:* The latter form is just a short-hand of `git checkout topic`\n-followed by `git rebase master`. When rebase exits `topic` will\n-remain the checked-out branch.\n-\n If the upstream branch already contains a change you have made (e.g.,\n because you mailed a patch which was applied upstream), then that commit\n will be skipped and warnings will be issued (if the 'merge' backend is\n-- \ngitgitgadget\n\n"},{"id":"523823","messageId":"f4f0a5a1172b283d5254ce06ef08795286bb725c.1754666665.git.gitgitgadget@gmail.com","threadId":"63930","inReplyTo":"pull.1949.git.1754666665.gitgitgadget@gmail.com","subject":"[PATCH 2/5] doc: git rebase: dedup merge conflict discussion","fromName":"Julia Evans via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-08-08T15:24:22Z","receivedAt":"2025-08-08T15:24:29Z","isPatch":true,"sender":{"key":"julia@jvns.ca","avatar":"https://avatars.githubusercontent.com/u/817739?v=4"},"body":"From: Julia Evans <julia@jvns.ca>\n\nPreviously there were two explanations, this combines them both into a\nsingle explanation.\n\nSigned-off-by: Julia Evans <julia@jvns.ca>\n---\n Documentation/git-rebase.adoc | 52 ++++++++++++++++-------------------\n 1 file changed, 23 insertions(+), 29 deletions(-)\n\ndiff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc\nindex fee73623990d..3087e558b509 100644\n--- a/Documentation/git-rebase.adoc\n+++ b/Documentation/git-rebase.adoc\n@@ -36,6 +36,29 @@ from `master` and copy the changes in each of those commits on top of the\n     D---E---F---G master\n ------------\n \n+If there is a merge conflict during this process, `git rebase` will stop at the\n+first problematic commit and leave conflict markers. If this happens, you can:\n+\n+1. Resolve the conflict. You can use `git diff` to find the markers (<<<<<<)\n+   and make edits to resolve the conflict. For each file you edit, you need to\n+   tell Git that the conflict has been resolved. Typically this would be\n+   done with\n+\n+   git add <filename>\n+\n+   You can then continue the rebasing process with\n+\n+   git rebase --continue\n+\n+2. Stop the `git rebase` and return your branch to its original state with\n+\n+   git rebase --abort\n+\n+3. Skip the commit that caused the merge conflict with\n+\n+   git rebase --skip\n+\n+\n If `<branch>` is specified, `git rebase` will perform an automatic\n `git switch <branch>` before doing anything else.  Otherwise\n it remains on the current branch.\n@@ -71,13 +94,6 @@ any commits in `HEAD` which introduce the same textual changes as a commit\n in `HEAD..<upstream>` are omitted (i.e., a patch already accepted upstream\n with a different commit message or timestamp will be skipped).\n \n-It is possible that a merge failure will prevent this process from being\n-completely automatic.  You will have to resolve any such merge failure\n-and run `git rebase --continue`.  Another option is to bypass the commit\n-that caused the merge failure with `git rebase --skip`.  To check out the\n-original `<branch>` and remove the `.git/rebase-apply` working files, use\n-the command `git rebase --abort` instead.\n-\n If the upstream branch already contains a change you have made (e.g.,\n because you mailed a patch which was applied upstream), then that commit\n will be skipped and warnings will be issued (if the 'merge' backend is\n@@ -180,28 +196,6 @@ This is useful if F and G were flawed in some way, or should not be\n part of topicA.  Note that the argument to `--onto` and the `<upstream>`\n parameter can be any valid commit-ish.\n \n-In case of conflict, `git rebase` will stop at the first problematic commit\n-and leave conflict markers in the tree.  You can use `git diff` to locate\n-the markers (<<<<<<) and make edits to resolve the conflict.  For each\n-file you edit, you need to tell Git that the conflict has been resolved,\n-typically this would be done with\n-\n-\n-    git add <filename>\n-\n-\n-After resolving the conflict manually and updating the index with the\n-desired resolution, you can continue the rebasing process with\n-\n-\n-    git rebase --continue\n-\n-\n-Alternatively, you can undo the 'git rebase' with\n-\n-\n-    git rebase --abort\n-\n MODE OPTIONS\n ------------\n \n-- \ngitgitgadget\n\n"},{"id":"523825","messageId":"b27117ea19a41ec544d3e721e3a188ceb6efbedd.1754666665.git.gitgitgadget@gmail.com","threadId":"63930","inReplyTo":"pull.1949.git.1754666665.gitgitgadget@gmail.com","subject":"[PATCH 3/5] doc: git rebase: clarify arguments syntax","fromName":"Julia Evans via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-08-08T15:24:23Z","receivedAt":"2025-08-08T15:24:30Z","isPatch":true,"sender":{"key":"julia@jvns.ca","avatar":"https://avatars.githubusercontent.com/u/817739?v=4"},"body":"From: Julia Evans <julia@jvns.ca>\n\nI found this extremely hard to understand as it was and this seemed like\na clearer wording to me.\n\nSigned-off-by: Julia Evans <julia@jvns.ca>\n---\n Documentation/git-rebase.adoc | 8 +++-----\n 1 file changed, 3 insertions(+), 5 deletions(-)\n\ndiff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc\nindex 3087e558b509..ada9f6b2614b 100644\n--- a/Documentation/git-rebase.adoc\n+++ b/Documentation/git-rebase.adoc\n@@ -58,12 +58,10 @@ first problematic commit and leave conflict markers. If this happens, you can:\n \n    git rebase --skip\n \n+`git rebase <upstream> <branch>` is shorthand for `git switch <branch>`\n+followed by `git rebase <upstream>`.\n \n-If `<branch>` is specified, `git rebase` will perform an automatic\n-`git switch <branch>` before doing anything else.  Otherwise\n-it remains on the current branch.\n-\n-If `<upstream>` is not specified, the upstream configured in\n+If you don't specify an `<upstream>` to rebase onto, the upstream configured in\n `branch.<name>.remote` and `branch.<name>.merge` options will be used (see\n linkgit:git-config[1] for details) and the `--fork-point` option is\n assumed.  If you are currently not on any branch or if the current\n-- \ngitgitgadget\n\n"},{"id":"523826","messageId":"28b00d3b32fbb2771048ddf6088e59172983a8aa.1754666665.git.gitgitgadget@gmail.com","threadId":"63930","inReplyTo":"pull.1949.git.1754666665.gitgitgadget@gmail.com","subject":"[PATCH 4/5] doc: git-rebase: move --onto explanation down","fromName":"Julia Evans via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-08-08T15:24:24Z","receivedAt":"2025-08-08T15:24:31Z","isPatch":true,"sender":{"key":"julia@jvns.ca","avatar":"https://avatars.githubusercontent.com/u/817739?v=4"},"body":"From: Julia Evans <julia@jvns.ca>\n\nThere's a very clear explanation with examples of using --onto which is\ncurrently buried in the very long DESCRIPTION section. This moves it to\nits own section, so that we can reference the explanation from the\n`--onto` option by name.\n\nSigned-off-by: Julia Evans <julia@jvns.ca>\n---\n Documentation/git-rebase.adoc | 168 ++++++++++++++++++----------------\n 1 file changed, 87 insertions(+), 81 deletions(-)\n\ndiff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc\nindex ada9f6b2614b..c63d67f340a0 100644\n--- a/Documentation/git-rebase.adoc\n+++ b/Documentation/git-rebase.adoc\n@@ -113,87 +113,6 @@ will result in:\n     D---E---A'---F master\n ------------\n \n-Here is how you would transplant a topic branch based on one\n-branch to another, to pretend that you forked the topic branch\n-from the latter branch, using `rebase --onto`.\n-\n-First let's assume your 'topic' is based on branch 'next'.\n-For example, a feature developed in 'topic' depends on some\n-functionality which is found in 'next'.\n-\n-------------\n-    o---o---o---o---o  master\n-         \\\n-          o---o---o---o---o  next\n-                           \\\n-                            o---o---o  topic\n-------------\n-\n-We want to make 'topic' forked from branch 'master'; for example,\n-because the functionality on which 'topic' depends was merged into the\n-more stable 'master' branch. We want our tree to look like this:\n-\n-------------\n-    o---o---o---o---o  master\n-        |            \\\n-        |             o'--o'--o'  topic\n-         \\\n-          o---o---o---o---o  next\n-------------\n-\n-We can get this using the following command:\n-\n-    git rebase --onto master next topic\n-\n-\n-Another example of --onto option is to rebase part of a\n-branch.  If we have the following situation:\n-\n-------------\n-                            H---I---J topicB\n-                           /\n-                  E---F---G  topicA\n-                 /\n-    A---B---C---D  master\n-------------\n-\n-then the command\n-\n-    git rebase --onto master topicA topicB\n-\n-would result in:\n-\n-------------\n-                 H'--I'--J'  topicB\n-                /\n-                | E---F---G  topicA\n-                |/\n-    A---B---C---D  master\n-------------\n-\n-This is useful when topicB does not depend on topicA.\n-\n-A range of commits could also be removed with rebase.  If we have\n-the following situation:\n-\n-------------\n-    E---F---G---H---I---J  topicA\n-------------\n-\n-then the command\n-\n-    git rebase --onto topicA~5 topicA~3 topicA\n-\n-would result in the removal of commits F and G:\n-\n-------------\n-    E---H'---I'---J'  topicA\n-------------\n-\n-This is useful if F and G were flawed in some way, or should not be\n-part of topicA.  Note that the argument to `--onto` and the `<upstream>`\n-parameter can be any valid commit-ish.\n-\n MODE OPTIONS\n ------------\n \n@@ -239,6 +158,8 @@ As a special case, you may use \"A\\...B\" as a shortcut for the\n merge base of A and B if there is exactly one merge base. You can\n leave out at most one of A and B, in which case it defaults to HEAD.\n \n+See TRANSPLANTING A TOPIC BRANCH WITH --ONTO below for examples.\n+\n --keep-base::\n \tSet the starting point at which to create the new commits to the\n \tmerge base of `<upstream>` and `<branch>`. Running\n@@ -1017,6 +938,91 @@ consistent (they compile, pass the testsuite, etc.) you should use\n after each commit, test, and amend the commit if fixes are necessary.\n \n \n+TRANSPLANTING A TOPIC BRANCH WITH --ONTO\n+----------------------------------------\n+\n+Here is how you would transplant a topic branch based on one\n+branch to another, to pretend that you forked the topic branch\n+from the latter branch, using `rebase --onto`.\n+\n+First let's assume your 'topic' is based on branch 'next'.\n+For example, a feature developed in 'topic' depends on some\n+functionality which is found in 'next'.\n+\n+------------\n+    o---o---o---o---o  master\n+         \\\n+          o---o---o---o---o  next\n+                           \\\n+                            o---o---o  topic\n+------------\n+\n+We want to make 'topic' forked from branch 'master'; for example,\n+because the functionality on which 'topic' depends was merged into the\n+more stable 'master' branch. We want our tree to look like this:\n+\n+------------\n+    o---o---o---o---o  master\n+        |            \\\n+        |             o'--o'--o'  topic\n+         \\\n+          o---o---o---o---o  next\n+------------\n+\n+We can get this using the following command:\n+\n+    git rebase --onto master next topic\n+\n+\n+Another example of --onto option is to rebase part of a\n+branch.  If we have the following situation:\n+\n+------------\n+                            H---I---J topicB\n+                           /\n+                  E---F---G  topicA\n+                 /\n+    A---B---C---D  master\n+------------\n+\n+then the command\n+\n+    git rebase --onto master topicA topicB\n+\n+would result in:\n+\n+------------\n+                 H'--I'--J'  topicB\n+                /\n+                | E---F---G  topicA\n+                |/\n+    A---B---C---D  master\n+------------\n+\n+This is useful when topicB does not depend on topicA.\n+\n+A range of commits could also be removed with rebase.  If we have\n+the following situation:\n+\n+------------\n+    E---F---G---H---I---J  topicA\n+------------\n+\n+then the command\n+\n+    git rebase --onto topicA~5 topicA~3 topicA\n+\n+would result in the removal of commits F and G:\n+\n+------------\n+    E---H'---I'---J'  topicA\n+------------\n+\n+This is useful if F and G were flawed in some way, or should not be\n+part of topicA.  Note that the argument to `--onto` and the `<upstream>`\n+parameter can be any valid commit-ish.\n+\n+\n RECOVERING FROM UPSTREAM REBASE\n -------------------------------\n \n-- \ngitgitgadget\n\n"},{"id":"523827","messageId":"7d4dc6d2c046aa33497f1c485a2022c9896e051e.1754666665.git.gitgitgadget@gmail.com","threadId":"63930","inReplyTo":"pull.1949.git.1754666665.gitgitgadget@gmail.com","subject":"[PATCH 5/5] doc: git-rebase: update discussion of internals","fromName":"Julia Evans via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-08-08T15:24:25Z","receivedAt":"2025-08-08T15:24:32Z","isPatch":true,"sender":{"key":"julia@jvns.ca","avatar":"https://avatars.githubusercontent.com/u/817739?v=4"},"body":"From: Julia Evans <julia@jvns.ca>\n\n- make it clearer that we're talking about three steps of a process\n- delete a duplicate explanation of how git rebase skips commits with\n  the same textual changes (it's explained in more detail a few lines\n  further down)\n- move the `ORIG_HEAD` note down so that it doesn't interrupt the\n  discussion of the mechanics.\n\nSigned-off-by: Julia Evans <julia@jvns.ca>\n---\n Documentation/git-rebase.adoc | 15 +++++++--------\n 1 file changed, 7 insertions(+), 8 deletions(-)\n\ndiff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc\nindex c63d67f340a0..6b79cd0daca9 100644\n--- a/Documentation/git-rebase.adoc\n+++ b/Documentation/git-rebase.adoc\n@@ -67,18 +67,23 @@ linkgit:git-config[1] for details) and the `--fork-point` option is\n assumed.  If you are currently not on any branch or if the current\n branch does not have a configured upstream, the rebase will abort.\n \n-All changes made by commits in the current branch but that are not\n+Here is a more detailed description of what `git rebase <upstream>` does:\n+\n+First, all changes made by commits in the current branch but that are not\n in `<upstream>` are saved to a temporary area.  This is the same set\n of commits that would be shown by `git log <upstream>..HEAD`; or by\n `git log 'fork_point'..HEAD`, if `--fork-point` is active (see the\n description on `--fork-point` below); or by `git log HEAD`, if the\n `--root` option is specified.\n \n-The current branch is reset to `<upstream>` or `<newbase>` if the\n+Then the current branch is reset to `<upstream>` or `<newbase>` if the\n `--onto` option was supplied.  This has the exact same effect as\n `git reset --hard <upstream>` (or `<newbase>`). `ORIG_HEAD` is set\n to point at the tip of the branch before the reset.\n \n+Then the commits that were previously saved into the temporary area are\n+reapplied to the current branch, one by one, in order.\n+\n [NOTE]\n `ORIG_HEAD` is not guaranteed to still point to the previous branch tip\n at the end of the rebase if other commands that write that pseudo-ref\n@@ -86,12 +91,6 @@ at the end of the rebase if other commands that write that pseudo-ref\n however, is accessible using the reflog of the current branch\n (i.e. `@{1}`, see linkgit:gitrevisions[7]).\n \n-The commits that were previously saved into the temporary area are\n-then reapplied to the current branch, one by one, in order. Note that\n-any commits in `HEAD` which introduce the same textual changes as a commit\n-in `HEAD..<upstream>` are omitted (i.e., a patch already accepted upstream\n-with a different commit message or timestamp will be skipped).\n-\n If the upstream branch already contains a change you have made (e.g.,\n because you mailed a patch which was applied upstream), then that commit\n will be skipped and warnings will be issued (if the 'merge' backend is\n-- \ngitgitgadget\n"},{"id":"523831","messageId":"xmqq34a1ixo3.fsf@gitster.g","threadId":"63930","inReplyTo":"ac3a91c04bfa5ab2b0e479c0bfeb2ba275fe1d56.1754666665.git.gitgitgadget@gmail.com","subject":"Re: [PATCH 1/5] doc: git-rebase: start with an example","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2025-08-08T16:30:04Z","receivedAt":"2025-08-08T16:30:07Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Julia Evans via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n\n> From: Julia Evans <julia@jvns.ca>\n>\n> Start with an example that mirrors the example in the `git-merge` man\n> page, to make it easier for folks to understand the difference between a\n> rebase and a merge.\n>\n> Signed-off-by: Julia Evans <julia@jvns.ca>\n> ---\n>  Documentation/git-rebase.adoc | 46 +++++++++++++++--------------------\n>  1 file changed, 20 insertions(+), 26 deletions(-)\n>\n> diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc\n> index 956d3048f5a6..fee73623990d 100644\n> --- a/Documentation/git-rebase.adoc\n> +++ b/Documentation/git-rebase.adoc\n> @@ -16,6 +16,26 @@ SYNOPSIS\n>  \n>  DESCRIPTION\n>  -----------\n> +Transplant a series of commits onto a different starting point.\n\nIt is an excellent idea to start with what it does, before\nexplaining how you would drive it.\n\n> +For example, assume the following history exists and the current branch is `topic`:\n\nThe line is a bit overly long, and the style a bit on the\n\"description of dry facts\" side, which might want to give\na bit more \"motivation\" to help readers.\n\nHere is my attempt.\n\n    Imagine that you have been working on the `topic` branch in this\n    history, and you'd want to \"catch up\" to the work done on the\n    `master` branch.\n\n      *** Illustration of \"before\" state ***\n\n    You want to transplant the commits you made on `topic` since it\n    diverged from `master` (i.e. A, B, and C), on top of the current\n    `master`.  You can do so by running `git rebase master` while the\n    `topic` branch is checked out.  `git rebase master topic` works\n    as a short-cut to `git checkout topic && git rebase master`.\n\n      *** Illustration of \"after\" state ***\n\nperhaps?  \n\nNote that you lost the mention of `git rebase master topic` syntax\nand the explanation that the form being a shorthand for checkout\nfollowed by rebase, which I do not think appear anywhere else in the\ndocument, so my suggested rewrite above resurrects it.\n\n> +------------\n> +          A---B---C topic\n> +         /\n> +    D---E---F---G master\n> +------------\n> +\n> +Then `git rebase master` will find all of the commits since `topic` diverged\n> +from `master` and copy the changes in each of those commits on top of the\n> +`master` branch.\n> +\n> +------------\n> +                  A'--B'--C' topic\n> +                 /\n> +    D---E---F---G master\n> +------------\n> +\n>  If `<branch>` is specified, `git rebase` will perform an automatic\n>  `git switch <branch>` before doing anything else.  Otherwise\n>  it remains on the current branch.\n> @@ -58,32 +78,6 @@ that caused the merge failure with `git rebase --skip`.  To check out the\n>  original `<branch>` and remove the `.git/rebase-apply` working files, use\n>  the command `git rebase --abort` instead.\n>  \n> -Assume the following history exists and the current branch is \"topic\":\n> -\n> -------------\n> -          A---B---C topic\n> -         /\n> -    D---E---F---G master\n> -------------\n> -\n> -From this point, the result of either of the following commands:\n> -\n> -\n> -    git rebase master\n> -    git rebase master topic\n> -\n> -would be:\n> -\n> -------------\n> -                  A'--B'--C' topic\n> -                 /\n> -    D---E---F---G master\n> -------------\n> -\n> -*NOTE:* The latter form is just a short-hand of `git checkout topic`\n> -followed by `git rebase master`. When rebase exits `topic` will\n> -remain the checked-out branch.\n> -\n>  If the upstream branch already contains a change you have made (e.g.,\n>  because you mailed a patch which was applied upstream), then that commit\n>  will be skipped and warnings will be issued (if the 'merge' backend is\n"},{"id":"523832","messageId":"f9cd981e-276b-4b13-8e98-c7bae17bcf62@app.fastmail.com","threadId":"63930","inReplyTo":"xmqq34a1ixo3.fsf@gitster.g","subject":"Re: [PATCH 1/5] doc: git-rebase: start with an example","fromName":"Julia Evans","fromEmail":"julia@jvns.ca","sentAt":"2025-08-08T17:13:48Z","receivedAt":"2025-08-08T17:14:10Z","isPatch":true,"sender":{"key":"julia@jvns.ca","avatar":"https://avatars.githubusercontent.com/u/817739?v=4"},"body":"On Fri, Aug 8, 2025, at 12:30 PM, Junio C Hamano wrote:\n> \"Julia Evans via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n>\n>> From: Julia Evans <julia@jvns.ca>\n>>\n>> Start with an example that mirrors the example in the `git-merge` man\n>> page, to make it easier for folks to understand the difference between a\n>> rebase and a merge.\n>>\n>> Signed-off-by: Julia Evans <julia@jvns.ca>\n>> ---\n>>  Documentation/git-rebase.adoc | 46 +++++++++++++++--------------------\n>>  1 file changed, 20 insertions(+), 26 deletions(-)\n>>\n>> diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc\n>> index 956d3048f5a6..fee73623990d 100644\n>> --- a/Documentation/git-rebase.adoc\n>> +++ b/Documentation/git-rebase.adoc\n>> @@ -16,6 +16,26 @@ SYNOPSIS\n>>  \n>>  DESCRIPTION\n>>  -----------\n>> +Transplant a series of commits onto a different starting point.\n>\n> It is an excellent idea to start with what it does, before\n> explaining how you would drive it.\n>\n>> +For example, assume the following history exists and the current branch is `topic`:\n>\n> The line is a bit overly long, and the style a bit on the\n> \"description of dry facts\" side, which might want to give\n> a bit more \"motivation\" to help readers.\n\nI'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.\n\n> Note that you lost the mention of `git rebase master topic` syntax\n> and the explanation that the form being a shorthand for checkout\n> followed by rebase, which I do not think appear anywhere else in the\n> document, so my suggested rewrite above resurrects it.\n\nThat'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.\n"},{"id":"523834","messageId":"xmqqikixhfhk.fsf@gitster.g","threadId":"63930","inReplyTo":"f4f0a5a1172b283d5254ce06ef08795286bb725c.1754666665.git.gitgitgadget@gmail.com","subject":"Re: [PATCH 2/5] doc: git rebase: dedup merge conflict discussion","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2025-08-08T17:48:07Z","receivedAt":"2025-08-08T17:48:10Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Julia Evans via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n\n> +If there is a merge conflict during this process, `git rebase` will stop at the\n> +first problematic commit and leave conflict markers. If this happens, you can:\n\nBy using the numbered enumeration below, we may mislead the readers\nthat these are the things they have to do in this order, when we\nactually are giving them choices.\n\n\tIf this happens, you can do one of these things:\n\nwould be an easy workaround.\n\n> +1. Resolve the conflict. You can use `git diff` to find the markers (<<<<<<)\n> +   and make edits to resolve the conflict. For each file you edit, you need to\n> +   tell Git that the conflict has been resolved. Typically this would be\n> +   done with\n> +\n> +   git add <filename>\n> +\n> +   You can then continue the rebasing process with\n> +\n> +   git rebase --continue\n\nThe original (below) does not do a perfect job, but I am afraid that\nthis increases the chance of misunderstanding by new readers that\nthey'd run \"continue\" after marking each confclited fines as \"done\"\nwith \"git add\", by reducing a sentence to a mere \"then\" in \"You can\nthen continue\".\n\n\tTypically after resolving all the conflicts in a single\n\tfile, you would tell Git that you are done with this file:\n\n\tgit add <filename>\n\n\tAnd after dealing with all the conflicted files and telling\n\tGit that you are done, you would continue the rebasing\n\tprocess with\n\n\tgit rebase --continue\n\nor something?\n\n> +2. Stop the `git rebase` and return your branch to its original state with\n> +\n> +   git rebase --abort\n> +\n> +3. Skip the commit that caused the merge conflict with\n> +\n> +   git rebase --skip\n\nThe explanation in the above looks good, and the new organization is\nmuch easier to follow and is definite improvement compared to the\noriginal.\n\nI am not sure how the above how the above formats, though,\nespecially on a medium that is not monospaced text (e.g., html\nrendition, not \"git help -m rebase\" on terminals).  The prose should\ntypeset just like the normal text (i.e. your \"Transplant a series of\ncommits\" in the previous step that starts the description section),\nbut the command that the users would type should be typeset in\nmonospace typewriter.  Have you tried?\n\nThanks.\n"},{"id":"523835","messageId":"xmqqcy95hedv.fsf@gitster.g","threadId":"63930","inReplyTo":"f9cd981e-276b-4b13-8e98-c7bae17bcf62@app.fastmail.com","subject":"Re: [PATCH 1/5] doc: git-rebase: start with an example","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2025-08-08T18:11:56Z","receivedAt":"2025-08-08T18:11:59Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Julia Evans\" <julia@jvns.ca> writes:\n\n> I'm very happy to hear that feedback: I thought it was very dry as\n> well, but I copied that part from elsewhere in the man page\n> because I thought that was git's preferred documentation\n> style. I'll work on making it less dry.\n\n[administrivia: please wrap your overlong lines; we write for this\nhypothetiical reader on an 80-column terminal].\n\n>> Note that you lost the mention of `git rebase master topic` syntax\n>> and the explanation that the form being a shorthand for checkout\n>> followed by rebase, which I do not think appear anywhere else in the\n>> document, so my suggested rewrite above resurrects it.\n>\n> That's actually in PATCH 3/5 of this series:...\n\nWhich I think is too late; both are quite commonly used and useful,\nso showing them upfront when the command line examples are first\nintroduced would be more preferrable.\n\nThanks.\n"},{"id":"523836","messageId":"pull.1949.v2.git.1754680525.gitgitgadget@gmail.com","threadId":"63930","inReplyTo":"pull.1949.git.1754666665.gitgitgadget@gmail.com","subject":"[PATCH v2 0/5] doc: git-rebase: clarify DESCRIPTION section","fromName":"Julia Evans via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-08-08T19:15:20Z","receivedAt":"2025-08-08T19:15:29Z","isPatch":true,"sender":{"key":"julia@jvns.ca","avatar":"https://avatars.githubusercontent.com/u/817739?v=4"},"body":"Thanks for the review comments, here are the new changes which:\n\n * make the intro to the man page less dry, with the suggested wording\n * clarify the merge conflict resolution explanation & fix the HTML\n   formatting issues\n * move the explanation of the git rebase <upstream> <branch> syntax up into\n   the intro\n\nI'm still curious about the intention for the git rebase master topic\nsyntax, since I'd never heard of it before. Is it just to save on typing,\nsince it's fewer characters than git switch topic and then git rebase\nmaster? I ask because someone mentioned to me on Mastodon\n(https://hachyderm.io/@simontatham/114988051822317920) that they sometimes\nuse git rebase HEAD main as part of their workflow, which is not equivalent\nto git checkout main && git rebase HEAD. That made me think that there might\nbe some broader intent to enable rebases that wouldn't otherwise be possible\nwithout that syntax.\n\nI'll wrap my text to 80 characters in the future, still learning the process\nfor emailing a plain-text mailing list :)\n\nJulia Evans (5):\n  doc: git-rebase: start with an example\n  doc: git rebase: dedup merge conflict discussion\n  doc: git rebase: clarify arguments syntax\n  doc: git-rebase: move --onto explanation down\n  doc: git-rebase: update discussion of internals\n\n Documentation/git-rebase.adoc | 285 ++++++++++++++++------------------\n 1 file changed, 137 insertions(+), 148 deletions(-)\n\n\nbase-commit: 2c2ba49d55ff26c1082b8137b1ec5eeccb4337d1\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-1949%2Fjvns%2Fclarify-rebase-v2\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1949/jvns/clarify-rebase-v2\nPull-Request: https://github.com/gitgitgadget/git/pull/1949\n\nRange-diff vs v1:\n\n 1:  ac3a91c04bf ! 1:  26b742eb49f doc: git-rebase: start with an example\n     @@ Documentation/git-rebase.adoc: SYNOPSIS\n       -----------\n      +Transplant a series of commits onto a different starting point.\n      +\n     -+For example, assume the following history exists and the current branch is `topic`:\n     ++For example, imagine that you have been working on the `topic` branch in this\n     ++history, and you want to \"catch up\" to the work done on the `master` branch.\n      +\n      +------------\n      +          A---B---C topic\n     @@ Documentation/git-rebase.adoc: SYNOPSIS\n      +    D---E---F---G master\n      +------------\n      +\n     -+Then `git rebase master` will find all of the commits since `topic` diverged\n     -+from `master` and copy the changes in each of those commits on top of the\n     -+`master` branch.\n     ++You want to transplant the commits you made on `topic` since it diverged from\n     ++`master` (i.e. A, B, and C), on top of the current `master`.  You can do this\n     ++by running `git rebase master` while the `topic` branch is checked out.  If you\n     ++want to rebase `topic` while on another branch, `git rebase master topic` is a\n     ++short-cut for `git switch topic && git rebase master`.\n      +\n      +------------\n      +                  A'--B'--C' topic\n 2:  f4f0a5a1172 ! 2:  249a5127904 doc: git rebase: dedup merge conflict discussion\n     @@ Commit message\n          Signed-off-by: Julia Evans <julia@jvns.ca>\n      \n       ## Documentation/git-rebase.adoc ##\n     -@@ Documentation/git-rebase.adoc: from `master` and copy the changes in each of those commits on top of the\n     +@@ Documentation/git-rebase.adoc: short-cut for `git switch topic && git rebase master`.\n           D---E---F---G master\n       ------------\n       \n      +If there is a merge conflict during this process, `git rebase` will stop at the\n     -+first problematic commit and leave conflict markers. If this happens, you can:\n     ++first problematic commit and leave conflict markers. If this happens, you can do\n     ++one of these things:\n      +\n      +1. Resolve the conflict. You can use `git diff` to find the markers (<<<<<<)\n      +   and make edits to resolve the conflict. For each file you edit, you need to\n     -+   tell Git that the conflict has been resolved. Typically this would be\n     -+   done with\n     -+\n     -+   git add <filename>\n     -+\n     -+   You can then continue the rebasing process with\n     ++   tell Git that the conflict has been resolved. You can mark the conflict as\n     ++   resolved with  `git add <filename>`. After resolving all of the conflicts,\n     ++   you can continue the rebasing process with\n      +\n      +   git rebase --continue\n      +\n 3:  b27117ea19a ! 3:  ce7ab74ea0f doc: git rebase: clarify arguments syntax\n     @@ Metadata\n       ## Commit message ##\n          doc: git rebase: clarify arguments syntax\n      \n     -    I found this extremely hard to understand as it was and this seemed like\n     -    a clearer wording to me.\n     +    This removes the explanation of `git rebase <upstream> <branch>`, since\n     +    it was already explained above that it's shorthand for `git switch\n     +    <branch> && git rebase <upstream>`\n      \n          Signed-off-by: Julia Evans <julia@jvns.ca>\n      \n       ## Documentation/git-rebase.adoc ##\n     -@@ Documentation/git-rebase.adoc: first problematic commit and leave conflict markers. If this happens, you can:\n     +@@ Documentation/git-rebase.adoc: one of these things:\n       \n          git rebase --skip\n       \n     -+`git rebase <upstream> <branch>` is shorthand for `git switch <branch>`\n     -+followed by `git rebase <upstream>`.\n     - \n     +-\n      -If `<branch>` is specified, `git rebase` will perform an automatic\n      -`git switch <branch>` before doing anything else.  Otherwise\n      -it remains on the current branch.\n 4:  28b00d3b32f = 4:  590d7486d3d doc: git-rebase: move --onto explanation down\n 5:  7d4dc6d2c04 = 5:  ad97cd9e671 doc: git-rebase: update discussion of internals\n\n-- \ngitgitgadget\n"},{"id":"523837","messageId":"26b742eb49f935147ac373bf9435827a6f85e531.1754680525.git.gitgitgadget@gmail.com","threadId":"63930","inReplyTo":"pull.1949.v2.git.1754680525.gitgitgadget@gmail.com","subject":"[PATCH v2 1/5] doc: git-rebase: start with an example","fromName":"Julia Evans via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-08-08T19:15:21Z","receivedAt":"2025-08-08T19:15:30Z","isPatch":true,"sender":{"key":"julia@jvns.ca","avatar":"https://avatars.githubusercontent.com/u/817739?v=4"},"body":"From: Julia Evans <julia@jvns.ca>\n\nStart with an example that mirrors the example in the `git-merge` man\npage, to make it easier for folks to understand the difference between a\nrebase and a merge.\n\nSigned-off-by: Julia Evans <julia@jvns.ca>\n---\n Documentation/git-rebase.adoc | 49 ++++++++++++++++-------------------\n 1 file changed, 23 insertions(+), 26 deletions(-)\n\ndiff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc\nindex 956d3048f5a6..6dacf693bd71 100644\n--- a/Documentation/git-rebase.adoc\n+++ b/Documentation/git-rebase.adoc\n@@ -16,6 +16,29 @@ SYNOPSIS\n \n DESCRIPTION\n -----------\n+Transplant a series of commits onto a different starting point.\n+\n+For example, imagine that you have been working on the `topic` branch in this\n+history, and you want to \"catch up\" to the work done on the `master` branch.\n+\n+------------\n+          A---B---C topic\n+         /\n+    D---E---F---G master\n+------------\n+\n+You want to transplant the commits you made on `topic` since it diverged from\n+`master` (i.e. A, B, and C), on top of the current `master`.  You can do this\n+by running `git rebase master` while the `topic` branch is checked out.  If you\n+want to rebase `topic` while on another branch, `git rebase master topic` is a\n+short-cut for `git switch topic && git rebase master`.\n+\n+------------\n+                  A'--B'--C' topic\n+                 /\n+    D---E---F---G master\n+------------\n+\n If `<branch>` is specified, `git rebase` will perform an automatic\n `git switch <branch>` before doing anything else.  Otherwise\n it remains on the current branch.\n@@ -58,32 +81,6 @@ that caused the merge failure with `git rebase --skip`.  To check out the\n original `<branch>` and remove the `.git/rebase-apply` working files, use\n the command `git rebase --abort` instead.\n \n-Assume the following history exists and the current branch is \"topic\":\n-\n-------------\n-          A---B---C topic\n-         /\n-    D---E---F---G master\n-------------\n-\n-From this point, the result of either of the following commands:\n-\n-\n-    git rebase master\n-    git rebase master topic\n-\n-would be:\n-\n-------------\n-                  A'--B'--C' topic\n-                 /\n-    D---E---F---G master\n-------------\n-\n-*NOTE:* The latter form is just a short-hand of `git checkout topic`\n-followed by `git rebase master`. When rebase exits `topic` will\n-remain the checked-out branch.\n-\n If the upstream branch already contains a change you have made (e.g.,\n because you mailed a patch which was applied upstream), then that commit\n will be skipped and warnings will be issued (if the 'merge' backend is\n-- \ngitgitgadget\n\n"},{"id":"523838","messageId":"249a5127904f2d73119f3b60d70a57fe84d1b4ad.1754680525.git.gitgitgadget@gmail.com","threadId":"63930","inReplyTo":"pull.1949.v2.git.1754680525.gitgitgadget@gmail.com","subject":"[PATCH v2 2/5] doc: git rebase: dedup merge conflict discussion","fromName":"Julia Evans via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-08-08T19:15:22Z","receivedAt":"2025-08-08T19:15:30Z","isPatch":true,"sender":{"key":"julia@jvns.ca","avatar":"https://avatars.githubusercontent.com/u/817739?v=4"},"body":"From: Julia Evans <julia@jvns.ca>\n\nPreviously there were two explanations, this combines them both into a\nsingle explanation.\n\nSigned-off-by: Julia Evans <julia@jvns.ca>\n---\n Documentation/git-rebase.adoc | 50 +++++++++++++++--------------------\n 1 file changed, 21 insertions(+), 29 deletions(-)\n\ndiff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc\nindex 6dacf693bd71..a93c616f38b1 100644\n--- a/Documentation/git-rebase.adoc\n+++ b/Documentation/git-rebase.adoc\n@@ -39,6 +39,27 @@ short-cut for `git switch topic && git rebase master`.\n     D---E---F---G master\n ------------\n \n+If there is a merge conflict during this process, `git rebase` will stop at the\n+first problematic commit and leave conflict markers. If this happens, you can do\n+one of these things:\n+\n+1. Resolve the conflict. You can use `git diff` to find the markers (<<<<<<)\n+   and make edits to resolve the conflict. For each file you edit, you need to\n+   tell Git that the conflict has been resolved. You can mark the conflict as\n+   resolved with  `git add <filename>`. After resolving all of the conflicts,\n+   you can continue the rebasing process with\n+\n+   git rebase --continue\n+\n+2. Stop the `git rebase` and return your branch to its original state with\n+\n+   git rebase --abort\n+\n+3. Skip the commit that caused the merge conflict with\n+\n+   git rebase --skip\n+\n+\n If `<branch>` is specified, `git rebase` will perform an automatic\n `git switch <branch>` before doing anything else.  Otherwise\n it remains on the current branch.\n@@ -74,13 +95,6 @@ any commits in `HEAD` which introduce the same textual changes as a commit\n in `HEAD..<upstream>` are omitted (i.e., a patch already accepted upstream\n with a different commit message or timestamp will be skipped).\n \n-It is possible that a merge failure will prevent this process from being\n-completely automatic.  You will have to resolve any such merge failure\n-and run `git rebase --continue`.  Another option is to bypass the commit\n-that caused the merge failure with `git rebase --skip`.  To check out the\n-original `<branch>` and remove the `.git/rebase-apply` working files, use\n-the command `git rebase --abort` instead.\n-\n If the upstream branch already contains a change you have made (e.g.,\n because you mailed a patch which was applied upstream), then that commit\n will be skipped and warnings will be issued (if the 'merge' backend is\n@@ -183,28 +197,6 @@ This is useful if F and G were flawed in some way, or should not be\n part of topicA.  Note that the argument to `--onto` and the `<upstream>`\n parameter can be any valid commit-ish.\n \n-In case of conflict, `git rebase` will stop at the first problematic commit\n-and leave conflict markers in the tree.  You can use `git diff` to locate\n-the markers (<<<<<<) and make edits to resolve the conflict.  For each\n-file you edit, you need to tell Git that the conflict has been resolved,\n-typically this would be done with\n-\n-\n-    git add <filename>\n-\n-\n-After resolving the conflict manually and updating the index with the\n-desired resolution, you can continue the rebasing process with\n-\n-\n-    git rebase --continue\n-\n-\n-Alternatively, you can undo the 'git rebase' with\n-\n-\n-    git rebase --abort\n-\n MODE OPTIONS\n ------------\n \n-- \ngitgitgadget\n\n"},{"id":"523839","messageId":"ce7ab74ea0fc0719d66a53c3a1666be2371adea5.1754680525.git.gitgitgadget@gmail.com","threadId":"63930","inReplyTo":"pull.1949.v2.git.1754680525.gitgitgadget@gmail.com","subject":"[PATCH v2 3/5] doc: git rebase: clarify arguments syntax","fromName":"Julia Evans via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-08-08T19:15:23Z","receivedAt":"2025-08-08T19:15:31Z","isPatch":true,"sender":{"key":"julia@jvns.ca","avatar":"https://avatars.githubusercontent.com/u/817739?v=4"},"body":"From: Julia Evans <julia@jvns.ca>\n\nThis removes the explanation of `git rebase <upstream> <branch>`, since\nit was already explained above that it's shorthand for `git switch\n<branch> && git rebase <upstream>`\n\nSigned-off-by: Julia Evans <julia@jvns.ca>\n---\n Documentation/git-rebase.adoc | 7 +------\n 1 file changed, 1 insertion(+), 6 deletions(-)\n\ndiff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc\nindex a93c616f38b1..e700b92e35ac 100644\n--- a/Documentation/git-rebase.adoc\n+++ b/Documentation/git-rebase.adoc\n@@ -59,12 +59,7 @@ one of these things:\n \n    git rebase --skip\n \n-\n-If `<branch>` is specified, `git rebase` will perform an automatic\n-`git switch <branch>` before doing anything else.  Otherwise\n-it remains on the current branch.\n-\n-If `<upstream>` is not specified, the upstream configured in\n+If you don't specify an `<upstream>` to rebase onto, the upstream configured in\n `branch.<name>.remote` and `branch.<name>.merge` options will be used (see\n linkgit:git-config[1] for details) and the `--fork-point` option is\n assumed.  If you are currently not on any branch or if the current\n-- \ngitgitgadget\n\n"},{"id":"523840","messageId":"590d7486d3d5d6bf4e9542743b21727da690dd50.1754680525.git.gitgitgadget@gmail.com","threadId":"63930","inReplyTo":"pull.1949.v2.git.1754680525.gitgitgadget@gmail.com","subject":"[PATCH v2 4/5] doc: git-rebase: move --onto explanation down","fromName":"Julia Evans via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-08-08T19:15:24Z","receivedAt":"2025-08-08T19:15:33Z","isPatch":true,"sender":{"key":"julia@jvns.ca","avatar":"https://avatars.githubusercontent.com/u/817739?v=4"},"body":"From: Julia Evans <julia@jvns.ca>\n\nThere's a very clear explanation with examples of using --onto which is\ncurrently buried in the very long DESCRIPTION section. This moves it to\nits own section, so that we can reference the explanation from the\n`--onto` option by name.\n\nSigned-off-by: Julia Evans <julia@jvns.ca>\n---\n Documentation/git-rebase.adoc | 168 ++++++++++++++++++----------------\n 1 file changed, 87 insertions(+), 81 deletions(-)\n\ndiff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc\nindex e700b92e35ac..6a4b3dbd5960 100644\n--- a/Documentation/git-rebase.adoc\n+++ b/Documentation/git-rebase.adoc\n@@ -111,87 +111,6 @@ will result in:\n     D---E---A'---F master\n ------------\n \n-Here is how you would transplant a topic branch based on one\n-branch to another, to pretend that you forked the topic branch\n-from the latter branch, using `rebase --onto`.\n-\n-First let's assume your 'topic' is based on branch 'next'.\n-For example, a feature developed in 'topic' depends on some\n-functionality which is found in 'next'.\n-\n-------------\n-    o---o---o---o---o  master\n-         \\\n-          o---o---o---o---o  next\n-                           \\\n-                            o---o---o  topic\n-------------\n-\n-We want to make 'topic' forked from branch 'master'; for example,\n-because the functionality on which 'topic' depends was merged into the\n-more stable 'master' branch. We want our tree to look like this:\n-\n-------------\n-    o---o---o---o---o  master\n-        |            \\\n-        |             o'--o'--o'  topic\n-         \\\n-          o---o---o---o---o  next\n-------------\n-\n-We can get this using the following command:\n-\n-    git rebase --onto master next topic\n-\n-\n-Another example of --onto option is to rebase part of a\n-branch.  If we have the following situation:\n-\n-------------\n-                            H---I---J topicB\n-                           /\n-                  E---F---G  topicA\n-                 /\n-    A---B---C---D  master\n-------------\n-\n-then the command\n-\n-    git rebase --onto master topicA topicB\n-\n-would result in:\n-\n-------------\n-                 H'--I'--J'  topicB\n-                /\n-                | E---F---G  topicA\n-                |/\n-    A---B---C---D  master\n-------------\n-\n-This is useful when topicB does not depend on topicA.\n-\n-A range of commits could also be removed with rebase.  If we have\n-the following situation:\n-\n-------------\n-    E---F---G---H---I---J  topicA\n-------------\n-\n-then the command\n-\n-    git rebase --onto topicA~5 topicA~3 topicA\n-\n-would result in the removal of commits F and G:\n-\n-------------\n-    E---H'---I'---J'  topicA\n-------------\n-\n-This is useful if F and G were flawed in some way, or should not be\n-part of topicA.  Note that the argument to `--onto` and the `<upstream>`\n-parameter can be any valid commit-ish.\n-\n MODE OPTIONS\n ------------\n \n@@ -237,6 +156,8 @@ As a special case, you may use \"A\\...B\" as a shortcut for the\n merge base of A and B if there is exactly one merge base. You can\n leave out at most one of A and B, in which case it defaults to HEAD.\n \n+See TRANSPLANTING A TOPIC BRANCH WITH --ONTO below for examples.\n+\n --keep-base::\n \tSet the starting point at which to create the new commits to the\n \tmerge base of `<upstream>` and `<branch>`. Running\n@@ -1015,6 +936,91 @@ consistent (they compile, pass the testsuite, etc.) you should use\n after each commit, test, and amend the commit if fixes are necessary.\n \n \n+TRANSPLANTING A TOPIC BRANCH WITH --ONTO\n+----------------------------------------\n+\n+Here is how you would transplant a topic branch based on one\n+branch to another, to pretend that you forked the topic branch\n+from the latter branch, using `rebase --onto`.\n+\n+First let's assume your 'topic' is based on branch 'next'.\n+For example, a feature developed in 'topic' depends on some\n+functionality which is found in 'next'.\n+\n+------------\n+    o---o---o---o---o  master\n+         \\\n+          o---o---o---o---o  next\n+                           \\\n+                            o---o---o  topic\n+------------\n+\n+We want to make 'topic' forked from branch 'master'; for example,\n+because the functionality on which 'topic' depends was merged into the\n+more stable 'master' branch. We want our tree to look like this:\n+\n+------------\n+    o---o---o---o---o  master\n+        |            \\\n+        |             o'--o'--o'  topic\n+         \\\n+          o---o---o---o---o  next\n+------------\n+\n+We can get this using the following command:\n+\n+    git rebase --onto master next topic\n+\n+\n+Another example of --onto option is to rebase part of a\n+branch.  If we have the following situation:\n+\n+------------\n+                            H---I---J topicB\n+                           /\n+                  E---F---G  topicA\n+                 /\n+    A---B---C---D  master\n+------------\n+\n+then the command\n+\n+    git rebase --onto master topicA topicB\n+\n+would result in:\n+\n+------------\n+                 H'--I'--J'  topicB\n+                /\n+                | E---F---G  topicA\n+                |/\n+    A---B---C---D  master\n+------------\n+\n+This is useful when topicB does not depend on topicA.\n+\n+A range of commits could also be removed with rebase.  If we have\n+the following situation:\n+\n+------------\n+    E---F---G---H---I---J  topicA\n+------------\n+\n+then the command\n+\n+    git rebase --onto topicA~5 topicA~3 topicA\n+\n+would result in the removal of commits F and G:\n+\n+------------\n+    E---H'---I'---J'  topicA\n+------------\n+\n+This is useful if F and G were flawed in some way, or should not be\n+part of topicA.  Note that the argument to `--onto` and the `<upstream>`\n+parameter can be any valid commit-ish.\n+\n+\n RECOVERING FROM UPSTREAM REBASE\n -------------------------------\n \n-- \ngitgitgadget\n\n"},{"id":"523841","messageId":"ad97cd9e6718be2540657c2c820f29b9efafa883.1754680525.git.gitgitgadget@gmail.com","threadId":"63930","inReplyTo":"pull.1949.v2.git.1754680525.gitgitgadget@gmail.com","subject":"[PATCH v2 5/5] doc: git-rebase: update discussion of internals","fromName":"Julia Evans via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-08-08T19:15:25Z","receivedAt":"2025-08-08T19:15:33Z","isPatch":true,"sender":{"key":"julia@jvns.ca","avatar":"https://avatars.githubusercontent.com/u/817739?v=4"},"body":"From: Julia Evans <julia@jvns.ca>\n\n- make it clearer that we're talking about three steps of a process\n- delete a duplicate explanation of how git rebase skips commits with\n  the same textual changes (it's explained in more detail a few lines\n  further down)\n- move the `ORIG_HEAD` note down so that it doesn't interrupt the\n  discussion of the mechanics.\n\nSigned-off-by: Julia Evans <julia@jvns.ca>\n---\n Documentation/git-rebase.adoc | 15 +++++++--------\n 1 file changed, 7 insertions(+), 8 deletions(-)\n\ndiff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc\nindex 6a4b3dbd5960..5a49e4f2de9a 100644\n--- a/Documentation/git-rebase.adoc\n+++ b/Documentation/git-rebase.adoc\n@@ -65,18 +65,23 @@ linkgit:git-config[1] for details) and the `--fork-point` option is\n assumed.  If you are currently not on any branch or if the current\n branch does not have a configured upstream, the rebase will abort.\n \n-All changes made by commits in the current branch but that are not\n+Here is a more detailed description of what `git rebase <upstream>` does:\n+\n+First, all changes made by commits in the current branch but that are not\n in `<upstream>` are saved to a temporary area.  This is the same set\n of commits that would be shown by `git log <upstream>..HEAD`; or by\n `git log 'fork_point'..HEAD`, if `--fork-point` is active (see the\n description on `--fork-point` below); or by `git log HEAD`, if the\n `--root` option is specified.\n \n-The current branch is reset to `<upstream>` or `<newbase>` if the\n+Then the current branch is reset to `<upstream>` or `<newbase>` if the\n `--onto` option was supplied.  This has the exact same effect as\n `git reset --hard <upstream>` (or `<newbase>`). `ORIG_HEAD` is set\n to point at the tip of the branch before the reset.\n \n+Then the commits that were previously saved into the temporary area are\n+reapplied to the current branch, one by one, in order.\n+\n [NOTE]\n `ORIG_HEAD` is not guaranteed to still point to the previous branch tip\n at the end of the rebase if other commands that write that pseudo-ref\n@@ -84,12 +89,6 @@ at the end of the rebase if other commands that write that pseudo-ref\n however, is accessible using the reflog of the current branch\n (i.e. `@{1}`, see linkgit:gitrevisions[7]).\n \n-The commits that were previously saved into the temporary area are\n-then reapplied to the current branch, one by one, in order. Note that\n-any commits in `HEAD` which introduce the same textual changes as a commit\n-in `HEAD..<upstream>` are omitted (i.e., a patch already accepted upstream\n-with a different commit message or timestamp will be skipped).\n-\n If the upstream branch already contains a change you have made (e.g.,\n because you mailed a patch which was applied upstream), then that commit\n will be skipped and warnings will be issued (if the 'merge' backend is\n-- \ngitgitgadget\n"},{"id":"523844","messageId":"xmqqwm7dfrlt.fsf@gitster.g","threadId":"63930","inReplyTo":"ce7ab74ea0fc0719d66a53c3a1666be2371adea5.1754680525.git.gitgitgadget@gmail.com","subject":"Re: [PATCH v2 3/5] doc: git rebase: clarify arguments syntax","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2025-08-08T21:09:18Z","receivedAt":"2025-08-08T21:09:20Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Julia Evans via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n\n> From: Julia Evans <julia@jvns.ca>\n>\n> This removes the explanation of `git rebase <upstream> <branch>`, since\n> it was already explained above that it's shorthand for `git switch\n> <branch> && git rebase <upstream>`\n\nWe usually do not say \"This [commit] does X\".  In this particular\ncase, since the objective is so obvious, we do not necessarily have\nto follow the whole \"summarize the current state, explain why it is\nproblematic, and then tell somebody sitting in front of a keyboard\nto change the code in this and that way to make it improve\" 9 yards;\njust tweaking it into\n\n\tRemove the redundant explanation of `git ...`, since it was\n\talready explained earlier.\n\nwould be sufficient.\n\nAlthough the proposed log message does not mention it, I actually\nlike the other change in this patch, that rephrases the \"if you\ndon't specify...\", even better.  The addtional \"to rebase onto\" does\nmake the description clearer.\n\nThanks.\n\n> Signed-off-by: Julia Evans <julia@jvns.ca>\n> ---\n>  Documentation/git-rebase.adoc | 7 +------\n>  1 file changed, 1 insertion(+), 6 deletions(-)\n>\n> diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc\n> index a93c616f38b1..e700b92e35ac 100644\n> --- a/Documentation/git-rebase.adoc\n> +++ b/Documentation/git-rebase.adoc\n> @@ -59,12 +59,7 @@ one of these things:\n>  \n>     git rebase --skip\n>  \n> -\n> -If `<branch>` is specified, `git rebase` will perform an automatic\n> -`git switch <branch>` before doing anything else.  Otherwise\n> -it remains on the current branch.\n> -\n> -If `<upstream>` is not specified, the upstream configured in\n> +If you don't specify an `<upstream>` to rebase onto, the upstream configured in\n>  `branch.<name>.remote` and `branch.<name>.merge` options will be used (see\n>  linkgit:git-config[1] for details) and the `--fork-point` option is\n>  assumed.  If you are currently not on any branch or if the current\n"},{"id":"523846","messageId":"xmqqbjopfpiy.fsf@gitster.g","threadId":"63930","inReplyTo":"ad97cd9e6718be2540657c2c820f29b9efafa883.1754680525.git.gitgitgadget@gmail.com","subject":"Re: [PATCH v2 5/5] doc: git-rebase: update discussion of internals","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2025-08-08T21:54:13Z","receivedAt":"2025-08-08T21:54:16Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Julia Evans via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n\n> From: Julia Evans <julia@jvns.ca>\n>\n> - make it clearer that we're talking about three steps of a process\n\nA good call.  \"First, then, then\" does make it clear where each new\nstep begins.  \"First, then, finally\" would make it even more obvious\nwhich step concludes the sequence, though.\n\n> - delete a duplicate explanation of how git rebase skips commits with\n>   the same textual changes (it's explained in more detail a few lines\n>   further down)\n\nOK.\n\n> - move the `ORIG_HEAD` note down so that it doesn't interrupt the\n>   discussion of the mechanics.\n\nI thought you moved the \"finally we reapply\" up, instead of moving\nthe note down ;-) And when viewed that way, a more direct way to\njustify this change is that you made sure these three steps are kept\ntogether.\n\nAgain, good change.\n\n> -All changes made by commits in the current branch but that are not\n> +Here is a more detailed description of what `git rebase <upstream>` does:\n> +\n> +First, all changes made by commits in the current branch but that are not\n>  in `<upstream>` are saved to a temporary area.  This is the same set\n>  of commits that would be shown by `git log <upstream>..HEAD`; or by\n>  `git log 'fork_point'..HEAD`, if `--fork-point` is active (see the\n>  description on `--fork-point` below); or by `git log HEAD`, if the\n>  `--root` option is specified.\n\nIf we are ambitious, we may want to rewrite this first step to put\nalmost no stress on \"saving\" and \"temporary area\".  Especially when\nyou rebase with merge backend, it would be morally a sequence of\ncherry-pick, without us having to save anything---we only need to\nfigure out which commits to replay in what order.\n\n    First, the command figures out changes from which commits to\n    replay in what order.  The set of commits are those shown by\n    `git log <base>..HEAD`, where <base> is the <upstream> if given,\n    or computed fork-point if the `--fork-point` option is active,\n    or all commits that lead to `HEAD` if `--root` is given.\n\n\n> -The current branch is reset to `<upstream>` or `<newbase>` if the\n> +Then the current branch is reset to `<upstream>` or `<newbase>` if the\n>  `--onto` option was supplied.  This has the exact same effect as\n>  `git reset --hard <upstream>` (or `<newbase>`). `ORIG_HEAD` is set\n>  to point at the tip of the branch before the reset.\n\n\"This has the exact same effect as\" made my reading hiccup.\n\n    Then `git reset --hard` rewinds the current branch to the commit\n    given by `--onto`, if specified, or to `<upstream>`.\n\nI am not sure if it is worth talking about ORIG_HEAD at this point,\nas that is part of what `git reset --hard` does with this step.\nGiven especially that we have NOTE that says ORIG_HEAD cannot be\nrelied upon once the replaying of commits begin, mentioning the\nvalue of ORIG_HEAD before the replaying begins does not seem to add\nmuch value to the explanation.\n\n> +Then the commits that were previously saved into the temporary area are\n> +reapplied to the current branch, one by one, in order.\n\nYup.  As I suggested, \"Then\" -> \"Finally\".\n\nI do not know how much detail we want to give to readers, and I do\nto prefer to tell some white lie in end-user facing documentation if\nsimplified description helps the initial understanding, so I am not\nyet decided if I recommend rewriting these \"three step\" explanation,\nbut FYI, the modern rebase machinery works slightly differently:\n\n    First the command figures out what to replay, on which commit,\n    and in what order.\n\n    Then the HEAD is detached (\"git checkout --detach <onto>\") to\n    the commit the first change is replayed onto.\n\n    Then the changes are replayed, one by one, in the order.\n    Optionally a mergy history can be rebased while retaining\n    the topology.\n\n    Finally, the branch being rebased is made to point at the\n    resulting HEAD (i.e. equivalent to \"git checkout -B <branch>\"\n    to jump back from the detached HEAD state).\n\nThe difference between the simplified procedure and this \"replaying\nis done while on detached HEAD\" procedure gives us a somewhat big\nusability improvement, as a rebasing will be recorded in a single\nreflog event for the branch getting rebased, no matter how many\ncommits are on the branch.\n"},{"id":"523848","messageId":"pull.1949.v3.git.1754693552.gitgitgadget@gmail.com","threadId":"63930","inReplyTo":"pull.1949.v2.git.1754680525.gitgitgadget@gmail.com","subject":"[PATCH v3 0/5] doc: git-rebase: clarify DESCRIPTION section","fromName":"Julia Evans via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-08-08T22:52:27Z","receivedAt":"2025-08-08T22:52:36Z","isPatch":true,"sender":{"key":"julia@jvns.ca","avatar":"https://avatars.githubusercontent.com/u/817739?v=4"},"body":"I liked the idea of trying a more ambitious rewrite of the \"here's how git\nrebase works internally\" section, so here's an attempt at it.\n\nMy idea is to give an accurate technical description of how the merge\nbackend works while deferring some of the details (like how exactly\n--fork-point works or what happens when you rebase a merge) to later in the\nman page. I've also tried to use a minimum of git jargon, for example saying\n\"Then it checks out <upstream>\" instead of mentioning anything about a\n\"detached HEAD\" since I know that term can jarring for folks who aren't used\nto that term.\n\nI hedged a bit by saying that rebase is \"similar to\" running git cherry-pick\nrepeatedly since I think of a rebase as being like doing a bunch of\ncherry-picks (and very often hear people describing it that way), but I'm\nsure that there are differences that I'm not aware of.\n\nI've also updated the \"clarify arguments syntax\" commit message.\n\nJulia Evans (5):\n  doc: git-rebase: start with an example\n  doc: git rebase: dedup merge conflict discussion\n  doc: git rebase: clarify arguments syntax\n  doc: git-rebase: move --onto explanation down\n  doc: git-rebase: update discussion of internals\n\n Documentation/git-rebase.adoc | 300 ++++++++++++++++------------------\n 1 file changed, 145 insertions(+), 155 deletions(-)\n\n\nbase-commit: 2c2ba49d55ff26c1082b8137b1ec5eeccb4337d1\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-1949%2Fjvns%2Fclarify-rebase-v3\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1949/jvns/clarify-rebase-v3\nPull-Request: https://github.com/gitgitgadget/git/pull/1949\n\nRange-diff vs v2:\n\n 1:  26b742eb49f = 1:  26b742eb49f doc: git-rebase: start with an example\n 2:  249a5127904 = 2:  249a5127904 doc: git rebase: dedup merge conflict discussion\n 3:  ce7ab74ea0f ! 3:  013a5044ef3 doc: git rebase: clarify arguments syntax\n     @@ Metadata\n       ## Commit message ##\n          doc: git rebase: clarify arguments syntax\n      \n     -    This removes the explanation of `git rebase <upstream> <branch>`, since\n     -    it was already explained above that it's shorthand for `git switch\n     -    <branch> && git rebase <upstream>`\n     +    Remove duplicate explanation of `git rebase <upstream> <branch>` which\n     +    is already explained above.\n      \n          Signed-off-by: Julia Evans <julia@jvns.ca>\n      \n 4:  590d7486d3d = 4:  c574a27412d doc: git-rebase: move --onto explanation down\n 5:  ad97cd9e671 ! 5:  eabacd3c159 doc: git-rebase: update discussion of internals\n     @@ Metadata\n       ## Commit message ##\n          doc: git-rebase: update discussion of internals\n      \n     -    - make it clearer that we're talking about three steps of a process\n     +    - make it clearer that we're talking about a multistep process\n     +    - give a more technically accurate description how rebase works with the\n     +      merge backend.\n          - delete a duplicate explanation of how git rebase skips commits with\n            the same textual changes (it's explained in more detail a few lines\n            further down)\n     -    - move the `ORIG_HEAD` note down so that it doesn't interrupt the\n     -      discussion of the mechanics.\n     +    - remove the explanation of how exactly `--fork-point` and `--root`\n     +      work since that information is in the OPTIONS section\n     +    - put all discussion of `ORIG_HEAD` inside the note\n      \n          Signed-off-by: Julia Evans <julia@jvns.ca>\n      \n     @@ Documentation/git-rebase.adoc: linkgit:git-config[1] for details) and the `--for\n       branch does not have a configured upstream, the rebase will abort.\n       \n      -All changes made by commits in the current branch but that are not\n     +-in `<upstream>` are saved to a temporary area.  This is the same set\n     +-of commits that would be shown by `git log <upstream>..HEAD`; or by\n     +-`git log 'fork_point'..HEAD`, if `--fork-point` is active (see the\n     +-description on `--fork-point` below); or by `git log HEAD`, if the\n     +-`--root` option is specified.\n     +-\n     +-The current branch is reset to `<upstream>` or `<newbase>` if the\n     +-`--onto` option was supplied.  This has the exact same effect as\n     +-`git reset --hard <upstream>` (or `<newbase>`). `ORIG_HEAD` is set\n     +-to point at the tip of the branch before the reset.\n      +Here is a more detailed description of what `git rebase <upstream>` does:\n      +\n     -+First, all changes made by commits in the current branch but that are not\n     - in `<upstream>` are saved to a temporary area.  This is the same set\n     - of commits that would be shown by `git log <upstream>..HEAD`; or by\n     - `git log 'fork_point'..HEAD`, if `--fork-point` is active (see the\n     - description on `--fork-point` below); or by `git log HEAD`, if the\n     - `--root` option is specified.\n     - \n     --The current branch is reset to `<upstream>` or `<newbase>` if the\n     -+Then the current branch is reset to `<upstream>` or `<newbase>` if the\n     - `--onto` option was supplied.  This has the exact same effect as\n     - `git reset --hard <upstream>` (or `<newbase>`). `ORIG_HEAD` is set\n     - to point at the tip of the branch before the reset.\n     - \n     -+Then the commits that were previously saved into the temporary area are\n     -+reapplied to the current branch, one by one, in order.\n     ++First, it makes a list of all commits in the current branch that are not in\n     ++`<upstream>`. This is the same set of commits that would be shown by `git log\n     ++<upstream>..HEAD`. You can use `--fork-point` or `--root` to change how this\n     ++list of commits is constructed.\n     ++\n     ++Then it checks out `<upstream>` (or `<newbase>` if the `--onto` option was\n     ++supplied) with the equivalent of `git switch --detach <upstream>`.\n      +\n     ++Then it replays the commits, one by one, in order. This is similar to running\n     ++`git cherry-pick <commit>` for each commit. See REBASING MERGES for how merges\n     ++are handled.\n     ++\n     ++Finally, it updates your branch to point to the final commit with the equivalent\n     ++of `git switch -C <branch>`.\n     + \n       [NOTE]\n     ++`ORIG_HEAD` is set to point at the tip of the branch before the rebase.\n       `ORIG_HEAD` is not guaranteed to still point to the previous branch tip\n       at the end of the rebase if other commands that write that pseudo-ref\n     -@@ Documentation/git-rebase.adoc: at the end of the rebase if other commands that write that pseudo-ref\n     + (e.g. `git reset`) are used during the rebase. The previous branch tip,\n       however, is accessible using the reflog of the current branch\n       (i.e. `@{1}`, see linkgit:gitrevisions[7]).\n       \n\n-- \ngitgitgadget\n"},{"id":"523849","messageId":"26b742eb49f935147ac373bf9435827a6f85e531.1754693552.git.gitgitgadget@gmail.com","threadId":"63930","inReplyTo":"pull.1949.v3.git.1754693552.gitgitgadget@gmail.com","subject":"[PATCH v3 1/5] doc: git-rebase: start with an example","fromName":"Julia Evans via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-08-08T22:52:28Z","receivedAt":"2025-08-08T22:52:36Z","isPatch":true,"sender":{"key":"julia@jvns.ca","avatar":"https://avatars.githubusercontent.com/u/817739?v=4"},"body":"From: Julia Evans <julia@jvns.ca>\n\nStart with an example that mirrors the example in the `git-merge` man\npage, to make it easier for folks to understand the difference between a\nrebase and a merge.\n\nSigned-off-by: Julia Evans <julia@jvns.ca>\n---\n Documentation/git-rebase.adoc | 49 ++++++++++++++++-------------------\n 1 file changed, 23 insertions(+), 26 deletions(-)\n\ndiff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc\nindex 956d3048f5a6..6dacf693bd71 100644\n--- a/Documentation/git-rebase.adoc\n+++ b/Documentation/git-rebase.adoc\n@@ -16,6 +16,29 @@ SYNOPSIS\n \n DESCRIPTION\n -----------\n+Transplant a series of commits onto a different starting point.\n+\n+For example, imagine that you have been working on the `topic` branch in this\n+history, and you want to \"catch up\" to the work done on the `master` branch.\n+\n+------------\n+          A---B---C topic\n+         /\n+    D---E---F---G master\n+------------\n+\n+You want to transplant the commits you made on `topic` since it diverged from\n+`master` (i.e. A, B, and C), on top of the current `master`.  You can do this\n+by running `git rebase master` while the `topic` branch is checked out.  If you\n+want to rebase `topic` while on another branch, `git rebase master topic` is a\n+short-cut for `git switch topic && git rebase master`.\n+\n+------------\n+                  A'--B'--C' topic\n+                 /\n+    D---E---F---G master\n+------------\n+\n If `<branch>` is specified, `git rebase` will perform an automatic\n `git switch <branch>` before doing anything else.  Otherwise\n it remains on the current branch.\n@@ -58,32 +81,6 @@ that caused the merge failure with `git rebase --skip`.  To check out the\n original `<branch>` and remove the `.git/rebase-apply` working files, use\n the command `git rebase --abort` instead.\n \n-Assume the following history exists and the current branch is \"topic\":\n-\n-------------\n-          A---B---C topic\n-         /\n-    D---E---F---G master\n-------------\n-\n-From this point, the result of either of the following commands:\n-\n-\n-    git rebase master\n-    git rebase master topic\n-\n-would be:\n-\n-------------\n-                  A'--B'--C' topic\n-                 /\n-    D---E---F---G master\n-------------\n-\n-*NOTE:* The latter form is just a short-hand of `git checkout topic`\n-followed by `git rebase master`. When rebase exits `topic` will\n-remain the checked-out branch.\n-\n If the upstream branch already contains a change you have made (e.g.,\n because you mailed a patch which was applied upstream), then that commit\n will be skipped and warnings will be issued (if the 'merge' backend is\n-- \ngitgitgadget\n\n"},{"id":"523850","messageId":"249a5127904f2d73119f3b60d70a57fe84d1b4ad.1754693552.git.gitgitgadget@gmail.com","threadId":"63930","inReplyTo":"pull.1949.v3.git.1754693552.gitgitgadget@gmail.com","subject":"[PATCH v3 2/5] doc: git rebase: dedup merge conflict discussion","fromName":"Julia Evans via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-08-08T22:52:29Z","receivedAt":"2025-08-08T22:52:37Z","isPatch":true,"sender":{"key":"julia@jvns.ca","avatar":"https://avatars.githubusercontent.com/u/817739?v=4"},"body":"From: Julia Evans <julia@jvns.ca>\n\nPreviously there were two explanations, this combines them both into a\nsingle explanation.\n\nSigned-off-by: Julia Evans <julia@jvns.ca>\n---\n Documentation/git-rebase.adoc | 50 +++++++++++++++--------------------\n 1 file changed, 21 insertions(+), 29 deletions(-)\n\ndiff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc\nindex 6dacf693bd71..a93c616f38b1 100644\n--- a/Documentation/git-rebase.adoc\n+++ b/Documentation/git-rebase.adoc\n@@ -39,6 +39,27 @@ short-cut for `git switch topic && git rebase master`.\n     D---E---F---G master\n ------------\n \n+If there is a merge conflict during this process, `git rebase` will stop at the\n+first problematic commit and leave conflict markers. If this happens, you can do\n+one of these things:\n+\n+1. Resolve the conflict. You can use `git diff` to find the markers (<<<<<<)\n+   and make edits to resolve the conflict. For each file you edit, you need to\n+   tell Git that the conflict has been resolved. You can mark the conflict as\n+   resolved with  `git add <filename>`. After resolving all of the conflicts,\n+   you can continue the rebasing process with\n+\n+   git rebase --continue\n+\n+2. Stop the `git rebase` and return your branch to its original state with\n+\n+   git rebase --abort\n+\n+3. Skip the commit that caused the merge conflict with\n+\n+   git rebase --skip\n+\n+\n If `<branch>` is specified, `git rebase` will perform an automatic\n `git switch <branch>` before doing anything else.  Otherwise\n it remains on the current branch.\n@@ -74,13 +95,6 @@ any commits in `HEAD` which introduce the same textual changes as a commit\n in `HEAD..<upstream>` are omitted (i.e., a patch already accepted upstream\n with a different commit message or timestamp will be skipped).\n \n-It is possible that a merge failure will prevent this process from being\n-completely automatic.  You will have to resolve any such merge failure\n-and run `git rebase --continue`.  Another option is to bypass the commit\n-that caused the merge failure with `git rebase --skip`.  To check out the\n-original `<branch>` and remove the `.git/rebase-apply` working files, use\n-the command `git rebase --abort` instead.\n-\n If the upstream branch already contains a change you have made (e.g.,\n because you mailed a patch which was applied upstream), then that commit\n will be skipped and warnings will be issued (if the 'merge' backend is\n@@ -183,28 +197,6 @@ This is useful if F and G were flawed in some way, or should not be\n part of topicA.  Note that the argument to `--onto` and the `<upstream>`\n parameter can be any valid commit-ish.\n \n-In case of conflict, `git rebase` will stop at the first problematic commit\n-and leave conflict markers in the tree.  You can use `git diff` to locate\n-the markers (<<<<<<) and make edits to resolve the conflict.  For each\n-file you edit, you need to tell Git that the conflict has been resolved,\n-typically this would be done with\n-\n-\n-    git add <filename>\n-\n-\n-After resolving the conflict manually and updating the index with the\n-desired resolution, you can continue the rebasing process with\n-\n-\n-    git rebase --continue\n-\n-\n-Alternatively, you can undo the 'git rebase' with\n-\n-\n-    git rebase --abort\n-\n MODE OPTIONS\n ------------\n \n-- \ngitgitgadget\n\n"},{"id":"523851","messageId":"013a5044ef3dcbeaed0e819f21f62a7e398e35d6.1754693552.git.gitgitgadget@gmail.com","threadId":"63930","inReplyTo":"pull.1949.v3.git.1754693552.gitgitgadget@gmail.com","subject":"[PATCH v3 3/5] doc: git rebase: clarify arguments syntax","fromName":"Julia Evans via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-08-08T22:52:30Z","receivedAt":"2025-08-08T22:52:38Z","isPatch":true,"sender":{"key":"julia@jvns.ca","avatar":"https://avatars.githubusercontent.com/u/817739?v=4"},"body":"From: Julia Evans <julia@jvns.ca>\n\nRemove duplicate explanation of `git rebase <upstream> <branch>` which\nis already explained above.\n\nSigned-off-by: Julia Evans <julia@jvns.ca>\n---\n Documentation/git-rebase.adoc | 7 +------\n 1 file changed, 1 insertion(+), 6 deletions(-)\n\ndiff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc\nindex a93c616f38b1..e700b92e35ac 100644\n--- a/Documentation/git-rebase.adoc\n+++ b/Documentation/git-rebase.adoc\n@@ -59,12 +59,7 @@ one of these things:\n \n    git rebase --skip\n \n-\n-If `<branch>` is specified, `git rebase` will perform an automatic\n-`git switch <branch>` before doing anything else.  Otherwise\n-it remains on the current branch.\n-\n-If `<upstream>` is not specified, the upstream configured in\n+If you don't specify an `<upstream>` to rebase onto, the upstream configured in\n `branch.<name>.remote` and `branch.<name>.merge` options will be used (see\n linkgit:git-config[1] for details) and the `--fork-point` option is\n assumed.  If you are currently not on any branch or if the current\n-- \ngitgitgadget\n\n"},{"id":"523852","messageId":"c574a27412d343029213ca8688d3794a8176e0eb.1754693552.git.gitgitgadget@gmail.com","threadId":"63930","inReplyTo":"pull.1949.v3.git.1754693552.gitgitgadget@gmail.com","subject":"[PATCH v3 4/5] doc: git-rebase: move --onto explanation down","fromName":"Julia Evans via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-08-08T22:52:31Z","receivedAt":"2025-08-08T22:52:39Z","isPatch":true,"sender":{"key":"julia@jvns.ca","avatar":"https://avatars.githubusercontent.com/u/817739?v=4"},"body":"From: Julia Evans <julia@jvns.ca>\n\nThere's a very clear explanation with examples of using --onto which is\ncurrently buried in the very long DESCRIPTION section. This moves it to\nits own section, so that we can reference the explanation from the\n`--onto` option by name.\n\nSigned-off-by: Julia Evans <julia@jvns.ca>\n---\n Documentation/git-rebase.adoc | 168 ++++++++++++++++++----------------\n 1 file changed, 87 insertions(+), 81 deletions(-)\n\ndiff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc\nindex e700b92e35ac..6a4b3dbd5960 100644\n--- a/Documentation/git-rebase.adoc\n+++ b/Documentation/git-rebase.adoc\n@@ -111,87 +111,6 @@ will result in:\n     D---E---A'---F master\n ------------\n \n-Here is how you would transplant a topic branch based on one\n-branch to another, to pretend that you forked the topic branch\n-from the latter branch, using `rebase --onto`.\n-\n-First let's assume your 'topic' is based on branch 'next'.\n-For example, a feature developed in 'topic' depends on some\n-functionality which is found in 'next'.\n-\n-------------\n-    o---o---o---o---o  master\n-         \\\n-          o---o---o---o---o  next\n-                           \\\n-                            o---o---o  topic\n-------------\n-\n-We want to make 'topic' forked from branch 'master'; for example,\n-because the functionality on which 'topic' depends was merged into the\n-more stable 'master' branch. We want our tree to look like this:\n-\n-------------\n-    o---o---o---o---o  master\n-        |            \\\n-        |             o'--o'--o'  topic\n-         \\\n-          o---o---o---o---o  next\n-------------\n-\n-We can get this using the following command:\n-\n-    git rebase --onto master next topic\n-\n-\n-Another example of --onto option is to rebase part of a\n-branch.  If we have the following situation:\n-\n-------------\n-                            H---I---J topicB\n-                           /\n-                  E---F---G  topicA\n-                 /\n-    A---B---C---D  master\n-------------\n-\n-then the command\n-\n-    git rebase --onto master topicA topicB\n-\n-would result in:\n-\n-------------\n-                 H'--I'--J'  topicB\n-                /\n-                | E---F---G  topicA\n-                |/\n-    A---B---C---D  master\n-------------\n-\n-This is useful when topicB does not depend on topicA.\n-\n-A range of commits could also be removed with rebase.  If we have\n-the following situation:\n-\n-------------\n-    E---F---G---H---I---J  topicA\n-------------\n-\n-then the command\n-\n-    git rebase --onto topicA~5 topicA~3 topicA\n-\n-would result in the removal of commits F and G:\n-\n-------------\n-    E---H'---I'---J'  topicA\n-------------\n-\n-This is useful if F and G were flawed in some way, or should not be\n-part of topicA.  Note that the argument to `--onto` and the `<upstream>`\n-parameter can be any valid commit-ish.\n-\n MODE OPTIONS\n ------------\n \n@@ -237,6 +156,8 @@ As a special case, you may use \"A\\...B\" as a shortcut for the\n merge base of A and B if there is exactly one merge base. You can\n leave out at most one of A and B, in which case it defaults to HEAD.\n \n+See TRANSPLANTING A TOPIC BRANCH WITH --ONTO below for examples.\n+\n --keep-base::\n \tSet the starting point at which to create the new commits to the\n \tmerge base of `<upstream>` and `<branch>`. Running\n@@ -1015,6 +936,91 @@ consistent (they compile, pass the testsuite, etc.) you should use\n after each commit, test, and amend the commit if fixes are necessary.\n \n \n+TRANSPLANTING A TOPIC BRANCH WITH --ONTO\n+----------------------------------------\n+\n+Here is how you would transplant a topic branch based on one\n+branch to another, to pretend that you forked the topic branch\n+from the latter branch, using `rebase --onto`.\n+\n+First let's assume your 'topic' is based on branch 'next'.\n+For example, a feature developed in 'topic' depends on some\n+functionality which is found in 'next'.\n+\n+------------\n+    o---o---o---o---o  master\n+         \\\n+          o---o---o---o---o  next\n+                           \\\n+                            o---o---o  topic\n+------------\n+\n+We want to make 'topic' forked from branch 'master'; for example,\n+because the functionality on which 'topic' depends was merged into the\n+more stable 'master' branch. We want our tree to look like this:\n+\n+------------\n+    o---o---o---o---o  master\n+        |            \\\n+        |             o'--o'--o'  topic\n+         \\\n+          o---o---o---o---o  next\n+------------\n+\n+We can get this using the following command:\n+\n+    git rebase --onto master next topic\n+\n+\n+Another example of --onto option is to rebase part of a\n+branch.  If we have the following situation:\n+\n+------------\n+                            H---I---J topicB\n+                           /\n+                  E---F---G  topicA\n+                 /\n+    A---B---C---D  master\n+------------\n+\n+then the command\n+\n+    git rebase --onto master topicA topicB\n+\n+would result in:\n+\n+------------\n+                 H'--I'--J'  topicB\n+                /\n+                | E---F---G  topicA\n+                |/\n+    A---B---C---D  master\n+------------\n+\n+This is useful when topicB does not depend on topicA.\n+\n+A range of commits could also be removed with rebase.  If we have\n+the following situation:\n+\n+------------\n+    E---F---G---H---I---J  topicA\n+------------\n+\n+then the command\n+\n+    git rebase --onto topicA~5 topicA~3 topicA\n+\n+would result in the removal of commits F and G:\n+\n+------------\n+    E---H'---I'---J'  topicA\n+------------\n+\n+This is useful if F and G were flawed in some way, or should not be\n+part of topicA.  Note that the argument to `--onto` and the `<upstream>`\n+parameter can be any valid commit-ish.\n+\n+\n RECOVERING FROM UPSTREAM REBASE\n -------------------------------\n \n-- \ngitgitgadget\n\n"},{"id":"523853","messageId":"eabacd3c159a9abe656cbb778a53558d471b5165.1754693552.git.gitgitgadget@gmail.com","threadId":"63930","inReplyTo":"pull.1949.v3.git.1754693552.gitgitgadget@gmail.com","subject":"[PATCH v3 5/5] doc: git-rebase: update discussion of internals","fromName":"Julia Evans via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-08-08T22:52:32Z","receivedAt":"2025-08-08T22:52:39Z","isPatch":true,"sender":{"key":"julia@jvns.ca","avatar":"https://avatars.githubusercontent.com/u/817739?v=4"},"body":"From: Julia Evans <julia@jvns.ca>\n\n- make it clearer that we're talking about a multistep process\n- give a more technically accurate description how rebase works with the\n  merge backend.\n- delete a duplicate explanation of how git rebase skips commits with\n  the same textual changes (it's explained in more detail a few lines\n  further down)\n- remove the explanation of how exactly `--fork-point` and `--root`\n  work since that information is in the OPTIONS section\n- put all discussion of `ORIG_HEAD` inside the note\n\nSigned-off-by: Julia Evans <julia@jvns.ca>\n---\n Documentation/git-rebase.adoc | 34 +++++++++++++++++-----------------\n 1 file changed, 17 insertions(+), 17 deletions(-)\n\ndiff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc\nindex 6a4b3dbd5960..df77bbdecfec 100644\n--- a/Documentation/git-rebase.adoc\n+++ b/Documentation/git-rebase.adoc\n@@ -65,31 +65,31 @@ linkgit:git-config[1] for details) and the `--fork-point` option is\n assumed.  If you are currently not on any branch or if the current\n branch does not have a configured upstream, the rebase will abort.\n \n-All changes made by commits in the current branch but that are not\n-in `<upstream>` are saved to a temporary area.  This is the same set\n-of commits that would be shown by `git log <upstream>..HEAD`; or by\n-`git log 'fork_point'..HEAD`, if `--fork-point` is active (see the\n-description on `--fork-point` below); or by `git log HEAD`, if the\n-`--root` option is specified.\n-\n-The current branch is reset to `<upstream>` or `<newbase>` if the\n-`--onto` option was supplied.  This has the exact same effect as\n-`git reset --hard <upstream>` (or `<newbase>`). `ORIG_HEAD` is set\n-to point at the tip of the branch before the reset.\n+Here is a more detailed description of what `git rebase <upstream>` does:\n+\n+First, it makes a list of all commits in the current branch that are not in\n+`<upstream>`. This is the same set of commits that would be shown by `git log\n+<upstream>..HEAD`. You can use `--fork-point` or `--root` to change how this\n+list of commits is constructed.\n+\n+Then it checks out `<upstream>` (or `<newbase>` if the `--onto` option was\n+supplied) with the equivalent of `git switch --detach <upstream>`.\n+\n+Then it replays the commits, one by one, in order. This is similar to running\n+`git cherry-pick <commit>` for each commit. See REBASING MERGES for how merges\n+are handled.\n+\n+Finally, it updates your branch to point to the final commit with the equivalent\n+of `git switch -C <branch>`.\n \n [NOTE]\n+`ORIG_HEAD` is set to point at the tip of the branch before the rebase.\n `ORIG_HEAD` is not guaranteed to still point to the previous branch tip\n at the end of the rebase if other commands that write that pseudo-ref\n (e.g. `git reset`) are used during the rebase. The previous branch tip,\n however, is accessible using the reflog of the current branch\n (i.e. `@{1}`, see linkgit:gitrevisions[7]).\n \n-The commits that were previously saved into the temporary area are\n-then reapplied to the current branch, one by one, in order. Note that\n-any commits in `HEAD` which introduce the same textual changes as a commit\n-in `HEAD..<upstream>` are omitted (i.e., a patch already accepted upstream\n-with a different commit message or timestamp will be skipped).\n-\n If the upstream branch already contains a change you have made (e.g.,\n because you mailed a patch which was applied upstream), then that commit\n will be skipped and warnings will be issued (if the 'merge' backend is\n-- \ngitgitgadget\n"},{"id":"523854","messageId":"xmqqldnte6h3.fsf@gitster.g","threadId":"63930","inReplyTo":"26b742eb49f935147ac373bf9435827a6f85e531.1754680525.git.gitgitgadget@gmail.com","subject":"Re: [PATCH v2 1/5] doc: git-rebase: start with an example","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2025-08-08T23:31:04Z","receivedAt":"2025-08-08T23:31:06Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Julia Evans via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n\n> +Transplant a series of commits onto a different starting point.\n> +\n> +For example, imagine that you have been working on the `topic` branch in this\n> +history, and you want to \"catch up\" to the work done on the `master` branch.\n> +\n> +------------\n> +          A---B---C topic\n> +         /\n> +    D---E---F---G master\n> +------------\n> +\n> +You want to transplant the commits you made on `topic` since it diverged from\n> +`master` (i.e. A, B, and C), on top of the current `master`.  You can do this\n> +by running `git rebase master` while the `topic` branch is checked out.  If you\n> +want to rebase `topic` while on another branch, `git rebase master topic` is a\n> +short-cut for `git switch topic && git rebase master`.\n\ns/switch/checkout/, as that is how the original defines the short-cut.\n\n> +------------\n> +                  A'--B'--C' topic\n> +                 /\n> +    D---E---F---G master\n> +------------\n> +\n\nOther than that, looks great.\n"},{"id":"523855","messageId":"pull.1949.v4.git.1754702057.gitgitgadget@gmail.com","threadId":"63930","inReplyTo":"pull.1949.v3.git.1754693552.gitgitgadget@gmail.com","subject":"[PATCH v4 0/5] doc: git-rebase: clarify DESCRIPTION section","fromName":"Julia Evans via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-08-09T01:14:12Z","receivedAt":"2025-08-09T01:14:21Z","isPatch":true,"sender":{"key":"julia@jvns.ca","avatar":"https://avatars.githubusercontent.com/u/817739?v=4"},"body":"Replaced git switch topic && git rebase master with git checkout topic &&\ngit rebase master\n\nAlso \"short-cut\" with \"shortcut\" which is the spelling used elsewhere in the\nman pages\n\nJulia Evans (5):\n  doc: git-rebase: start with an example\n  doc: git rebase: dedup merge conflict discussion\n  doc: git rebase: clarify arguments syntax\n  doc: git-rebase: move --onto explanation down\n  doc: git-rebase: update discussion of internals\n\n Documentation/git-rebase.adoc | 300 ++++++++++++++++------------------\n 1 file changed, 145 insertions(+), 155 deletions(-)\n\n\nbase-commit: 2c2ba49d55ff26c1082b8137b1ec5eeccb4337d1\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-1949%2Fjvns%2Fclarify-rebase-v4\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1949/jvns/clarify-rebase-v4\nPull-Request: https://github.com/gitgitgadget/git/pull/1949\n\nRange-diff vs v3:\n\n 1:  26b742eb49f ! 1:  07a4bdb7ce5 doc: git-rebase: start with an example\n     @@ Documentation/git-rebase.adoc: SYNOPSIS\n      +`master` (i.e. A, B, and C), on top of the current `master`.  You can do this\n      +by running `git rebase master` while the `topic` branch is checked out.  If you\n      +want to rebase `topic` while on another branch, `git rebase master topic` is a\n     -+short-cut for `git switch topic && git rebase master`.\n     ++shortcut for `git checkout topic && git rebase master`.\n      +\n      +------------\n      +                  A'--B'--C' topic\n 2:  249a5127904 ! 2:  061790686b9 doc: git rebase: dedup merge conflict discussion\n     @@ Commit message\n          Signed-off-by: Julia Evans <julia@jvns.ca>\n      \n       ## Documentation/git-rebase.adoc ##\n     -@@ Documentation/git-rebase.adoc: short-cut for `git switch topic && git rebase master`.\n     +@@ Documentation/git-rebase.adoc: shortcut for `git checkout topic && git rebase master`.\n           D---E---F---G master\n       ------------\n       \n 3:  013a5044ef3 = 3:  fe9e161a51b doc: git rebase: clarify arguments syntax\n 4:  c574a27412d = 4:  b37ebc8389d doc: git-rebase: move --onto explanation down\n 5:  eabacd3c159 = 5:  105a65e6e71 doc: git-rebase: update discussion of internals\n\n-- \ngitgitgadget\n"},{"id":"523856","messageId":"07a4bdb7ce5eb456bd81972c350d0c4f298ebd46.1754702057.git.gitgitgadget@gmail.com","threadId":"63930","inReplyTo":"pull.1949.v4.git.1754702057.gitgitgadget@gmail.com","subject":"[PATCH v4 1/5] doc: git-rebase: start with an example","fromName":"Julia Evans via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-08-09T01:14:13Z","receivedAt":"2025-08-09T01:14:22Z","isPatch":true,"sender":{"key":"julia@jvns.ca","avatar":"https://avatars.githubusercontent.com/u/817739?v=4"},"body":"From: Julia Evans <julia@jvns.ca>\n\nStart with an example that mirrors the example in the `git-merge` man\npage, to make it easier for folks to understand the difference between a\nrebase and a merge.\n\nSigned-off-by: Julia Evans <julia@jvns.ca>\n---\n Documentation/git-rebase.adoc | 49 ++++++++++++++++-------------------\n 1 file changed, 23 insertions(+), 26 deletions(-)\n\ndiff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc\nindex 956d3048f5a6..449f01fba560 100644\n--- a/Documentation/git-rebase.adoc\n+++ b/Documentation/git-rebase.adoc\n@@ -16,6 +16,29 @@ SYNOPSIS\n \n DESCRIPTION\n -----------\n+Transplant a series of commits onto a different starting point.\n+\n+For example, imagine that you have been working on the `topic` branch in this\n+history, and you want to \"catch up\" to the work done on the `master` branch.\n+\n+------------\n+          A---B---C topic\n+         /\n+    D---E---F---G master\n+------------\n+\n+You want to transplant the commits you made on `topic` since it diverged from\n+`master` (i.e. A, B, and C), on top of the current `master`.  You can do this\n+by running `git rebase master` while the `topic` branch is checked out.  If you\n+want to rebase `topic` while on another branch, `git rebase master topic` is a\n+shortcut for `git checkout topic && git rebase master`.\n+\n+------------\n+                  A'--B'--C' topic\n+                 /\n+    D---E---F---G master\n+------------\n+\n If `<branch>` is specified, `git rebase` will perform an automatic\n `git switch <branch>` before doing anything else.  Otherwise\n it remains on the current branch.\n@@ -58,32 +81,6 @@ that caused the merge failure with `git rebase --skip`.  To check out the\n original `<branch>` and remove the `.git/rebase-apply` working files, use\n the command `git rebase --abort` instead.\n \n-Assume the following history exists and the current branch is \"topic\":\n-\n-------------\n-          A---B---C topic\n-         /\n-    D---E---F---G master\n-------------\n-\n-From this point, the result of either of the following commands:\n-\n-\n-    git rebase master\n-    git rebase master topic\n-\n-would be:\n-\n-------------\n-                  A'--B'--C' topic\n-                 /\n-    D---E---F---G master\n-------------\n-\n-*NOTE:* The latter form is just a short-hand of `git checkout topic`\n-followed by `git rebase master`. When rebase exits `topic` will\n-remain the checked-out branch.\n-\n If the upstream branch already contains a change you have made (e.g.,\n because you mailed a patch which was applied upstream), then that commit\n will be skipped and warnings will be issued (if the 'merge' backend is\n-- \ngitgitgadget\n\n"},{"id":"523857","messageId":"061790686b9036cf862c5b918126eac1ca02a79b.1754702057.git.gitgitgadget@gmail.com","threadId":"63930","inReplyTo":"pull.1949.v4.git.1754702057.gitgitgadget@gmail.com","subject":"[PATCH v4 2/5] doc: git rebase: dedup merge conflict discussion","fromName":"Julia Evans via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-08-09T01:14:14Z","receivedAt":"2025-08-09T01:14:23Z","isPatch":true,"sender":{"key":"julia@jvns.ca","avatar":"https://avatars.githubusercontent.com/u/817739?v=4"},"body":"From: Julia Evans <julia@jvns.ca>\n\nPreviously there were two explanations, this combines them both into a\nsingle explanation.\n\nSigned-off-by: Julia Evans <julia@jvns.ca>\n---\n Documentation/git-rebase.adoc | 50 +++++++++++++++--------------------\n 1 file changed, 21 insertions(+), 29 deletions(-)\n\ndiff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc\nindex 449f01fba560..e30b9535fff1 100644\n--- a/Documentation/git-rebase.adoc\n+++ b/Documentation/git-rebase.adoc\n@@ -39,6 +39,27 @@ shortcut for `git checkout topic && git rebase master`.\n     D---E---F---G master\n ------------\n \n+If there is a merge conflict during this process, `git rebase` will stop at the\n+first problematic commit and leave conflict markers. If this happens, you can do\n+one of these things:\n+\n+1. Resolve the conflict. You can use `git diff` to find the markers (<<<<<<)\n+   and make edits to resolve the conflict. For each file you edit, you need to\n+   tell Git that the conflict has been resolved. You can mark the conflict as\n+   resolved with  `git add <filename>`. After resolving all of the conflicts,\n+   you can continue the rebasing process with\n+\n+   git rebase --continue\n+\n+2. Stop the `git rebase` and return your branch to its original state with\n+\n+   git rebase --abort\n+\n+3. Skip the commit that caused the merge conflict with\n+\n+   git rebase --skip\n+\n+\n If `<branch>` is specified, `git rebase` will perform an automatic\n `git switch <branch>` before doing anything else.  Otherwise\n it remains on the current branch.\n@@ -74,13 +95,6 @@ any commits in `HEAD` which introduce the same textual changes as a commit\n in `HEAD..<upstream>` are omitted (i.e., a patch already accepted upstream\n with a different commit message or timestamp will be skipped).\n \n-It is possible that a merge failure will prevent this process from being\n-completely automatic.  You will have to resolve any such merge failure\n-and run `git rebase --continue`.  Another option is to bypass the commit\n-that caused the merge failure with `git rebase --skip`.  To check out the\n-original `<branch>` and remove the `.git/rebase-apply` working files, use\n-the command `git rebase --abort` instead.\n-\n If the upstream branch already contains a change you have made (e.g.,\n because you mailed a patch which was applied upstream), then that commit\n will be skipped and warnings will be issued (if the 'merge' backend is\n@@ -183,28 +197,6 @@ This is useful if F and G were flawed in some way, or should not be\n part of topicA.  Note that the argument to `--onto` and the `<upstream>`\n parameter can be any valid commit-ish.\n \n-In case of conflict, `git rebase` will stop at the first problematic commit\n-and leave conflict markers in the tree.  You can use `git diff` to locate\n-the markers (<<<<<<) and make edits to resolve the conflict.  For each\n-file you edit, you need to tell Git that the conflict has been resolved,\n-typically this would be done with\n-\n-\n-    git add <filename>\n-\n-\n-After resolving the conflict manually and updating the index with the\n-desired resolution, you can continue the rebasing process with\n-\n-\n-    git rebase --continue\n-\n-\n-Alternatively, you can undo the 'git rebase' with\n-\n-\n-    git rebase --abort\n-\n MODE OPTIONS\n ------------\n \n-- \ngitgitgadget\n\n"},{"id":"523858","messageId":"fe9e161a51b2c514287762ea841e5fee7f578ffc.1754702057.git.gitgitgadget@gmail.com","threadId":"63930","inReplyTo":"pull.1949.v4.git.1754702057.gitgitgadget@gmail.com","subject":"[PATCH v4 3/5] doc: git rebase: clarify arguments syntax","fromName":"Julia Evans via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-08-09T01:14:15Z","receivedAt":"2025-08-09T01:14:25Z","isPatch":true,"sender":{"key":"julia@jvns.ca","avatar":"https://avatars.githubusercontent.com/u/817739?v=4"},"body":"From: Julia Evans <julia@jvns.ca>\n\nRemove duplicate explanation of `git rebase <upstream> <branch>` which\nis already explained above.\n\nSigned-off-by: Julia Evans <julia@jvns.ca>\n---\n Documentation/git-rebase.adoc | 7 +------\n 1 file changed, 1 insertion(+), 6 deletions(-)\n\ndiff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc\nindex e30b9535fff1..914f743ae00f 100644\n--- a/Documentation/git-rebase.adoc\n+++ b/Documentation/git-rebase.adoc\n@@ -59,12 +59,7 @@ one of these things:\n \n    git rebase --skip\n \n-\n-If `<branch>` is specified, `git rebase` will perform an automatic\n-`git switch <branch>` before doing anything else.  Otherwise\n-it remains on the current branch.\n-\n-If `<upstream>` is not specified, the upstream configured in\n+If you don't specify an `<upstream>` to rebase onto, the upstream configured in\n `branch.<name>.remote` and `branch.<name>.merge` options will be used (see\n linkgit:git-config[1] for details) and the `--fork-point` option is\n assumed.  If you are currently not on any branch or if the current\n-- \ngitgitgadget\n\n"},{"id":"523859","messageId":"b37ebc8389d1c1df0f0114d9105e774d745e4361.1754702057.git.gitgitgadget@gmail.com","threadId":"63930","inReplyTo":"pull.1949.v4.git.1754702057.gitgitgadget@gmail.com","subject":"[PATCH v4 4/5] doc: git-rebase: move --onto explanation down","fromName":"Julia Evans via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-08-09T01:14:16Z","receivedAt":"2025-08-09T01:14:26Z","isPatch":true,"sender":{"key":"julia@jvns.ca","avatar":"https://avatars.githubusercontent.com/u/817739?v=4"},"body":"From: Julia Evans <julia@jvns.ca>\n\nThere's a very clear explanation with examples of using --onto which is\ncurrently buried in the very long DESCRIPTION section. This moves it to\nits own section, so that we can reference the explanation from the\n`--onto` option by name.\n\nSigned-off-by: Julia Evans <julia@jvns.ca>\n---\n Documentation/git-rebase.adoc | 168 ++++++++++++++++++----------------\n 1 file changed, 87 insertions(+), 81 deletions(-)\n\ndiff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc\nindex 914f743ae00f..50c84f138212 100644\n--- a/Documentation/git-rebase.adoc\n+++ b/Documentation/git-rebase.adoc\n@@ -111,87 +111,6 @@ will result in:\n     D---E---A'---F master\n ------------\n \n-Here is how you would transplant a topic branch based on one\n-branch to another, to pretend that you forked the topic branch\n-from the latter branch, using `rebase --onto`.\n-\n-First let's assume your 'topic' is based on branch 'next'.\n-For example, a feature developed in 'topic' depends on some\n-functionality which is found in 'next'.\n-\n-------------\n-    o---o---o---o---o  master\n-         \\\n-          o---o---o---o---o  next\n-                           \\\n-                            o---o---o  topic\n-------------\n-\n-We want to make 'topic' forked from branch 'master'; for example,\n-because the functionality on which 'topic' depends was merged into the\n-more stable 'master' branch. We want our tree to look like this:\n-\n-------------\n-    o---o---o---o---o  master\n-        |            \\\n-        |             o'--o'--o'  topic\n-         \\\n-          o---o---o---o---o  next\n-------------\n-\n-We can get this using the following command:\n-\n-    git rebase --onto master next topic\n-\n-\n-Another example of --onto option is to rebase part of a\n-branch.  If we have the following situation:\n-\n-------------\n-                            H---I---J topicB\n-                           /\n-                  E---F---G  topicA\n-                 /\n-    A---B---C---D  master\n-------------\n-\n-then the command\n-\n-    git rebase --onto master topicA topicB\n-\n-would result in:\n-\n-------------\n-                 H'--I'--J'  topicB\n-                /\n-                | E---F---G  topicA\n-                |/\n-    A---B---C---D  master\n-------------\n-\n-This is useful when topicB does not depend on topicA.\n-\n-A range of commits could also be removed with rebase.  If we have\n-the following situation:\n-\n-------------\n-    E---F---G---H---I---J  topicA\n-------------\n-\n-then the command\n-\n-    git rebase --onto topicA~5 topicA~3 topicA\n-\n-would result in the removal of commits F and G:\n-\n-------------\n-    E---H'---I'---J'  topicA\n-------------\n-\n-This is useful if F and G were flawed in some way, or should not be\n-part of topicA.  Note that the argument to `--onto` and the `<upstream>`\n-parameter can be any valid commit-ish.\n-\n MODE OPTIONS\n ------------\n \n@@ -237,6 +156,8 @@ As a special case, you may use \"A\\...B\" as a shortcut for the\n merge base of A and B if there is exactly one merge base. You can\n leave out at most one of A and B, in which case it defaults to HEAD.\n \n+See TRANSPLANTING A TOPIC BRANCH WITH --ONTO below for examples.\n+\n --keep-base::\n \tSet the starting point at which to create the new commits to the\n \tmerge base of `<upstream>` and `<branch>`. Running\n@@ -1015,6 +936,91 @@ consistent (they compile, pass the testsuite, etc.) you should use\n after each commit, test, and amend the commit if fixes are necessary.\n \n \n+TRANSPLANTING A TOPIC BRANCH WITH --ONTO\n+----------------------------------------\n+\n+Here is how you would transplant a topic branch based on one\n+branch to another, to pretend that you forked the topic branch\n+from the latter branch, using `rebase --onto`.\n+\n+First let's assume your 'topic' is based on branch 'next'.\n+For example, a feature developed in 'topic' depends on some\n+functionality which is found in 'next'.\n+\n+------------\n+    o---o---o---o---o  master\n+         \\\n+          o---o---o---o---o  next\n+                           \\\n+                            o---o---o  topic\n+------------\n+\n+We want to make 'topic' forked from branch 'master'; for example,\n+because the functionality on which 'topic' depends was merged into the\n+more stable 'master' branch. We want our tree to look like this:\n+\n+------------\n+    o---o---o---o---o  master\n+        |            \\\n+        |             o'--o'--o'  topic\n+         \\\n+          o---o---o---o---o  next\n+------------\n+\n+We can get this using the following command:\n+\n+    git rebase --onto master next topic\n+\n+\n+Another example of --onto option is to rebase part of a\n+branch.  If we have the following situation:\n+\n+------------\n+                            H---I---J topicB\n+                           /\n+                  E---F---G  topicA\n+                 /\n+    A---B---C---D  master\n+------------\n+\n+then the command\n+\n+    git rebase --onto master topicA topicB\n+\n+would result in:\n+\n+------------\n+                 H'--I'--J'  topicB\n+                /\n+                | E---F---G  topicA\n+                |/\n+    A---B---C---D  master\n+------------\n+\n+This is useful when topicB does not depend on topicA.\n+\n+A range of commits could also be removed with rebase.  If we have\n+the following situation:\n+\n+------------\n+    E---F---G---H---I---J  topicA\n+------------\n+\n+then the command\n+\n+    git rebase --onto topicA~5 topicA~3 topicA\n+\n+would result in the removal of commits F and G:\n+\n+------------\n+    E---H'---I'---J'  topicA\n+------------\n+\n+This is useful if F and G were flawed in some way, or should not be\n+part of topicA.  Note that the argument to `--onto` and the `<upstream>`\n+parameter can be any valid commit-ish.\n+\n+\n RECOVERING FROM UPSTREAM REBASE\n -------------------------------\n \n-- \ngitgitgadget\n\n"},{"id":"523860","messageId":"105a65e6e7121ac6a9a8a1d0b4f3217495a9f5e7.1754702057.git.gitgitgadget@gmail.com","threadId":"63930","inReplyTo":"pull.1949.v4.git.1754702057.gitgitgadget@gmail.com","subject":"[PATCH v4 5/5] doc: git-rebase: update discussion of internals","fromName":"Julia Evans via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-08-09T01:14:17Z","receivedAt":"2025-08-09T01:14:27Z","isPatch":true,"sender":{"key":"julia@jvns.ca","avatar":"https://avatars.githubusercontent.com/u/817739?v=4"},"body":"From: Julia Evans <julia@jvns.ca>\n\n- make it clearer that we're talking about a multistep process\n- give a more technically accurate description how rebase works with the\n  merge backend.\n- delete a duplicate explanation of how git rebase skips commits with\n  the same textual changes (it's explained in more detail a few lines\n  further down)\n- remove the explanation of how exactly `--fork-point` and `--root`\n  work since that information is in the OPTIONS section\n- put all discussion of `ORIG_HEAD` inside the note\n\nSigned-off-by: Julia Evans <julia@jvns.ca>\n---\n Documentation/git-rebase.adoc | 34 +++++++++++++++++-----------------\n 1 file changed, 17 insertions(+), 17 deletions(-)\n\ndiff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc\nindex 50c84f138212..c16ee37b46a7 100644\n--- a/Documentation/git-rebase.adoc\n+++ b/Documentation/git-rebase.adoc\n@@ -65,31 +65,31 @@ linkgit:git-config[1] for details) and the `--fork-point` option is\n assumed.  If you are currently not on any branch or if the current\n branch does not have a configured upstream, the rebase will abort.\n \n-All changes made by commits in the current branch but that are not\n-in `<upstream>` are saved to a temporary area.  This is the same set\n-of commits that would be shown by `git log <upstream>..HEAD`; or by\n-`git log 'fork_point'..HEAD`, if `--fork-point` is active (see the\n-description on `--fork-point` below); or by `git log HEAD`, if the\n-`--root` option is specified.\n-\n-The current branch is reset to `<upstream>` or `<newbase>` if the\n-`--onto` option was supplied.  This has the exact same effect as\n-`git reset --hard <upstream>` (or `<newbase>`). `ORIG_HEAD` is set\n-to point at the tip of the branch before the reset.\n+Here is a more detailed description of what `git rebase <upstream>` does:\n+\n+First, it makes a list of all commits in the current branch that are not in\n+`<upstream>`. This is the same set of commits that would be shown by `git log\n+<upstream>..HEAD`. You can use `--fork-point` or `--root` to change how this\n+list of commits is constructed.\n+\n+Then it checks out `<upstream>` (or `<newbase>` if the `--onto` option was\n+supplied) with the equivalent of `git switch --detach <upstream>`.\n+\n+Then it replays the commits, one by one, in order. This is similar to running\n+`git cherry-pick <commit>` for each commit. See REBASING MERGES for how merges\n+are handled.\n+\n+Finally, it updates your branch to point to the final commit with the equivalent\n+of `git switch -C <branch>`.\n \n [NOTE]\n+`ORIG_HEAD` is set to point at the tip of the branch before the rebase.\n `ORIG_HEAD` is not guaranteed to still point to the previous branch tip\n at the end of the rebase if other commands that write that pseudo-ref\n (e.g. `git reset`) are used during the rebase. The previous branch tip,\n however, is accessible using the reflog of the current branch\n (i.e. `@{1}`, see linkgit:gitrevisions[7]).\n \n-The commits that were previously saved into the temporary area are\n-then reapplied to the current branch, one by one, in order. Note that\n-any commits in `HEAD` which introduce the same textual changes as a commit\n-in `HEAD..<upstream>` are omitted (i.e., a patch already accepted upstream\n-with a different commit message or timestamp will be skipped).\n-\n If the upstream branch already contains a change you have made (e.g.,\n because you mailed a patch which was applied upstream), then that commit\n will be skipped and warnings will be issued (if the 'merge' backend is\n-- \ngitgitgadget\n"},{"id":"523872","messageId":"CALnO6CBxrNKM4oNNQHbyq7K9unA6=uu3JSxWPV1gwnUZ0=LNfg@mail.gmail.com","threadId":"63930","inReplyTo":"b37ebc8389d1c1df0f0114d9105e774d745e4361.1754702057.git.gitgitgadget@gmail.com","subject":"Re: [PATCH v4 4/5] doc: git-rebase: move --onto explanation down","fromName":"D. Ben Knoble","fromEmail":"ben.knoble@gmail.com","sentAt":"2025-08-09T14:55:40Z","receivedAt":"2025-08-09T14:55:53Z","isPatch":true,"sender":{"key":"ben.knoble@gmail.com","avatar":"https://avatars.githubusercontent.com/u/22802209?v=4"},"body":"On Fri, Aug 8, 2025 at 9:14 PM Julia Evans via GitGitGadget\n<gitgitgadget@gmail.com> wrote:\n>\n> From: Julia Evans <julia@jvns.ca>\n>\n> There's a very clear explanation with examples of using --onto which is\n> currently buried in the very long DESCRIPTION section. This moves it to\n> its own section, so that we can reference the explanation from the\n> `--onto` option by name.\n>\n> Signed-off-by: Julia Evans <julia@jvns.ca>\n> ---\n>  Documentation/git-rebase.adoc | 168 ++++++++++++++++++----------------\n>  1 file changed, 87 insertions(+), 81 deletions(-)\n>\n> diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc\n> index 914f743ae00f..50c84f138212 100644\n> --- a/Documentation/git-rebase.adoc\n> +++ b/Documentation/git-rebase.adoc\n> @@ -111,87 +111,6 @@ will result in:\n>      D---E---A'---F master\n>  ------------\n>\n> -Here is how you would transplant a topic branch based on one\n> -branch to another, to pretend that you forked the topic branch\n> -from the latter branch, using `rebase --onto`.\n\nI wonder if we should leave a pointer to the reader to the new section\nhere, also? The onto mode is not quite as common in my workflow as the\nother modes, but when helping less experienced users out I often end\nup using it, so keeping some reference to it early might be nice. IDK\nwhere a natural point is, though.\n\n> -\n> -First let's assume your 'topic' is based on branch 'next'.\n> -For example, a feature developed in 'topic' depends on some\n> -functionality which is found in 'next'.\n> -\n> -------------\n> -    o---o---o---o---o  master\n> -         \\\n> -          o---o---o---o---o  next\n> -                           \\\n> -                            o---o---o  topic\n> -------------\n> -\n> -We want to make 'topic' forked from branch 'master'; for example,\n> -because the functionality on which 'topic' depends was merged into the\n> -more stable 'master' branch. We want our tree to look like this:\n> -\n> -------------\n> -    o---o---o---o---o  master\n> -        |            \\\n> -        |             o'--o'--o'  topic\n> -         \\\n> -          o---o---o---o---o  next\n> -------------\n> -\n> -We can get this using the following command:\n> -\n> -    git rebase --onto master next topic\n> -\n> -\n> -Another example of --onto option is to rebase part of a\n> -branch.  If we have the following situation:\n> -\n> -------------\n> -                            H---I---J topicB\n> -                           /\n> -                  E---F---G  topicA\n> -                 /\n> -    A---B---C---D  master\n> -------------\n> -\n> -then the command\n> -\n> -    git rebase --onto master topicA topicB\n> -\n> -would result in:\n> -\n> -------------\n> -                 H'--I'--J'  topicB\n> -                /\n> -                | E---F---G  topicA\n> -                |/\n> -    A---B---C---D  master\n> -------------\n> -\n> -This is useful when topicB does not depend on topicA.\n> -\n> -A range of commits could also be removed with rebase.  If we have\n> -the following situation:\n> -\n> -------------\n> -    E---F---G---H---I---J  topicA\n> -------------\n> -\n> -then the command\n> -\n> -    git rebase --onto topicA~5 topicA~3 topicA\n> -\n> -would result in the removal of commits F and G:\n> -\n> -------------\n> -    E---H'---I'---J'  topicA\n> -------------\n> -\n> -This is useful if F and G were flawed in some way, or should not be\n> -part of topicA.  Note that the argument to `--onto` and the `<upstream>`\n> -parameter can be any valid commit-ish.\n> -\n>  MODE OPTIONS\n>  ------------\n>\n> @@ -237,6 +156,8 @@ As a special case, you may use \"A\\...B\" as a shortcut for the\n>  merge base of A and B if there is exactly one merge base. You can\n>  leave out at most one of A and B, in which case it defaults to HEAD.\n>\n> +See TRANSPLANTING A TOPIC BRANCH WITH --ONTO below for examples.\n> +\n>  --keep-base::\n>         Set the starting point at which to create the new commits to the\n>         merge base of `<upstream>` and `<branch>`. Running\n> @@ -1015,6 +936,91 @@ consistent (they compile, pass the testsuite, etc.) you should use\n>  after each commit, test, and amend the commit if fixes are necessary.\n>\n>\n> +TRANSPLANTING A TOPIC BRANCH WITH --ONTO\n> +----------------------------------------\n> +\n> +Here is how you would transplant a topic branch based on one\n> +branch to another, to pretend that you forked the topic branch\n> +from the latter branch, using `rebase --onto`.\n> +\n> +First let's assume your 'topic' is based on branch 'next'.\n> +For example, a feature developed in 'topic' depends on some\n> +functionality which is found in 'next'.\n> +\n> +------------\n> +    o---o---o---o---o  master\n> +         \\\n> +          o---o---o---o---o  next\n> +                           \\\n> +                            o---o---o  topic\n> +------------\n> +\n> +We want to make 'topic' forked from branch 'master'; for example,\n> +because the functionality on which 'topic' depends was merged into the\n> +more stable 'master' branch. We want our tree to look like this:\n> +\n> +------------\n> +    o---o---o---o---o  master\n> +        |            \\\n> +        |             o'--o'--o'  topic\n> +         \\\n> +          o---o---o---o---o  next\n> +------------\n> +\n> +We can get this using the following command:\n> +\n> +    git rebase --onto master next topic\n> +\n> +\n> +Another example of --onto option is to rebase part of a\n> +branch.  If we have the following situation:\n> +\n> +------------\n> +                            H---I---J topicB\n> +                           /\n> +                  E---F---G  topicA\n> +                 /\n> +    A---B---C---D  master\n> +------------\n> +\n> +then the command\n> +\n> +    git rebase --onto master topicA topicB\n> +\n> +would result in:\n> +\n> +------------\n> +                 H'--I'--J'  topicB\n> +                /\n> +                | E---F---G  topicA\n> +                |/\n> +    A---B---C---D  master\n> +------------\n> +\n> +This is useful when topicB does not depend on topicA.\n> +\n> +A range of commits could also be removed with rebase.  If we have\n> +the following situation:\n> +\n> +------------\n> +    E---F---G---H---I---J  topicA\n> +------------\n> +\n> +then the command\n> +\n> +    git rebase --onto topicA~5 topicA~3 topicA\n> +\n> +would result in the removal of commits F and G:\n> +\n> +------------\n> +    E---H'---I'---J'  topicA\n> +------------\n> +\n> +This is useful if F and G were flawed in some way, or should not be\n> +part of topicA.  Note that the argument to `--onto` and the `<upstream>`\n> +parameter can be any valid commit-ish.\n> +\n> +\n>  RECOVERING FROM UPSTREAM REBASE\n>  -------------------------------\n>\n> --\n> gitgitgadget\n>\n>\n\n\n-- \nD. Ben Knoble\n"},{"id":"523873","messageId":"CALnO6CAmC8bviFJeZeRpD_6OJoA6=N8HOR4EkWUN--2rjifTAw@mail.gmail.com","threadId":"63930","inReplyTo":"pull.1949.v2.git.1754680525.gitgitgadget@gmail.com","subject":"Re: [PATCH v2 0/5] doc: git-rebase: clarify DESCRIPTION section","fromName":"D. Ben Knoble","fromEmail":"ben.knoble@gmail.com","sentAt":"2025-08-09T15:04:52Z","receivedAt":"2025-08-09T15:05:05Z","isPatch":true,"sender":{"key":"ben.knoble@gmail.com","avatar":"https://avatars.githubusercontent.com/u/22802209?v=4"},"body":"On Fri, Aug 8, 2025 at 3:15 PM Julia Evans via GitGitGadget\n<gitgitgadget@gmail.com> wrote:\n>\n> Thanks for the review comments, here are the new changes which:\n>\n>  * make the intro to the man page less dry, with the suggested wording\n>  * clarify the merge conflict resolution explanation & fix the HTML\n>    formatting issues\n>  * move the explanation of the git rebase <upstream> <branch> syntax up into\n>    the intro\n>\n> I'm still curious about the intention for the git rebase master topic\n> syntax, since I'd never heard of it before. Is it just to save on typing,\n> since it's fewer characters than git switch topic and then git rebase\n> master? I ask because someone mentioned to me on Mastodon\n> (https://hachyderm.io/@simontatham/114988051822317920) that they sometimes\n> use git rebase HEAD main as part of their workflow, which is not equivalent\n> to git checkout main && git rebase HEAD. That made me think that there might\n> be some broader intent to enable rebases that wouldn't otherwise be possible\n> without that syntax.\n\nI think the intent really is \"shortcut.\" It's existed since the first\nversion of rebase (59e6b23ace ([PATCH] git-rebase-script: rebase local\ncommits to new upstream head., 2005-06-25),\nhttps://lore.kernel.org/git/7v4qboejp6.fsf_-_@assigned-by-dhcp.cox.net/).\nI didn't look too closely at that mailing list thread for any\njustification of the shortcut, though.\n\nThe example mentioned on Mastodon is still a shortcut, it's just more\nlike a function than a macro (that is, the arguments are evaluated\nfirst, then the shortcut applied):\n\n    git rebase HEAD main\n\nbecomes (in shell syntax)\n\n    head=$(git rev-parse HEAD)\n    git switch --detach main\n    git rebase $head\n\nrather than\n\n    git switch --detach main\n    git rebase HEAD # too late, HEAD has changed\n"},{"id":"523888","messageId":"38293aee-9055-4527-a511-1afa87289fb2@gmail.com","threadId":"63930","inReplyTo":"07a4bdb7ce5eb456bd81972c350d0c4f298ebd46.1754702057.git.gitgitgadget@gmail.com","subject":"Re: [PATCH v4 1/5] doc: git-rebase: start with an example","fromName":"Phillip Wood","fromEmail":"phillip.wood123@gmail.com","sentAt":"2025-08-10T15:41:48Z","receivedAt":"2025-08-10T15:41:51Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"Hi Julia\n\nOn 09/08/2025 02:14, Julia Evans via GitGitGadget wrote:\n> From: Julia Evans <julia@jvns.ca>\n> \n> Start with an example that mirrors the example in the `git-merge` man\n> page, to make it easier for folks to understand the difference between a\n> rebase and a merge.\n\nThis is a very welcome improvement which makes it clear what rebasing a \nbranch does. There are other important uses of rebase such as \nrearranging commits and squashing fixup commits that it would be nice to \nmention early on in the man page as well. Those do not necessarily \nchange the base of the branch. I wonder if we could add a sentence about \nthat which links to the INTERACTIVE MODE section.\n\nThanks\n\nPhillip\n\n> Signed-off-by: Julia Evans <julia@jvns.ca>\n> ---\n>   Documentation/git-rebase.adoc | 49 ++++++++++++++++-------------------\n>   1 file changed, 23 insertions(+), 26 deletions(-)\n> \n> diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc\n> index 956d3048f5a6..449f01fba560 100644\n> --- a/Documentation/git-rebase.adoc\n> +++ b/Documentation/git-rebase.adoc\n> @@ -16,6 +16,29 @@ SYNOPSIS\n>   \n>   DESCRIPTION\n>   -----------\n> +Transplant a series of commits onto a different starting point.\n> +\n> +For example, imagine that you have been working on the `topic` branch in this\n> +history, and you want to \"catch up\" to the work done on the `master` branch.\n> +\n> +------------\n> +          A---B---C topic\n> +         /\n> +    D---E---F---G master\n> +------------\n> +\n> +You want to transplant the commits you made on `topic` since it diverged from\n> +`master` (i.e. A, B, and C), on top of the current `master`.  You can do this\n> +by running `git rebase master` while the `topic` branch is checked out.  If you\n> +want to rebase `topic` while on another branch, `git rebase master topic` is a\n> +shortcut for `git checkout topic && git rebase master`.\n> +\n> +------------\n> +                  A'--B'--C' topic\n> +                 /\n> +    D---E---F---G master\n> +------------\n> +\n>   If `<branch>` is specified, `git rebase` will perform an automatic\n>   `git switch <branch>` before doing anything else.  Otherwise\n>   it remains on the current branch.\n> @@ -58,32 +81,6 @@ that caused the merge failure with `git rebase --skip`.  To check out the\n>   original `<branch>` and remove the `.git/rebase-apply` working files, use\n>   the command `git rebase --abort` instead.\n>   \n> -Assume the following history exists and the current branch is \"topic\":\n> -\n> -------------\n> -          A---B---C topic\n> -         /\n> -    D---E---F---G master\n> -------------\n> -\n> -From this point, the result of either of the following commands:\n> -\n> -\n> -    git rebase master\n> -    git rebase master topic\n> -\n> -would be:\n> -\n> -------------\n> -                  A'--B'--C' topic\n> -                 /\n> -    D---E---F---G master\n> -------------\n> -\n> -*NOTE:* The latter form is just a short-hand of `git checkout topic`\n> -followed by `git rebase master`. When rebase exits `topic` will\n> -remain the checked-out branch.\n> -\n>   If the upstream branch already contains a change you have made (e.g.,\n>   because you mailed a patch which was applied upstream), then that commit\n>   will be skipped and warnings will be issued (if the 'merge' backend is\n\n"},{"id":"523889","messageId":"10372e00-3bb1-453a-bb62-332aaa935b24@gmail.com","threadId":"63930","inReplyTo":"105a65e6e7121ac6a9a8a1d0b4f3217495a9f5e7.1754702057.git.gitgitgadget@gmail.com","subject":"Re: [PATCH v4 5/5] doc: git-rebase: update discussion of internals","fromName":"Phillip Wood","fromEmail":"phillip.wood123@gmail.com","sentAt":"2025-08-10T15:42:00Z","receivedAt":"2025-08-10T15:42:03Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"Hi Julia\n\nOn 09/08/2025 02:14, Julia Evans via GitGitGadget wrote:\n> From: Julia Evans <julia@jvns.ca>\n> \n> +Here is a more detailed description of what `git rebase <upstream>` does:\n> +\n> +First, it makes a list of all commits in the current branch that are not in\n> +`<upstream>`. This is the same set of commits that would be shown by `git log\n> +<upstream>..HEAD`.\n\nThe existing text is not quite accurate here, it should really say `git \nlog --cherry-pick --right-only <upstream>...HEAD` as we drop any commits \nfrom the branch that have already been cherry-picked to <upstream>.\n\n> You can use `--fork-point` or `--root` to change how this\n> +list of commits is constructed.\n\n`--reapply-cherry-picks` also changes how the list is constructed so I \nthink it would be worth adding that option here as well.\n\nThanks for working on this, it makes the description section much more \nreadable.\n\nPhillip\n> +\n> +Then it checks out `<upstream>` (or `<newbase>` if the `--onto` option was\n> +supplied) with the equivalent of `git switch --detach <upstream>`.\n> +\n> +Then it replays the commits, one by one, in order. This is similar to running\n> +`git cherry-pick <commit>` for each commit. See REBASING MERGES for how merges\n> +are handled.\n> +\n> +Finally, it updates your branch to point to the final commit with the equivalent\n> +of `git switch -C <branch>`.\n>   \n>   [NOTE]\n> +`ORIG_HEAD` is set to point at the tip of the branch before the rebase.\n>   `ORIG_HEAD` is not guaranteed to still point to the previous branch tip\n>   at the end of the rebase if other commands that write that pseudo-ref\n>   (e.g. `git reset`) are used during the rebase. The previous branch tip,\n>   however, is accessible using the reflog of the current branch\n>   (i.e. `@{1}`, see linkgit:gitrevisions[7]).\n>   \n> -The commits that were previously saved into the temporary area are\n> -then reapplied to the current branch, one by one, in order. Note that\n> -any commits in `HEAD` which introduce the same textual changes as a commit\n> -in `HEAD..<upstream>` are omitted (i.e., a patch already accepted upstream\n> -with a different commit message or timestamp will be skipped).\n> -\n>   If the upstream branch already contains a change you have made (e.g.,\n>   because you mailed a patch which was applied upstream), then that commit\n>   will be skipped and warnings will be issued (if the 'merge' backend is\n\n"},{"id":"523912","messageId":"aJmtyLgv1so8qdY7@pks.im","threadId":"63930","inReplyTo":"07a4bdb7ce5eb456bd81972c350d0c4f298ebd46.1754702057.git.gitgitgadget@gmail.com","subject":"Re: [PATCH v4 1/5] doc: git-rebase: start with an example","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2025-08-11T08:46:00Z","receivedAt":"2025-08-11T08:46:07Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Sat, Aug 09, 2025 at 01:14:13AM +0000, Julia Evans via GitGitGadget wrote:\n> From: Julia Evans <julia@jvns.ca>\n> \n> Start with an example that mirrors the example in the `git-merge` man\n> page, to make it easier for folks to understand the difference between a\n> rebase and a merge.\n\nMakes sense.\n\n> diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc\n> index 956d3048f5a6..449f01fba560 100644\n> --- a/Documentation/git-rebase.adoc\n> +++ b/Documentation/git-rebase.adoc\n> @@ -16,6 +16,29 @@ SYNOPSIS\n>  \n>  DESCRIPTION\n>  -----------\n> +Transplant a series of commits onto a different starting point.\n\nNit: while this is one use case for git-rebase(1), I'd claim that\nnowadays with interactive rebases there's the other use case where we\ndon't change the starting point but only edit the range of commits\nitself.\n\nSo how about this instead:\n\n    Edit a series of commits and optionally transplant it onto a\n    different starting point.\n\nWe could also make the two different modes a bit more explicit by\npointing out both different use cases directly.\n\nIf you agree then we should probably also modernize the description in\nthe NAME section accordingly.\n\nPatrick\n"},{"id":"523913","messageId":"aJmtzfuibPwS1WVl@pks.im","threadId":"63930","inReplyTo":"061790686b9036cf862c5b918126eac1ca02a79b.1754702057.git.gitgitgadget@gmail.com","subject":"Re: [PATCH v4 2/5] doc: git rebase: dedup merge conflict discussion","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2025-08-11T08:46:05Z","receivedAt":"2025-08-11T08:46:11Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Sat, Aug 09, 2025 at 01:14:14AM +0000, Julia Evans via GitGitGadget wrote:\n> diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc\n> index 449f01fba560..e30b9535fff1 100644\n> --- a/Documentation/git-rebase.adoc\n> +++ b/Documentation/git-rebase.adoc\n> @@ -39,6 +39,27 @@ shortcut for `git checkout topic && git rebase master`.\n>      D---E---F---G master\n>  ------------\n>  \n> +If there is a merge conflict during this process, `git rebase` will stop at the\n> +first problematic commit and leave conflict markers. If this happens, you can do\n> +one of these things:\n> +\n> +1. Resolve the conflict. You can use `git diff` to find the markers (<<<<<<)\n> +   and make edits to resolve the conflict. For each file you edit, you need to\n> +   tell Git that the conflict has been resolved. You can mark the conflict as\n> +   resolved with  `git add <filename>`. After resolving all of the conflicts,\n> +   you can continue the rebasing process with\n> +\n> +   git rebase --continue\n> +\n> +2. Stop the `git rebase` and return your branch to its original state with\n> +\n> +   git rebase --abort\n> +\n> +3. Skip the commit that caused the merge conflict with\n> +\n> +   git rebase --skip\n> +\n> +\n>  If `<branch>` is specified, `git rebase` will perform an automatic\n>  `git switch <branch>` before doing anything else.  Otherwise\n>  it remains on the current branch.\n\nYup, this reads a lot nicer.\n\n> @@ -74,13 +95,6 @@ any commits in `HEAD` which introduce the same textual changes as a commit\n>  in `HEAD..<upstream>` are omitted (i.e., a patch already accepted upstream\n>  with a different commit message or timestamp will be skipped).\n>  \n> -It is possible that a merge failure will prevent this process from being\n> -completely automatic.  You will have to resolve any such merge failure\n> -and run `git rebase --continue`.  Another option is to bypass the commit\n> -that caused the merge failure with `git rebase --skip`.  To check out the\n> -original `<branch>` and remove the `.git/rebase-apply` working files, use\n> -the command `git rebase --abort` instead.\n> -\n>  If the upstream branch already contains a change you have made (e.g.,\n>  because you mailed a patch which was applied upstream), then that commit\n>  will be skipped and warnings will be issued (if the 'merge' backend is\n\nWe lose the bit about `.git/rebase-apply`, but I don't think that's a\nbad thing. The user shouldn't have to care how exactly a rebase looks on\ndisk. All they should need to know is that `git rebase --abort` gets\nthem out of the state.\n\nPatrick\n"},{"id":"523914","messageId":"aJmt1fv66bO_ZMpI@pks.im","threadId":"63930","inReplyTo":"105a65e6e7121ac6a9a8a1d0b4f3217495a9f5e7.1754702057.git.gitgitgadget@gmail.com","subject":"Re: [PATCH v4 5/5] doc: git-rebase: update discussion of internals","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2025-08-11T08:46:13Z","receivedAt":"2025-08-11T08:46:18Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Sat, Aug 09, 2025 at 01:14:17AM +0000, Julia Evans via GitGitGadget wrote:\n> diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc\n> index 50c84f138212..c16ee37b46a7 100644\n> --- a/Documentation/git-rebase.adoc\n> +++ b/Documentation/git-rebase.adoc\n> @@ -65,31 +65,31 @@ linkgit:git-config[1] for details) and the `--fork-point` option is\n>  assumed.  If you are currently not on any branch or if the current\n>  branch does not have a configured upstream, the rebase will abort.\n>  \n> -All changes made by commits in the current branch but that are not\n> -in `<upstream>` are saved to a temporary area.  This is the same set\n> -of commits that would be shown by `git log <upstream>..HEAD`; or by\n> -`git log 'fork_point'..HEAD`, if `--fork-point` is active (see the\n> -description on `--fork-point` below); or by `git log HEAD`, if the\n> -`--root` option is specified.\n> -\n> -The current branch is reset to `<upstream>` or `<newbase>` if the\n> -`--onto` option was supplied.  This has the exact same effect as\n> -`git reset --hard <upstream>` (or `<newbase>`). `ORIG_HEAD` is set\n> -to point at the tip of the branch before the reset.\n> +Here is a more detailed description of what `git rebase <upstream>` does:\n> +\n> +First, it makes a list of all commits in the current branch that are not in\n> +`<upstream>`. This is the same set of commits that would be shown by `git log\n> +<upstream>..HEAD`. You can use `--fork-point` or `--root` to change how this\n> +list of commits is constructed.\n> +\n> +Then it checks out `<upstream>` (or `<newbase>` if the `--onto` option was\n> +supplied) with the equivalent of `git switch --detach <upstream>`.\n> +\n> +Then it replays the commits, one by one, in order. This is similar to running\n> +`git cherry-pick <commit>` for each commit. See REBASING MERGES for how merges\n> +are handled.\n> +\n> +Finally, it updates your branch to point to the final commit with the equivalent\n> +of `git switch -C <branch>`.\n\nWould it make sense to convert this into a bulleted list to further\nhighlight this multi-step process?\n\n>  [NOTE]\n> +`ORIG_HEAD` is set to point at the tip of the branch before the rebase.\n>  `ORIG_HEAD` is not guaranteed to still point to the previous branch tip\n>  at the end of the rebase if other commands that write that pseudo-ref\n>  (e.g. `git reset`) are used during the rebase. The previous branch tip,\n>  however, is accessible using the reflog of the current branch\n>  (i.e. `@{1}`, see linkgit:gitrevisions[7]).\n\nThis information feels somewhat contradictory. Should we maybe say\nsomething like this:\n\n    When starting the rebase, `ORIG_HEAD` is set to point to at the tip\n    of the to-be-rebased branch. As `ORIG_HEAD` may be modified by\n    various operations during the rebase, it is not guaranteed to still\n    point to this branch at the end of the rebase. The previous branch\n    tip, however, is accessible using the reflog of the current branch\n    (i.e. `@{1}`, see linkgit:gitrevisions[7]).\n\nNote that I'm also dropping the reference to \"pseudo-ref\". ORIG_HEAD is\nnot a pseudo-ref, as we have clarified in 6fd8037564\n(Documentation/glossary: redefine pseudorefs as special refs,\n2024-05-15).\n\nPatrick\n"},{"id":"523918","messageId":"CAOLa=ZSTaAaWJWeXBkoxPx46g_Equo-sHWgCESE9G6vk3HZeqA@mail.gmail.com","threadId":"63930","inReplyTo":"07a4bdb7ce5eb456bd81972c350d0c4f298ebd46.1754702057.git.gitgitgadget@gmail.com","subject":"Re: [PATCH v4 1/5] doc: git-rebase: start with an example","fromName":"Karthik Nayak","fromEmail":"karthik.188@gmail.com","sentAt":"2025-08-11T09:13:07Z","receivedAt":"2025-08-11T09:13:08Z","isPatch":true,"sender":{"key":"karthik.188@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1786334?v=4"},"body":"\"Julia Evans via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n\n> From: Julia Evans <julia@jvns.ca>\n>\n> Start with an example that mirrors the example in the `git-merge` man\n> page, to make it easier for folks to understand the difference between a\n> rebase and a merge.\n>\n\nHappy to see these changes.\n\n> Signed-off-by: Julia Evans <julia@jvns.ca>\n> ---\n>  Documentation/git-rebase.adoc | 49 ++++++++++++++++-------------------\n>  1 file changed, 23 insertions(+), 26 deletions(-)\n>\n> diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc\n> index 956d3048f5a6..449f01fba560 100644\n> --- a/Documentation/git-rebase.adoc\n> +++ b/Documentation/git-rebase.adoc\n> @@ -16,6 +16,29 @@ SYNOPSIS\n>\n>  DESCRIPTION\n>  -----------\n> +Transplant a series of commits onto a different starting point.\n> +\n> +For example, imagine that you have been working on the `topic` branch in this\n> +history, and you want to \"catch up\" to the work done on the `master` branch.\n> +\n> +------------\n> +          A---B---C topic\n> +         /\n> +    D---E---F---G master\n> +------------\n> +\n> +You want to transplant the commits you made on `topic` since it diverged from\n> +`master` (i.e. A, B, and C), on top of the current `master`.  You can do this\n> +by running `git rebase master` while the `topic` branch is checked out.  If you\n> +want to rebase `topic` while on another branch, `git rebase master topic` is a\n> +shortcut for `git checkout topic && git rebase master`.\n> +\n\nNit: now that `git-switch(1)` is no longer experimental, we should start\nrecommending it over `git-checkout(1)` as necessary. So perhaps, we\ncould s/checkout/switch here?\n\n[snip]\n"},{"id":"523927","messageId":"46477AC9-8363-453D-8A57-F599A451D36D@gmail.com","threadId":"63930","inReplyTo":"CAOLa=ZSTaAaWJWeXBkoxPx46g_Equo-sHWgCESE9G6vk3HZeqA@mail.gmail.com","subject":"Re: [PATCH v4 1/5] doc: git-rebase: start with an example","fromName":"Ben Knoble","fromEmail":"ben.knoble@gmail.com","sentAt":"2025-08-11T12:27:52Z","receivedAt":"2025-08-11T12:28:05Z","isPatch":true,"sender":{"key":"ben.knoble@gmail.com","avatar":"https://avatars.githubusercontent.com/u/22802209?v=4"},"body":"\n> Le 11 août 2025 à 05:29, Karthik Nayak <karthik.188@gmail.com> a écrit :\n> \n> ﻿\"Julia Evans via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n>> \n>> Signed-off-by: Julia Evans <julia@jvns.ca>\n>> ---\n>> Documentation/git-rebase.adoc | 49 ++++++++++++++++-------------------\n>> 1 file changed, 23 insertions(+), 26 deletions(-)\n>> \n>> diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc\n>> index 956d3048f5a6..449f01fba560 100644\n>> --- a/Documentation/git-rebase.adoc\n>> +++ b/Documentation/git-rebase.adoc\n>> @@ -16,6 +16,29 @@ SYNOPSIS\n>> \n>> DESCRIPTION\n>> -----------\n>> +Transplant a series of commits onto a different starting point.\n>> +\n>> +For example, imagine that you have been working on the `topic` branch in this\n>> +history, and you want to \"catch up\" to the work done on the `master` branch.\n>> +\n>> +------------\n>> +          A---B---C topic\n>> +         /\n>> +    D---E---F---G master\n>> +------------\n>> +\n>> +You want to transplant the commits you made on `topic` since it diverged from\n>> +`master` (i.e. A, B, and C), on top of the current `master`.  You can do this\n>> +by running `git rebase master` while the `topic` branch is checked out.  If you\n>> +want to rebase `topic` while on another branch, `git rebase master topic` is a\n>> +shortcut for `git checkout topic && git rebase master`.\n>> +\n> \n> Nit: now that `git-switch(1)` is no longer experimental, we should start\n> recommending it over `git-checkout(1)` as necessary. So perhaps, we\n> could s/checkout/switch here?\n\nJunio previously recommended checkout (a prior version used switch): I suspect because checkout will detach head without extra syntax (where switch will not)?"},{"id":"523928","messageId":"FA86B191-AEA6-49AE-A04F-EB736DF4845B@gmail.com","threadId":"63930","inReplyTo":"aJmt1fv66bO_ZMpI@pks.im","subject":"Re: [PATCH v4 5/5] doc: git-rebase: update discussion of internals","fromName":"Ben Knoble","fromEmail":"ben.knoble@gmail.com","sentAt":"2025-08-11T12:29:42Z","receivedAt":"2025-08-11T12:29:55Z","isPatch":true,"sender":{"key":"ben.knoble@gmail.com","avatar":"https://avatars.githubusercontent.com/u/22802209?v=4"},"body":"\n> Le 11 août 2025 à 04:46, Patrick Steinhardt <ps@pks.im> a écrit :\n> \n> ﻿On Sat, Aug 09, 2025 at 01:14:17AM +0000, Julia Evans via GitGitGadget wrote:\n>> diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc\n>> index 50c84f138212..c16ee37b46a7 100644\n>> --- a/Documentation/git-rebase.adoc\n>> +++ b/Documentation/git-rebase.adoc\n>> @@ -65,31 +65,31 @@ linkgit:git-config[1] for details) and the `--fork-point` option is\n>> assumed.  If you are currently not on any branch or if the current\n>> branch does not have a configured upstream, the rebase will abort.\n>> \n>> -All changes made by commits in the current branch but that are not\n>> -in `<upstream>` are saved to a temporary area.  This is the same set\n>> -of commits that would be shown by `git log <upstream>..HEAD`; or by\n>> -`git log 'fork_point'..HEAD`, if `--fork-point` is active (see the\n>> -description on `--fork-point` below); or by `git log HEAD`, if the\n>> -`--root` option is specified.\n>> -\n>> -The current branch is reset to `<upstream>` or `<newbase>` if the\n>> -`--onto` option was supplied.  This has the exact same effect as\n>> -`git reset --hard <upstream>` (or `<newbase>`). `ORIG_HEAD` is set\n>> -to point at the tip of the branch before the reset.\n>> +Here is a more detailed description of what `git rebase <upstream>` does:\n>> +\n>> +First, it makes a list of all commits in the current branch that are not in\n>> +`<upstream>`. This is the same set of commits that would be shown by `git log\n>> +<upstream>..HEAD`. You can use `--fork-point` or `--root` to change how this\n>> +list of commits is constructed.\n>> +\n>> +Then it checks out `<upstream>` (or `<newbase>` if the `--onto` option was\n>> +supplied) with the equivalent of `git switch --detach <upstream>`.\n>> +\n>> +Then it replays the commits, one by one, in order. This is similar to running\n>> +`git cherry-pick <commit>` for each commit. See REBASING MERGES for how merges\n>> +are handled.\n>> +\n>> +Finally, it updates your branch to point to the final commit with the equivalent\n>> +of `git switch -C <branch>`.\n> \n> Would it make sense to convert this into a bulleted list to further\n> highlight this multi-step process?\n\nNit: ordered list, perhaps? Unless we don’t use those in our manuals (away from documentation at the moment). "},{"id":"523929","messageId":"14d6589c-87a1-4d08-84c1-a9398f6cb8d8@gmail.com","threadId":"63930","inReplyTo":"aJmtzfuibPwS1WVl@pks.im","subject":"Re: [PATCH v4 2/5] doc: git rebase: dedup merge conflict discussion","fromName":"Phillip Wood","fromEmail":"phillip.wood123@gmail.com","sentAt":"2025-08-11T13:02:26Z","receivedAt":"2025-08-11T13:02:03Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"On 11/08/2025 09:46, Patrick Steinhardt wrote:\n> On Sat, Aug 09, 2025 at 01:14:14AM +0000, Julia Evans via GitGitGadget wrote:\n>>   \n>> -It is possible that a merge failure will prevent this process from being\n>> -completely automatic.  You will have to resolve any such merge failure\n>> -and run `git rebase --continue`.  Another option is to bypass the commit\n>> -that caused the merge failure with `git rebase --skip`.  To check out the\n>> -original `<branch>` and remove the `.git/rebase-apply` working files, use\n>> -the command `git rebase --abort` instead.\n>> -\n>>   If the upstream branch already contains a change you have made (e.g.,\n>>   because you mailed a patch which was applied upstream), then that commit\n>>   will be skipped and warnings will be issued (if the 'merge' backend is\n> \n> We lose the bit about `.git/rebase-apply`, but I don't think that's a\n> bad thing. The user shouldn't have to care how exactly a rebase looks on\n> disk.\n\nExactly, we don't want to encourage the user to poke about in the state \ndirectory. Also \".git/rebase-apply\" wont exist unless the user requested \nthe apply backend so mentioning it is misleading (the default is \n\".git/rebase-merge\" these days).\n\nThanks\n\nPhillip\n\n"},{"id":"523930","messageId":"84258154-322c-4ef0-9ebb-44858a5d58fc@gmail.com","threadId":"63930","inReplyTo":"CAOLa=ZSTaAaWJWeXBkoxPx46g_Equo-sHWgCESE9G6vk3HZeqA@mail.gmail.com","subject":"Re: [PATCH v4 1/5] doc: git-rebase: start with an example","fromName":"Phillip Wood","fromEmail":"phillip.wood123@gmail.com","sentAt":"2025-08-11T13:07:43Z","receivedAt":"2025-08-11T13:07:20Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"On 11/08/2025 10:13, Karthik Nayak wrote:\n> \"Julia Evans via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n>> +\n>> +You want to transplant the commits you made on `topic` since it diverged from\n>> +`master` (i.e. A, B, and C), on top of the current `master`.  You can do this\n>> +by running `git rebase master` while the `topic` branch is checked out.  If you\n>> +want to rebase `topic` while on another branch, `git rebase master topic` is a\n>> +shortcut for `git checkout topic && git rebase master`.\n>> +\n> \n> Nit: now that `git-switch(1)` is no longer experimental, we should start\n> recommending it over `git-checkout(1)` as necessary. So perhaps, we\n> could s/checkout/switch here?\n\nJunio has already expressed a preference for \"checkout\" here c.f. \n<xmqqldnte6h3.fsf@gitster.g>. I think that is technically correct as \n\"topic\" can be a commitish and \"git switch <object-id>\" fails without \n\"--detach\". Also rebase does not do any of the extra checks that \"git \nswitch\" does before switching branches (I'm not saying that is \nnecessarily a good thing).\n\nThanks\n\nPhillip\n\n"},{"id":"523933","messageId":"aJn0B-RNjLXjmqKl@pks.im","threadId":"63930","inReplyTo":"FA86B191-AEA6-49AE-A04F-EB736DF4845B@gmail.com","subject":"Re: [PATCH v4 5/5] doc: git-rebase: update discussion of internals","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2025-08-11T13:45:43Z","receivedAt":"2025-08-11T13:45:50Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Mon, Aug 11, 2025 at 08:29:42AM -0400, Ben Knoble wrote:\n> \n> > Le 11 août 2025 à 04:46, Patrick Steinhardt <ps@pks.im> a écrit :\n> > \n> > ﻿On Sat, Aug 09, 2025 at 01:14:17AM +0000, Julia Evans via GitGitGadget wrote:\n> >> diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc\n> >> index 50c84f138212..c16ee37b46a7 100644\n> >> --- a/Documentation/git-rebase.adoc\n> >> +++ b/Documentation/git-rebase.adoc\n> >> @@ -65,31 +65,31 @@ linkgit:git-config[1] for details) and the `--fork-point` option is\n> >> assumed.  If you are currently not on any branch or if the current\n> >> branch does not have a configured upstream, the rebase will abort.\n> >> \n> >> -All changes made by commits in the current branch but that are not\n> >> -in `<upstream>` are saved to a temporary area.  This is the same set\n> >> -of commits that would be shown by `git log <upstream>..HEAD`; or by\n> >> -`git log 'fork_point'..HEAD`, if `--fork-point` is active (see the\n> >> -description on `--fork-point` below); or by `git log HEAD`, if the\n> >> -`--root` option is specified.\n> >> -\n> >> -The current branch is reset to `<upstream>` or `<newbase>` if the\n> >> -`--onto` option was supplied.  This has the exact same effect as\n> >> -`git reset --hard <upstream>` (or `<newbase>`). `ORIG_HEAD` is set\n> >> -to point at the tip of the branch before the reset.\n> >> +Here is a more detailed description of what `git rebase <upstream>` does:\n> >> +\n> >> +First, it makes a list of all commits in the current branch that are not in\n> >> +`<upstream>`. This is the same set of commits that would be shown by `git log\n> >> +<upstream>..HEAD`. You can use `--fork-point` or `--root` to change how this\n> >> +list of commits is constructed.\n> >> +\n> >> +Then it checks out `<upstream>` (or `<newbase>` if the `--onto` option was\n> >> +supplied) with the equivalent of `git switch --detach <upstream>`.\n> >> +\n> >> +Then it replays the commits, one by one, in order. This is similar to running\n> >> +`git cherry-pick <commit>` for each commit. See REBASING MERGES for how merges\n> >> +are handled.\n> >> +\n> >> +Finally, it updates your branch to point to the final commit with the equivalent\n> >> +of `git switch -C <branch>`.\n> > \n> > Would it make sense to convert this into a bulleted list to further\n> > highlight this multi-step process?\n> \n> Nit: ordered list, perhaps? Unless we don’t use those in our manuals\n> (away from documentation at the moment). \n\nAh, I actually wanted to propose using an ordered list, not bulleted list.\nThanks for correcting me.\n\nPatrick\n"},{"id":"523965","messageId":"2c9d7fe5-4026-4143-9c56-f5c56f4634f3@app.fastmail.com","threadId":"63930","inReplyTo":"aJmt1fv66bO_ZMpI@pks.im","subject":"Re: [PATCH v4 5/5] doc: git-rebase: update discussion of internals","fromName":"Julia Evans","fromEmail":"julia@jvns.ca","sentAt":"2025-08-11T19:34:00Z","receivedAt":"2025-08-11T19:34:22Z","isPatch":true,"sender":{"key":"julia@jvns.ca","avatar":"https://avatars.githubusercontent.com/u/817739?v=4"},"body":"> Would it make sense to convert this into a bulleted list to further\n> highlight this multi-step process?\n\nI like this idea. I think we can combine this with Phillip's point about\n\"--reapply-cherry-picks\" to expand the list a little more and remove the\nparagraph at the end about how duplicate commits are skipped. (\"If the upstream\nbranch already contains a change you have made...\") I think probably the diagram\ncan be removed too, I'm not sure how much value it's adding.\n\n1. Make a list of all commits in the current branch that are not in\n   `<upstream>`. This is the same set of commits that would be shown by `git log\n   <upstream>..HEAD`. You can use `--fork-point` or `--root` to change how this\n   list of commits is constructed.\n2. Check whether any of those commits are duplicates of commits already\n   in `<upstream>`, remove them from the list, and print out a warning about\n   each removed commit. You can use `--reapply-cherry-picks` to include\n   duplicate commits.\n3. Check out `<upstream>` (or `<newbase>` if the `--onto` option was\n   supplied) with the equivalent of `git checkout --detach <upstream>`.\n4. Replay the commits, one by one, in order. This is similar to running\n   `git cherry-pick <commit>` for each commit. See REBASING MERGES for how merges\n   are handled.\n5. Update your branch to point to the final commit with the equivalent\n   of `git switch -C <branch>`.\n\nI imagine actually #1 and #2 happen concurrently, but I split them up because\nit felt unwieldy to explain them both the same point.\n\n>\n>>  [NOTE]\n>> +`ORIG_HEAD` is set to point at the tip of the branch before the rebase.\n>>  `ORIG_HEAD` is not guaranteed to still point to the previous branch tip\n>>  at the end of the rebase if other commands that write that pseudo-ref\n>>  (e.g. `git reset`) are used during the rebase. The previous branch tip,\n>>  however, is accessible using the reflog of the current branch\n>>  (i.e. `@{1}`, see linkgit:gitrevisions[7]).\n>\n> This information feels somewhat contradictory. Should we maybe say\n> something like this:\n>\n>     When starting the rebase, `ORIG_HEAD` is set to point to at the tip\n>     of the to-be-rebased branch. As `ORIG_HEAD` may be modified by\n>     various operations during the rebase, it is not guaranteed to still\n>     point to this branch at the end of the rebase. The previous branch\n>     tip, however, is accessible using the reflog of the current branch\n>     (i.e. `@{1}`, see linkgit:gitrevisions[7]).\n>\n> Note that I'm also dropping the reference to \"pseudo-ref\". ORIG_HEAD is\n> not a pseudo-ref, as we have clarified in 6fd8037564\n> (Documentation/glossary: redefine pseudorefs as special refs,\n> 2024-05-15).\n\nI like that! Also very happy to remove the word \"pseudo-ref\".\n\n- Julia\n"},{"id":"523968","messageId":"pull.1949.v5.git.1754943127.gitgitgadget@gmail.com","threadId":"63930","inReplyTo":"pull.1949.v4.git.1754702057.gitgitgadget@gmail.com","subject":"[PATCH v5 0/5] doc: git-rebase: clarify DESCRIPTION section","fromName":"Julia Evans via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-08-11T20:12:02Z","receivedAt":"2025-08-11T20:12:10Z","isPatch":true,"sender":{"key":"julia@jvns.ca","avatar":"https://avatars.githubusercontent.com/u/817739?v=4"},"body":" * Add a note about how you can use git rebase to reorder or combine commits\n * Convert the explanation of how rebase works to an ordered list, make it\n   more accurate (include how duplicate commits are removed), and remove the\n   diagram showing how duplicate commits are removed. I'm happy to bring the\n   diagram back if folks think it's important, but I felt like it made the\n   section end in an awkward way and I'm not sure that \"git rebase removes\n   duplicate commits\" really needs a diagram to explain it.\n\nJulia Evans (5):\n  doc: git-rebase: start with an example\n  doc: git rebase: dedup merge conflict discussion\n  doc: git rebase: clarify arguments syntax\n  doc: git-rebase: move --onto explanation down\n  doc: git-rebase: update discussion of internals\n\n Documentation/git-rebase.adoc | 305 ++++++++++++++++------------------\n 1 file changed, 139 insertions(+), 166 deletions(-)\n\n\nbase-commit: 2c2ba49d55ff26c1082b8137b1ec5eeccb4337d1\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-1949%2Fjvns%2Fclarify-rebase-v5\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1949/jvns/clarify-rebase-v5\nPull-Request: https://github.com/gitgitgadget/git/pull/1949\n\nRange-diff vs v4:\n\n 1:  07a4bdb7ce5 ! 1:  c2f2e05078f doc: git-rebase: start with an example\n     @@ Metadata\n       ## Commit message ##\n          doc: git-rebase: start with an example\n      \n     -    Start with an example that mirrors the example in the `git-merge` man\n     -    page, to make it easier for folks to understand the difference between a\n     -    rebase and a merge.\n     +    - Start with an example that mirrors the example in the `git-merge` man\n     +      page, to make it easier for folks to understand the difference between\n     +      a rebase and a merge.\n     +    - Mention that rebase can combine or reorder commits\n      \n          Signed-off-by: Julia Evans <julia@jvns.ca>\n      \n     @@ Documentation/git-rebase.adoc: SYNOPSIS\n      +                 /\n      +    D---E---F---G master\n      +------------\n     ++\n     ++You can also use `git rebase` to reorder or combine commits: see INTERACTIVE\n     ++MODE below for how to do that.\n      +\n       If `<branch>` is specified, `git rebase` will perform an automatic\n       `git switch <branch>` before doing anything else.  Otherwise\n 2:  061790686b9 ! 2:  5459b7ff560 doc: git rebase: dedup merge conflict discussion\n     @@ Commit message\n      \n       ## Documentation/git-rebase.adoc ##\n      @@ Documentation/git-rebase.adoc: shortcut for `git checkout topic && git rebase master`.\n     -     D---E---F---G master\n     - ------------\n     + You can also use `git rebase` to reorder or combine commits: see INTERACTIVE\n     + MODE below for how to do that.\n       \n      +If there is a merge conflict during this process, `git rebase` will stop at the\n      +first problematic commit and leave conflict markers. If this happens, you can do\n     @@ Documentation/git-rebase.adoc: shortcut for `git checkout topic && git rebase ma\n      +3. Skip the commit that caused the merge conflict with\n      +\n      +   git rebase --skip\n     -+\n      +\n       If `<branch>` is specified, `git rebase` will perform an automatic\n       `git switch <branch>` before doing anything else.  Otherwise\n 3:  fe9e161a51b ! 3:  948c205f1e6 doc: git rebase: clarify arguments syntax\n     @@ Documentation/git-rebase.adoc: one of these things:\n       \n          git rebase --skip\n       \n     --\n      -If `<branch>` is specified, `git rebase` will perform an automatic\n      -`git switch <branch>` before doing anything else.  Otherwise\n      -it remains on the current branch.\n 4:  b37ebc8389d = 4:  e229b9fccb2 doc: git-rebase: move --onto explanation down\n 5:  105a65e6e71 ! 5:  5ab235b067b doc: git-rebase: update discussion of internals\n     @@ Commit message\n          - make it clearer that we're talking about a multistep process\n          - give a more technically accurate description how rebase works with the\n            merge backend.\n     -    - delete a duplicate explanation of how git rebase skips commits with\n     -      the same textual changes (it's explained in more detail a few lines\n     -      further down)\n     +    - condense the explanation of how git rebase skips commits with the same\n     +      textual changes into a single bullet point and remove the explanatory\n     +      diagram. Lots of things which are more complicated are already being\n     +      explained without a diagram.\n          - remove the explanation of how exactly `--fork-point` and `--root`\n            work since that information is in the OPTIONS section\n          - put all discussion of `ORIG_HEAD` inside the note\n     @@ Documentation/git-rebase.adoc: linkgit:git-config[1] for details) and the `--for\n      -to point at the tip of the branch before the reset.\n      +Here is a more detailed description of what `git rebase <upstream>` does:\n      +\n     -+First, it makes a list of all commits in the current branch that are not in\n     -+`<upstream>`. This is the same set of commits that would be shown by `git log\n     -+<upstream>..HEAD`. You can use `--fork-point` or `--root` to change how this\n     -+list of commits is constructed.\n     -+\n     -+Then it checks out `<upstream>` (or `<newbase>` if the `--onto` option was\n     -+supplied) with the equivalent of `git switch --detach <upstream>`.\n     -+\n     -+Then it replays the commits, one by one, in order. This is similar to running\n     -+`git cherry-pick <commit>` for each commit. See REBASING MERGES for how merges\n     -+are handled.\n     -+\n     -+Finally, it updates your branch to point to the final commit with the equivalent\n     -+of `git switch -C <branch>`.\n     ++1. Make a list of all commits in the current branch that are not in\n     ++   `<upstream>`. This is the same set of commits that would be shown by `git log\n     ++   <upstream>..HEAD`. You can use `--fork-point` or `--root` to change how this\n     ++   list of commits is constructed.\n     ++2. Check whether any of those commits are duplicates of commits already\n     ++   in `<upstream>`, remove them from the list, and print out a warning about\n     ++   each removed commit. You can use `--reapply-cherry-picks` to include\n     ++   duplicate commits.\n     ++3. Check out `<upstream>` (or `<newbase>` if the `--onto` option was\n     ++   supplied) with the equivalent of `git checkout --detach <upstream>`.\n     ++4. Replay the commits, one by one, in order. This is similar to running\n     ++   `git cherry-pick <commit>` for each commit. See REBASING MERGES for how merges\n     ++   are handled.\n     ++5. Update your branch to point to the final commit with the equivalent\n     ++   of `git switch -C <branch>`.\n       \n       [NOTE]\n     -+`ORIG_HEAD` is set to point at the tip of the branch before the rebase.\n     - `ORIG_HEAD` is not guaranteed to still point to the previous branch tip\n     - at the end of the rebase if other commands that write that pseudo-ref\n     - (e.g. `git reset`) are used during the rebase. The previous branch tip,\n     - however, is accessible using the reflog of the current branch\n     - (i.e. `@{1}`, see linkgit:gitrevisions[7]).\n     - \n     +-`ORIG_HEAD` is not guaranteed to still point to the previous branch tip\n     +-at the end of the rebase if other commands that write that pseudo-ref\n     +-(e.g. `git reset`) are used during the rebase. The previous branch tip,\n     +-however, is accessible using the reflog of the current branch\n     +-(i.e. `@{1}`, see linkgit:gitrevisions[7]).\n     +-\n      -The commits that were previously saved into the temporary area are\n      -then reapplied to the current branch, one by one, in order. Note that\n      -any commits in `HEAD` which introduce the same textual changes as a commit\n      -in `HEAD..<upstream>` are omitted (i.e., a patch already accepted upstream\n      -with a different commit message or timestamp will be skipped).\n      -\n     - If the upstream branch already contains a change you have made (e.g.,\n     - because you mailed a patch which was applied upstream), then that commit\n     - will be skipped and warnings will be issued (if the 'merge' backend is\n     +-If the upstream branch already contains a change you have made (e.g.,\n     +-because you mailed a patch which was applied upstream), then that commit\n     +-will be skipped and warnings will be issued (if the 'merge' backend is\n     +-used).  For example, running `git rebase master` on the following\n     +-history (in which `A'` and `A` introduce the same set of changes, but\n     +-have different committer information):\n     +-\n     +-------------\n     +-          A---B---C topic\n     +-         /\n     +-    D---E---A'---F master\n     +-------------\n     +-\n     +-will result in:\n     +-\n     +-------------\n     +-                   B'---C' topic\n     +-                  /\n     +-    D---E---A'---F master\n     +-------------\n     ++When starting the rebase, `ORIG_HEAD` is set to point to the commit at the tip\n     ++of the to-be-rebased branch. However, `ORIG_HEAD` is not guaranteed to still\n     ++point to that commit at the end of the rebase if other commands that change\n     ++`ORIG_HEAD` (like `git reset`) are used during the rebase. The previous branch\n     ++tip, however, is accessible using the reflog of the current branch (i.e. `@{1}`,\n     ++see linkgit:gitrevisions[7].\n     + \n     + MODE OPTIONS\n     + ------------\n\n-- \ngitgitgadget\n"},{"id":"523969","messageId":"c2f2e05078f3be604495b53f295e9a8a75f223a7.1754943127.git.gitgitgadget@gmail.com","threadId":"63930","inReplyTo":"pull.1949.v5.git.1754943127.gitgitgadget@gmail.com","subject":"[PATCH v5 1/5] doc: git-rebase: start with an example","fromName":"Julia Evans via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-08-11T20:12:03Z","receivedAt":"2025-08-11T20:12:50Z","isPatch":true,"sender":{"key":"julia@jvns.ca","avatar":"https://avatars.githubusercontent.com/u/817739?v=4"},"body":"From: Julia Evans <julia@jvns.ca>\n\n- Start with an example that mirrors the example in the `git-merge` man\n  page, to make it easier for folks to understand the difference between\n  a rebase and a merge.\n- Mention that rebase can combine or reorder commits\n\nSigned-off-by: Julia Evans <julia@jvns.ca>\n---\n Documentation/git-rebase.adoc | 52 +++++++++++++++++------------------\n 1 file changed, 26 insertions(+), 26 deletions(-)\n\ndiff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc\nindex 956d3048f5a6..03d1b74a9a09 100644\n--- a/Documentation/git-rebase.adoc\n+++ b/Documentation/git-rebase.adoc\n@@ -16,6 +16,32 @@ SYNOPSIS\n \n DESCRIPTION\n -----------\n+Transplant a series of commits onto a different starting point.\n+\n+For example, imagine that you have been working on the `topic` branch in this\n+history, and you want to \"catch up\" to the work done on the `master` branch.\n+\n+------------\n+          A---B---C topic\n+         /\n+    D---E---F---G master\n+------------\n+\n+You want to transplant the commits you made on `topic` since it diverged from\n+`master` (i.e. A, B, and C), on top of the current `master`.  You can do this\n+by running `git rebase master` while the `topic` branch is checked out.  If you\n+want to rebase `topic` while on another branch, `git rebase master topic` is a\n+shortcut for `git checkout topic && git rebase master`.\n+\n+------------\n+                  A'--B'--C' topic\n+                 /\n+    D---E---F---G master\n+------------\n+\n+You can also use `git rebase` to reorder or combine commits: see INTERACTIVE\n+MODE below for how to do that.\n+\n If `<branch>` is specified, `git rebase` will perform an automatic\n `git switch <branch>` before doing anything else.  Otherwise\n it remains on the current branch.\n@@ -58,32 +84,6 @@ that caused the merge failure with `git rebase --skip`.  To check out the\n original `<branch>` and remove the `.git/rebase-apply` working files, use\n the command `git rebase --abort` instead.\n \n-Assume the following history exists and the current branch is \"topic\":\n-\n-------------\n-          A---B---C topic\n-         /\n-    D---E---F---G master\n-------------\n-\n-From this point, the result of either of the following commands:\n-\n-\n-    git rebase master\n-    git rebase master topic\n-\n-would be:\n-\n-------------\n-                  A'--B'--C' topic\n-                 /\n-    D---E---F---G master\n-------------\n-\n-*NOTE:* The latter form is just a short-hand of `git checkout topic`\n-followed by `git rebase master`. When rebase exits `topic` will\n-remain the checked-out branch.\n-\n If the upstream branch already contains a change you have made (e.g.,\n because you mailed a patch which was applied upstream), then that commit\n will be skipped and warnings will be issued (if the 'merge' backend is\n-- \ngitgitgadget\n\n"},{"id":"523970","messageId":"5459b7ff5608580045ac02f27530e4b3919ce00f.1754943127.git.gitgitgadget@gmail.com","threadId":"63930","inReplyTo":"pull.1949.v5.git.1754943127.gitgitgadget@gmail.com","subject":"[PATCH v5 2/5] doc: git rebase: dedup merge conflict discussion","fromName":"Julia Evans via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-08-11T20:12:04Z","receivedAt":"2025-08-11T20:13:15Z","isPatch":true,"sender":{"key":"julia@jvns.ca","avatar":"https://avatars.githubusercontent.com/u/817739?v=4"},"body":"From: Julia Evans <julia@jvns.ca>\n\nPreviously there were two explanations, this combines them both into a\nsingle explanation.\n\nSigned-off-by: Julia Evans <julia@jvns.ca>\n---\n Documentation/git-rebase.adoc | 49 ++++++++++++++---------------------\n 1 file changed, 20 insertions(+), 29 deletions(-)\n\ndiff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc\nindex 03d1b74a9a09..4ba74a8cf9ba 100644\n--- a/Documentation/git-rebase.adoc\n+++ b/Documentation/git-rebase.adoc\n@@ -42,6 +42,26 @@ shortcut for `git checkout topic && git rebase master`.\n You can also use `git rebase` to reorder or combine commits: see INTERACTIVE\n MODE below for how to do that.\n \n+If there is a merge conflict during this process, `git rebase` will stop at the\n+first problematic commit and leave conflict markers. If this happens, you can do\n+one of these things:\n+\n+1. Resolve the conflict. You can use `git diff` to find the markers (<<<<<<)\n+   and make edits to resolve the conflict. For each file you edit, you need to\n+   tell Git that the conflict has been resolved. You can mark the conflict as\n+   resolved with  `git add <filename>`. After resolving all of the conflicts,\n+   you can continue the rebasing process with\n+\n+   git rebase --continue\n+\n+2. Stop the `git rebase` and return your branch to its original state with\n+\n+   git rebase --abort\n+\n+3. Skip the commit that caused the merge conflict with\n+\n+   git rebase --skip\n+\n If `<branch>` is specified, `git rebase` will perform an automatic\n `git switch <branch>` before doing anything else.  Otherwise\n it remains on the current branch.\n@@ -77,13 +97,6 @@ any commits in `HEAD` which introduce the same textual changes as a commit\n in `HEAD..<upstream>` are omitted (i.e., a patch already accepted upstream\n with a different commit message or timestamp will be skipped).\n \n-It is possible that a merge failure will prevent this process from being\n-completely automatic.  You will have to resolve any such merge failure\n-and run `git rebase --continue`.  Another option is to bypass the commit\n-that caused the merge failure with `git rebase --skip`.  To check out the\n-original `<branch>` and remove the `.git/rebase-apply` working files, use\n-the command `git rebase --abort` instead.\n-\n If the upstream branch already contains a change you have made (e.g.,\n because you mailed a patch which was applied upstream), then that commit\n will be skipped and warnings will be issued (if the 'merge' backend is\n@@ -186,28 +199,6 @@ This is useful if F and G were flawed in some way, or should not be\n part of topicA.  Note that the argument to `--onto` and the `<upstream>`\n parameter can be any valid commit-ish.\n \n-In case of conflict, `git rebase` will stop at the first problematic commit\n-and leave conflict markers in the tree.  You can use `git diff` to locate\n-the markers (<<<<<<) and make edits to resolve the conflict.  For each\n-file you edit, you need to tell Git that the conflict has been resolved,\n-typically this would be done with\n-\n-\n-    git add <filename>\n-\n-\n-After resolving the conflict manually and updating the index with the\n-desired resolution, you can continue the rebasing process with\n-\n-\n-    git rebase --continue\n-\n-\n-Alternatively, you can undo the 'git rebase' with\n-\n-\n-    git rebase --abort\n-\n MODE OPTIONS\n ------------\n \n-- \ngitgitgadget\n\n"},{"id":"523971","messageId":"948c205f1e6c005d008030b06e20a4069cd4c50e.1754943127.git.gitgitgadget@gmail.com","threadId":"63930","inReplyTo":"pull.1949.v5.git.1754943127.gitgitgadget@gmail.com","subject":"[PATCH v5 3/5] doc: git rebase: clarify arguments syntax","fromName":"Julia Evans via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-08-11T20:12:05Z","receivedAt":"2025-08-11T20:13:32Z","isPatch":true,"sender":{"key":"julia@jvns.ca","avatar":"https://avatars.githubusercontent.com/u/817739?v=4"},"body":"From: Julia Evans <julia@jvns.ca>\n\nRemove duplicate explanation of `git rebase <upstream> <branch>` which\nis already explained above.\n\nSigned-off-by: Julia Evans <julia@jvns.ca>\n---\n Documentation/git-rebase.adoc | 6 +-----\n 1 file changed, 1 insertion(+), 5 deletions(-)\n\ndiff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc\nindex 4ba74a8cf9ba..117c3f43719f 100644\n--- a/Documentation/git-rebase.adoc\n+++ b/Documentation/git-rebase.adoc\n@@ -62,11 +62,7 @@ one of these things:\n \n    git rebase --skip\n \n-If `<branch>` is specified, `git rebase` will perform an automatic\n-`git switch <branch>` before doing anything else.  Otherwise\n-it remains on the current branch.\n-\n-If `<upstream>` is not specified, the upstream configured in\n+If you don't specify an `<upstream>` to rebase onto, the upstream configured in\n `branch.<name>.remote` and `branch.<name>.merge` options will be used (see\n linkgit:git-config[1] for details) and the `--fork-point` option is\n assumed.  If you are currently not on any branch or if the current\n-- \ngitgitgadget\n\n"},{"id":"523972","messageId":"e229b9fccb20d61853dd7bce457937d186401242.1754943127.git.gitgitgadget@gmail.com","threadId":"63930","inReplyTo":"pull.1949.v5.git.1754943127.gitgitgadget@gmail.com","subject":"[PATCH v5 4/5] doc: git-rebase: move --onto explanation down","fromName":"Julia Evans via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-08-11T20:12:06Z","receivedAt":"2025-08-11T20:13:38Z","isPatch":true,"sender":{"key":"julia@jvns.ca","avatar":"https://avatars.githubusercontent.com/u/817739?v=4"},"body":"From: Julia Evans <julia@jvns.ca>\n\nThere's a very clear explanation with examples of using --onto which is\ncurrently buried in the very long DESCRIPTION section. This moves it to\nits own section, so that we can reference the explanation from the\n`--onto` option by name.\n\nSigned-off-by: Julia Evans <julia@jvns.ca>\n---\n Documentation/git-rebase.adoc | 168 ++++++++++++++++++----------------\n 1 file changed, 87 insertions(+), 81 deletions(-)\n\ndiff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc\nindex 117c3f43719f..750f5e67e4c3 100644\n--- a/Documentation/git-rebase.adoc\n+++ b/Documentation/git-rebase.adoc\n@@ -114,87 +114,6 @@ will result in:\n     D---E---A'---F master\n ------------\n \n-Here is how you would transplant a topic branch based on one\n-branch to another, to pretend that you forked the topic branch\n-from the latter branch, using `rebase --onto`.\n-\n-First let's assume your 'topic' is based on branch 'next'.\n-For example, a feature developed in 'topic' depends on some\n-functionality which is found in 'next'.\n-\n-------------\n-    o---o---o---o---o  master\n-         \\\n-          o---o---o---o---o  next\n-                           \\\n-                            o---o---o  topic\n-------------\n-\n-We want to make 'topic' forked from branch 'master'; for example,\n-because the functionality on which 'topic' depends was merged into the\n-more stable 'master' branch. We want our tree to look like this:\n-\n-------------\n-    o---o---o---o---o  master\n-        |            \\\n-        |             o'--o'--o'  topic\n-         \\\n-          o---o---o---o---o  next\n-------------\n-\n-We can get this using the following command:\n-\n-    git rebase --onto master next topic\n-\n-\n-Another example of --onto option is to rebase part of a\n-branch.  If we have the following situation:\n-\n-------------\n-                            H---I---J topicB\n-                           /\n-                  E---F---G  topicA\n-                 /\n-    A---B---C---D  master\n-------------\n-\n-then the command\n-\n-    git rebase --onto master topicA topicB\n-\n-would result in:\n-\n-------------\n-                 H'--I'--J'  topicB\n-                /\n-                | E---F---G  topicA\n-                |/\n-    A---B---C---D  master\n-------------\n-\n-This is useful when topicB does not depend on topicA.\n-\n-A range of commits could also be removed with rebase.  If we have\n-the following situation:\n-\n-------------\n-    E---F---G---H---I---J  topicA\n-------------\n-\n-then the command\n-\n-    git rebase --onto topicA~5 topicA~3 topicA\n-\n-would result in the removal of commits F and G:\n-\n-------------\n-    E---H'---I'---J'  topicA\n-------------\n-\n-This is useful if F and G were flawed in some way, or should not be\n-part of topicA.  Note that the argument to `--onto` and the `<upstream>`\n-parameter can be any valid commit-ish.\n-\n MODE OPTIONS\n ------------\n \n@@ -240,6 +159,8 @@ As a special case, you may use \"A\\...B\" as a shortcut for the\n merge base of A and B if there is exactly one merge base. You can\n leave out at most one of A and B, in which case it defaults to HEAD.\n \n+See TRANSPLANTING A TOPIC BRANCH WITH --ONTO below for examples.\n+\n --keep-base::\n \tSet the starting point at which to create the new commits to the\n \tmerge base of `<upstream>` and `<branch>`. Running\n@@ -1018,6 +939,91 @@ consistent (they compile, pass the testsuite, etc.) you should use\n after each commit, test, and amend the commit if fixes are necessary.\n \n \n+TRANSPLANTING A TOPIC BRANCH WITH --ONTO\n+----------------------------------------\n+\n+Here is how you would transplant a topic branch based on one\n+branch to another, to pretend that you forked the topic branch\n+from the latter branch, using `rebase --onto`.\n+\n+First let's assume your 'topic' is based on branch 'next'.\n+For example, a feature developed in 'topic' depends on some\n+functionality which is found in 'next'.\n+\n+------------\n+    o---o---o---o---o  master\n+         \\\n+          o---o---o---o---o  next\n+                           \\\n+                            o---o---o  topic\n+------------\n+\n+We want to make 'topic' forked from branch 'master'; for example,\n+because the functionality on which 'topic' depends was merged into the\n+more stable 'master' branch. We want our tree to look like this:\n+\n+------------\n+    o---o---o---o---o  master\n+        |            \\\n+        |             o'--o'--o'  topic\n+         \\\n+          o---o---o---o---o  next\n+------------\n+\n+We can get this using the following command:\n+\n+    git rebase --onto master next topic\n+\n+\n+Another example of --onto option is to rebase part of a\n+branch.  If we have the following situation:\n+\n+------------\n+                            H---I---J topicB\n+                           /\n+                  E---F---G  topicA\n+                 /\n+    A---B---C---D  master\n+------------\n+\n+then the command\n+\n+    git rebase --onto master topicA topicB\n+\n+would result in:\n+\n+------------\n+                 H'--I'--J'  topicB\n+                /\n+                | E---F---G  topicA\n+                |/\n+    A---B---C---D  master\n+------------\n+\n+This is useful when topicB does not depend on topicA.\n+\n+A range of commits could also be removed with rebase.  If we have\n+the following situation:\n+\n+------------\n+    E---F---G---H---I---J  topicA\n+------------\n+\n+then the command\n+\n+    git rebase --onto topicA~5 topicA~3 topicA\n+\n+would result in the removal of commits F and G:\n+\n+------------\n+    E---H'---I'---J'  topicA\n+------------\n+\n+This is useful if F and G were flawed in some way, or should not be\n+part of topicA.  Note that the argument to `--onto` and the `<upstream>`\n+parameter can be any valid commit-ish.\n+\n+\n RECOVERING FROM UPSTREAM REBASE\n -------------------------------\n \n-- \ngitgitgadget\n\n"},{"id":"523973","messageId":"5ab235b067b40e468185ee905f735ff73ccc9552.1754943127.git.gitgitgadget@gmail.com","threadId":"63930","inReplyTo":"pull.1949.v5.git.1754943127.gitgitgadget@gmail.com","subject":"[PATCH v5 5/5] doc: git-rebase: update discussion of internals","fromName":"Julia Evans via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-08-11T20:12:07Z","receivedAt":"2025-08-11T20:13:49Z","isPatch":true,"sender":{"key":"julia@jvns.ca","avatar":"https://avatars.githubusercontent.com/u/817739?v=4"},"body":"From: Julia Evans <julia@jvns.ca>\n\n- make it clearer that we're talking about a multistep process\n- give a more technically accurate description how rebase works with the\n  merge backend.\n- condense the explanation of how git rebase skips commits with the same\n  textual changes into a single bullet point and remove the explanatory\n  diagram. Lots of things which are more complicated are already being\n  explained without a diagram.\n- remove the explanation of how exactly `--fork-point` and `--root`\n  work since that information is in the OPTIONS section\n- put all discussion of `ORIG_HEAD` inside the note\n\nSigned-off-by: Julia Evans <julia@jvns.ca>\n---\n Documentation/git-rebase.adoc | 66 ++++++++++++-----------------------\n 1 file changed, 23 insertions(+), 43 deletions(-)\n\ndiff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc\nindex 750f5e67e4c3..b4e5519d2839 100644\n--- a/Documentation/git-rebase.adoc\n+++ b/Documentation/git-rebase.adoc\n@@ -68,51 +68,31 @@ linkgit:git-config[1] for details) and the `--fork-point` option is\n assumed.  If you are currently not on any branch or if the current\n branch does not have a configured upstream, the rebase will abort.\n \n-All changes made by commits in the current branch but that are not\n-in `<upstream>` are saved to a temporary area.  This is the same set\n-of commits that would be shown by `git log <upstream>..HEAD`; or by\n-`git log 'fork_point'..HEAD`, if `--fork-point` is active (see the\n-description on `--fork-point` below); or by `git log HEAD`, if the\n-`--root` option is specified.\n-\n-The current branch is reset to `<upstream>` or `<newbase>` if the\n-`--onto` option was supplied.  This has the exact same effect as\n-`git reset --hard <upstream>` (or `<newbase>`). `ORIG_HEAD` is set\n-to point at the tip of the branch before the reset.\n+Here is a more detailed description of what `git rebase <upstream>` does:\n+\n+1. Make a list of all commits in the current branch that are not in\n+   `<upstream>`. This is the same set of commits that would be shown by `git log\n+   <upstream>..HEAD`. You can use `--fork-point` or `--root` to change how this\n+   list of commits is constructed.\n+2. Check whether any of those commits are duplicates of commits already\n+   in `<upstream>`, remove them from the list, and print out a warning about\n+   each removed commit. You can use `--reapply-cherry-picks` to include\n+   duplicate commits.\n+3. Check out `<upstream>` (or `<newbase>` if the `--onto` option was\n+   supplied) with the equivalent of `git checkout --detach <upstream>`.\n+4. Replay the commits, one by one, in order. This is similar to running\n+   `git cherry-pick <commit>` for each commit. See REBASING MERGES for how merges\n+   are handled.\n+5. Update your branch to point to the final commit with the equivalent\n+   of `git switch -C <branch>`.\n \n [NOTE]\n-`ORIG_HEAD` is not guaranteed to still point to the previous branch tip\n-at the end of the rebase if other commands that write that pseudo-ref\n-(e.g. `git reset`) are used during the rebase. The previous branch tip,\n-however, is accessible using the reflog of the current branch\n-(i.e. `@{1}`, see linkgit:gitrevisions[7]).\n-\n-The commits that were previously saved into the temporary area are\n-then reapplied to the current branch, one by one, in order. Note that\n-any commits in `HEAD` which introduce the same textual changes as a commit\n-in `HEAD..<upstream>` are omitted (i.e., a patch already accepted upstream\n-with a different commit message or timestamp will be skipped).\n-\n-If the upstream branch already contains a change you have made (e.g.,\n-because you mailed a patch which was applied upstream), then that commit\n-will be skipped and warnings will be issued (if the 'merge' backend is\n-used).  For example, running `git rebase master` on the following\n-history (in which `A'` and `A` introduce the same set of changes, but\n-have different committer information):\n-\n-------------\n-          A---B---C topic\n-         /\n-    D---E---A'---F master\n-------------\n-\n-will result in:\n-\n-------------\n-                   B'---C' topic\n-                  /\n-    D---E---A'---F master\n-------------\n+When starting the rebase, `ORIG_HEAD` is set to point to the commit at the tip\n+of the to-be-rebased branch. However, `ORIG_HEAD` is not guaranteed to still\n+point to that commit at the end of the rebase if other commands that change\n+`ORIG_HEAD` (like `git reset`) are used during the rebase. The previous branch\n+tip, however, is accessible using the reflog of the current branch (i.e. `@{1}`,\n+see linkgit:gitrevisions[7].\n \n MODE OPTIONS\n ------------\n-- \ngitgitgadget\n"},{"id":"523974","messageId":"xmqqpld11t2c.fsf@gitster.g","threadId":"63930","inReplyTo":"c2f2e05078f3be604495b53f295e9a8a75f223a7.1754943127.git.gitgitgadget@gmail.com","subject":"Re: [PATCH v5 1/5] doc: git-rebase: start with an example","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2025-08-11T20:50:35Z","receivedAt":"2025-08-11T20:50:38Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Julia Evans via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n\n> From: Julia Evans <julia@jvns.ca>\n>\n> - Start with an example that mirrors the example in the `git-merge` man\n>   page, to make it easier for folks to understand the difference between\n>   a rebase and a merge.\n> - Mention that rebase can combine or reorder commits\n\nThe new comment added by this second point looks somewhat out of\nplace.  With this patch as-is, the text talks only about the best\ncase of the basic usage, tell the reader to go elsewhere if they are\nnot interested in learning the basic usage, and then switches back\nto the basic usage topic and talks about conflict resolution.\n\nIt may be easier to read if you covered the fact that there are two\nmajor use cases upfront, perhaps like:\n\n    DESCRIPTION\n    -----------\n    Transplant a series of commits onto a different starting point.\n    You can also use `git rebase` to reorder or combine commits: see\n    INTERACTIVE MODE below for how to do that.\n\n    For example, imagine ...\n\n"},{"id":"523984","messageId":"xmqq8qjp1ryo.fsf@gitster.g","threadId":"63930","inReplyTo":"5ab235b067b40e468185ee905f735ff73ccc9552.1754943127.git.gitgitgadget@gmail.com","subject":"Re: [PATCH v5 5/5] doc: git-rebase: update discussion of internals","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2025-08-11T21:14:23Z","receivedAt":"2025-08-11T21:14:26Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Julia Evans via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n\n> From: Julia Evans <julia@jvns.ca>\n>\n> - make it clearer that we're talking about a multistep process\n> - give a more technically accurate description how rebase works with the\n>   merge backend.\n> - condense the explanation of how git rebase skips commits with the same\n>   textual changes into a single bullet point and remove the explanatory\n>   diagram. Lots of things which are more complicated are already being\n>   explained without a diagram.\n> - remove the explanation of how exactly `--fork-point` and `--root`\n>   work since that information is in the OPTIONS section\n> - put all discussion of `ORIG_HEAD` inside the note\n>\n> Signed-off-by: Julia Evans <julia@jvns.ca>\n> ---\n>  Documentation/git-rebase.adoc | 66 ++++++++++++-----------------------\n>  1 file changed, 23 insertions(+), 43 deletions(-)\n>\n> diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc\n> index 750f5e67e4c3..b4e5519d2839 100644\n> --- a/Documentation/git-rebase.adoc\n> +++ b/Documentation/git-rebase.adoc\n> @@ -68,51 +68,31 @@ linkgit:git-config[1] for details) and the `--fork-point` option is\n>  assumed.  If you are currently not on any branch or if the current\n>  branch does not have a configured upstream, the rebase will abort.\n>  \n> -All changes made by commits in the current branch but that are not\n> -in `<upstream>` are saved to a temporary area.  This is the same set\n> -of commits that would be shown by `git log <upstream>..HEAD`; or by\n> -`git log 'fork_point'..HEAD`, if `--fork-point` is active (see the\n> -description on `--fork-point` below); or by `git log HEAD`, if the\n> -`--root` option is specified.\n> -\n> -The current branch is reset to `<upstream>` or `<newbase>` if the\n> -`--onto` option was supplied.  This has the exact same effect as\n> -`git reset --hard <upstream>` (or `<newbase>`). `ORIG_HEAD` is set\n> -to point at the tip of the branch before the reset.\n\n\n\n> +Here is a more detailed description of what `git rebase <upstream>` does:\n\nWere there a sketchy description given elsewhere already?  I\npersonally feel that giving too much details here would not\nnecessarily help readers' understanding.  I'd prefer to see an\nintroduction read more like \"The command conceptually does these\nthings in the following order\", and leave the level of description\nalso to match that introduction.  It may be just me, but when\nsomebody says \"here is a detailed description\", I would expect it to\ncontain little or no white lies mixed in, even for simplicity.\n\nBut of course others may have different opinions ;-)\n\n> +1. Make a list of all commits in the current branch that are not in\n> +   `<upstream>`. This is the same set of commits that would be shown by `git log\n> +   <upstream>..HEAD`. You can use `--fork-point` or `--root` to change how this\n> +   list of commits is constructed.\n\nDidn't somebody mention \"git log --cherry-pick <upstream>..HEAD\"?\nIf omission of it is for simplicity, that is fine, but that is\nanother reason why we do not want to say \"more detaild description\".\n\nAlso, shouldn't there be step #0 that says \"If the <branch> to rebase\nis given, check out that branch and make it current\", for the HEAD\nin this description to work correctly?\n\n> +2. Check whether any of those commits are duplicates of commits already\n> +   in `<upstream>`, remove them from the list, and print out a warning about\n> +   each removed commit. You can use `--reapply-cherry-picks` to include\n> +   duplicate commits.\n\nThis is done as part of #1 above as part of a single invocation of\nrevision walk (i.e. a loop in sequencer.c:sequencer_make_script()\nthat calls get_revision() repeatedly).\n\n> +3. Check out `<upstream>` (or `<newbase>` if the `--onto` option was\n> +   supplied) with the equivalent of `git checkout --detach <upstream>`.\n> +4. Replay the commits, one by one, in order. This is similar to running\n> +   `git cherry-pick <commit>` for each commit. See REBASING MERGES for how merges\n> +   are handled.\n> +5. Update your branch to point to the final commit with the equivalent\n> +   of `git switch -C <branch>`.\n\nIn step #3, you switched to <upstream> with \"git checkout\"; here you\nuse \"git switch\".  Uninitiated readers would wonder what criteria\nwere used to decide which one among these two different commands to\nuse in steps #3 and #5, even though either would work fine.  Because\nthis page is not where readers come to learn about the equivalence\nof these two commands that are not essential to learning \"git\nrebase\", it is better, so once you started with \"git checkout\", to\nstick to it throughout to reduce the mental burden to first-time\nlearners.\n\nThanks.\n"},{"id":"523988","messageId":"pull.1949.v6.git.1754949075.gitgitgadget@gmail.com","threadId":"63930","inReplyTo":"pull.1949.v5.git.1754943127.gitgitgadget@gmail.com","subject":"[PATCH v6 0/5] doc: git-rebase: clarify DESCRIPTION section","fromName":"Julia Evans via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-08-11T21:51:10Z","receivedAt":"2025-08-11T21:51:19Z","isPatch":true,"sender":{"key":"julia@jvns.ca","avatar":"https://avatars.githubusercontent.com/u/817739?v=4"},"body":" * move \"You can also use git rebase to reorder or combine commits:\" to the\n   beginning\n * replace \"detailed description\" with \"simplified description\" -- I thought\n   that I could write something that was relatively readable and also\n   accurate, but as usual Git has proven me wrong :). I tried to leave in\n   the details that I think seem relevant to using git: for example git\n   checkout --detach is relevant because it explains why git reflog works\n   well after a rebase.\n * replace the git switch with git checkout that I'd missed previously\n\nI didn't use the git log --cherry-pick option in the explanation because I\nhad personally never heard of that option before today, and I don't want\npeople to have to read the git log man page to be able to understand the\nexplanation. I also left out --reapply-cherry-picks just because I don't\nunderstand the use case so I couldn't evaluate how likely it is to be\nrelevant to the person reading.\n\nJulia Evans (5):\n  doc: git-rebase: start with an example\n  doc: git rebase: dedup merge conflict discussion\n  doc: git rebase: clarify arguments syntax\n  doc: git-rebase: move --onto explanation down\n  doc: git-rebase: update discussion of internals\n\n Documentation/git-rebase.adoc | 302 +++++++++++++++-------------------\n 1 file changed, 136 insertions(+), 166 deletions(-)\n\n\nbase-commit: 2c2ba49d55ff26c1082b8137b1ec5eeccb4337d1\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-1949%2Fjvns%2Fclarify-rebase-v6\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1949/jvns/clarify-rebase-v6\nPull-Request: https://github.com/gitgitgadget/git/pull/1949\n\nRange-diff vs v5:\n\n 1:  c2f2e05078f ! 1:  e7a8fbbe53c doc: git-rebase: start with an example\n     @@ Documentation/git-rebase.adoc: SYNOPSIS\n       DESCRIPTION\n       -----------\n      +Transplant a series of commits onto a different starting point.\n     ++You can also use `git rebase` to reorder or combine commits: see INTERACTIVE\n     ++MODE below for how to do that.\n      +\n      +For example, imagine that you have been working on the `topic` branch in this\n      +history, and you want to \"catch up\" to the work done on the `master` branch.\n     @@ Documentation/git-rebase.adoc: SYNOPSIS\n      +    D---E---F---G master\n      +------------\n      +\n     -+You can also use `git rebase` to reorder or combine commits: see INTERACTIVE\n     -+MODE below for how to do that.\n      +\n       If `<branch>` is specified, `git rebase` will perform an automatic\n       `git switch <branch>` before doing anything else.  Otherwise\n 2:  5459b7ff560 ! 2:  ad63f69918d doc: git rebase: dedup merge conflict discussion\n     @@ Commit message\n      \n       ## Documentation/git-rebase.adoc ##\n      @@ Documentation/git-rebase.adoc: shortcut for `git checkout topic && git rebase master`.\n     - You can also use `git rebase` to reorder or combine commits: see INTERACTIVE\n     - MODE below for how to do that.\n     + ------------\n     + \n       \n      +If there is a merge conflict during this process, `git rebase` will stop at the\n      +first problematic commit and leave conflict markers. If this happens, you can do\n 3:  948c205f1e6 = 3:  7ee6b0afe88 doc: git rebase: clarify arguments syntax\n 4:  e229b9fccb2 = 4:  4686417b28e doc: git-rebase: move --onto explanation down\n 5:  5ab235b067b ! 5:  9c7f2716bc8 doc: git-rebase: update discussion of internals\n     @@ Documentation/git-rebase.adoc: linkgit:git-config[1] for details) and the `--for\n      -`--onto` option was supplied.  This has the exact same effect as\n      -`git reset --hard <upstream>` (or `<newbase>`). `ORIG_HEAD` is set\n      -to point at the tip of the branch before the reset.\n     -+Here is a more detailed description of what `git rebase <upstream>` does:\n     ++Here is a simplified description of what `git rebase <upstream>` does:\n      +\n     -+1. Make a list of all commits in the current branch that are not in\n     -+   `<upstream>`. This is the same set of commits that would be shown by `git log\n     -+   <upstream>..HEAD`. You can use `--fork-point` or `--root` to change how this\n     -+   list of commits is constructed.\n     ++1. Make a list of all new commits on your current branch since it branched\n     ++   off from `<upstream>`. This is the same set of commits that would be shown\n     ++   by `git log  <upstream>..HEAD`. You can use `--fork-point` or  `--root` to\n     ++   change how this list of commits is constructed.\n      +2. Check whether any of those commits are duplicates of commits already\n     -+   in `<upstream>`, remove them from the list, and print out a warning about\n     -+   each removed commit. You can use `--reapply-cherry-picks` to include\n     -+   duplicate commits.\n     -+3. Check out `<upstream>` (or `<newbase>` if the `--onto` option was\n     -+   supplied) with the equivalent of `git checkout --detach <upstream>`.\n     ++   in `<upstream>` and remove them from the list.\n     ++3. Check out `<upstream>` with the equivalent of `git checkout --detach <upstream>`.\n      +4. Replay the commits, one by one, in order. This is similar to running\n      +   `git cherry-pick <commit>` for each commit. See REBASING MERGES for how merges\n      +   are handled.\n      +5. Update your branch to point to the final commit with the equivalent\n     -+   of `git switch -C <branch>`.\n     ++   of `git checkout -C <branch>`.\n       \n       [NOTE]\n      -`ORIG_HEAD` is not guaranteed to still point to the previous branch tip\n\n-- \ngitgitgadget\n"},{"id":"523989","messageId":"e7a8fbbe53c9cf5cb7b8d822e72ff4219de37e1c.1754949075.git.gitgitgadget@gmail.com","threadId":"63930","inReplyTo":"pull.1949.v6.git.1754949075.gitgitgadget@gmail.com","subject":"[PATCH v6 1/5] doc: git-rebase: start with an example","fromName":"Julia Evans via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-08-11T21:51:11Z","receivedAt":"2025-08-11T21:51:19Z","isPatch":true,"sender":{"key":"julia@jvns.ca","avatar":"https://avatars.githubusercontent.com/u/817739?v=4"},"body":"From: Julia Evans <julia@jvns.ca>\n\n- Start with an example that mirrors the example in the `git-merge` man\n  page, to make it easier for folks to understand the difference between\n  a rebase and a merge.\n- Mention that rebase can combine or reorder commits\n\nSigned-off-by: Julia Evans <julia@jvns.ca>\n---\n Documentation/git-rebase.adoc | 52 +++++++++++++++++------------------\n 1 file changed, 26 insertions(+), 26 deletions(-)\n\ndiff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc\nindex 956d3048f5a6..bb5a3ff7f828 100644\n--- a/Documentation/git-rebase.adoc\n+++ b/Documentation/git-rebase.adoc\n@@ -16,6 +16,32 @@ SYNOPSIS\n \n DESCRIPTION\n -----------\n+Transplant a series of commits onto a different starting point.\n+You can also use `git rebase` to reorder or combine commits: see INTERACTIVE\n+MODE below for how to do that.\n+\n+For example, imagine that you have been working on the `topic` branch in this\n+history, and you want to \"catch up\" to the work done on the `master` branch.\n+\n+------------\n+          A---B---C topic\n+         /\n+    D---E---F---G master\n+------------\n+\n+You want to transplant the commits you made on `topic` since it diverged from\n+`master` (i.e. A, B, and C), on top of the current `master`.  You can do this\n+by running `git rebase master` while the `topic` branch is checked out.  If you\n+want to rebase `topic` while on another branch, `git rebase master topic` is a\n+shortcut for `git checkout topic && git rebase master`.\n+\n+------------\n+                  A'--B'--C' topic\n+                 /\n+    D---E---F---G master\n+------------\n+\n+\n If `<branch>` is specified, `git rebase` will perform an automatic\n `git switch <branch>` before doing anything else.  Otherwise\n it remains on the current branch.\n@@ -58,32 +84,6 @@ that caused the merge failure with `git rebase --skip`.  To check out the\n original `<branch>` and remove the `.git/rebase-apply` working files, use\n the command `git rebase --abort` instead.\n \n-Assume the following history exists and the current branch is \"topic\":\n-\n-------------\n-          A---B---C topic\n-         /\n-    D---E---F---G master\n-------------\n-\n-From this point, the result of either of the following commands:\n-\n-\n-    git rebase master\n-    git rebase master topic\n-\n-would be:\n-\n-------------\n-                  A'--B'--C' topic\n-                 /\n-    D---E---F---G master\n-------------\n-\n-*NOTE:* The latter form is just a short-hand of `git checkout topic`\n-followed by `git rebase master`. When rebase exits `topic` will\n-remain the checked-out branch.\n-\n If the upstream branch already contains a change you have made (e.g.,\n because you mailed a patch which was applied upstream), then that commit\n will be skipped and warnings will be issued (if the 'merge' backend is\n-- \ngitgitgadget\n\n"},{"id":"523990","messageId":"ad63f69918df0130b6b0236d04e27f8529115cd4.1754949075.git.gitgitgadget@gmail.com","threadId":"63930","inReplyTo":"pull.1949.v6.git.1754949075.gitgitgadget@gmail.com","subject":"[PATCH v6 2/5] doc: git rebase: dedup merge conflict discussion","fromName":"Julia Evans via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-08-11T21:51:12Z","receivedAt":"2025-08-11T21:51:21Z","isPatch":true,"sender":{"key":"julia@jvns.ca","avatar":"https://avatars.githubusercontent.com/u/817739?v=4"},"body":"From: Julia Evans <julia@jvns.ca>\n\nPreviously there were two explanations, this combines them both into a\nsingle explanation.\n\nSigned-off-by: Julia Evans <julia@jvns.ca>\n---\n Documentation/git-rebase.adoc | 49 ++++++++++++++---------------------\n 1 file changed, 20 insertions(+), 29 deletions(-)\n\ndiff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc\nindex bb5a3ff7f828..e82ceb9cbfce 100644\n--- a/Documentation/git-rebase.adoc\n+++ b/Documentation/git-rebase.adoc\n@@ -42,6 +42,26 @@ shortcut for `git checkout topic && git rebase master`.\n ------------\n \n \n+If there is a merge conflict during this process, `git rebase` will stop at the\n+first problematic commit and leave conflict markers. If this happens, you can do\n+one of these things:\n+\n+1. Resolve the conflict. You can use `git diff` to find the markers (<<<<<<)\n+   and make edits to resolve the conflict. For each file you edit, you need to\n+   tell Git that the conflict has been resolved. You can mark the conflict as\n+   resolved with  `git add <filename>`. After resolving all of the conflicts,\n+   you can continue the rebasing process with\n+\n+   git rebase --continue\n+\n+2. Stop the `git rebase` and return your branch to its original state with\n+\n+   git rebase --abort\n+\n+3. Skip the commit that caused the merge conflict with\n+\n+   git rebase --skip\n+\n If `<branch>` is specified, `git rebase` will perform an automatic\n `git switch <branch>` before doing anything else.  Otherwise\n it remains on the current branch.\n@@ -77,13 +97,6 @@ any commits in `HEAD` which introduce the same textual changes as a commit\n in `HEAD..<upstream>` are omitted (i.e., a patch already accepted upstream\n with a different commit message or timestamp will be skipped).\n \n-It is possible that a merge failure will prevent this process from being\n-completely automatic.  You will have to resolve any such merge failure\n-and run `git rebase --continue`.  Another option is to bypass the commit\n-that caused the merge failure with `git rebase --skip`.  To check out the\n-original `<branch>` and remove the `.git/rebase-apply` working files, use\n-the command `git rebase --abort` instead.\n-\n If the upstream branch already contains a change you have made (e.g.,\n because you mailed a patch which was applied upstream), then that commit\n will be skipped and warnings will be issued (if the 'merge' backend is\n@@ -186,28 +199,6 @@ This is useful if F and G were flawed in some way, or should not be\n part of topicA.  Note that the argument to `--onto` and the `<upstream>`\n parameter can be any valid commit-ish.\n \n-In case of conflict, `git rebase` will stop at the first problematic commit\n-and leave conflict markers in the tree.  You can use `git diff` to locate\n-the markers (<<<<<<) and make edits to resolve the conflict.  For each\n-file you edit, you need to tell Git that the conflict has been resolved,\n-typically this would be done with\n-\n-\n-    git add <filename>\n-\n-\n-After resolving the conflict manually and updating the index with the\n-desired resolution, you can continue the rebasing process with\n-\n-\n-    git rebase --continue\n-\n-\n-Alternatively, you can undo the 'git rebase' with\n-\n-\n-    git rebase --abort\n-\n MODE OPTIONS\n ------------\n \n-- \ngitgitgadget\n\n"},{"id":"523991","messageId":"7ee6b0afe88fe4f5346776192a0df99c6b64de19.1754949075.git.gitgitgadget@gmail.com","threadId":"63930","inReplyTo":"pull.1949.v6.git.1754949075.gitgitgadget@gmail.com","subject":"[PATCH v6 3/5] doc: git rebase: clarify arguments syntax","fromName":"Julia Evans via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-08-11T21:51:13Z","receivedAt":"2025-08-11T21:51:21Z","isPatch":true,"sender":{"key":"julia@jvns.ca","avatar":"https://avatars.githubusercontent.com/u/817739?v=4"},"body":"From: Julia Evans <julia@jvns.ca>\n\nRemove duplicate explanation of `git rebase <upstream> <branch>` which\nis already explained above.\n\nSigned-off-by: Julia Evans <julia@jvns.ca>\n---\n Documentation/git-rebase.adoc | 6 +-----\n 1 file changed, 1 insertion(+), 5 deletions(-)\n\ndiff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc\nindex e82ceb9cbfce..6d02648a9b3c 100644\n--- a/Documentation/git-rebase.adoc\n+++ b/Documentation/git-rebase.adoc\n@@ -62,11 +62,7 @@ one of these things:\n \n    git rebase --skip\n \n-If `<branch>` is specified, `git rebase` will perform an automatic\n-`git switch <branch>` before doing anything else.  Otherwise\n-it remains on the current branch.\n-\n-If `<upstream>` is not specified, the upstream configured in\n+If you don't specify an `<upstream>` to rebase onto, the upstream configured in\n `branch.<name>.remote` and `branch.<name>.merge` options will be used (see\n linkgit:git-config[1] for details) and the `--fork-point` option is\n assumed.  If you are currently not on any branch or if the current\n-- \ngitgitgadget\n\n"},{"id":"523992","messageId":"4686417b28e4ab386983ad68e4d4d4798a467811.1754949075.git.gitgitgadget@gmail.com","threadId":"63930","inReplyTo":"pull.1949.v6.git.1754949075.gitgitgadget@gmail.com","subject":"[PATCH v6 4/5] doc: git-rebase: move --onto explanation down","fromName":"Julia Evans via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-08-11T21:51:14Z","receivedAt":"2025-08-11T21:51:24Z","isPatch":true,"sender":{"key":"julia@jvns.ca","avatar":"https://avatars.githubusercontent.com/u/817739?v=4"},"body":"From: Julia Evans <julia@jvns.ca>\n\nThere's a very clear explanation with examples of using --onto which is\ncurrently buried in the very long DESCRIPTION section. This moves it to\nits own section, so that we can reference the explanation from the\n`--onto` option by name.\n\nSigned-off-by: Julia Evans <julia@jvns.ca>\n---\n Documentation/git-rebase.adoc | 168 ++++++++++++++++++----------------\n 1 file changed, 87 insertions(+), 81 deletions(-)\n\ndiff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc\nindex 6d02648a9b3c..d041d87f270b 100644\n--- a/Documentation/git-rebase.adoc\n+++ b/Documentation/git-rebase.adoc\n@@ -114,87 +114,6 @@ will result in:\n     D---E---A'---F master\n ------------\n \n-Here is how you would transplant a topic branch based on one\n-branch to another, to pretend that you forked the topic branch\n-from the latter branch, using `rebase --onto`.\n-\n-First let's assume your 'topic' is based on branch 'next'.\n-For example, a feature developed in 'topic' depends on some\n-functionality which is found in 'next'.\n-\n-------------\n-    o---o---o---o---o  master\n-         \\\n-          o---o---o---o---o  next\n-                           \\\n-                            o---o---o  topic\n-------------\n-\n-We want to make 'topic' forked from branch 'master'; for example,\n-because the functionality on which 'topic' depends was merged into the\n-more stable 'master' branch. We want our tree to look like this:\n-\n-------------\n-    o---o---o---o---o  master\n-        |            \\\n-        |             o'--o'--o'  topic\n-         \\\n-          o---o---o---o---o  next\n-------------\n-\n-We can get this using the following command:\n-\n-    git rebase --onto master next topic\n-\n-\n-Another example of --onto option is to rebase part of a\n-branch.  If we have the following situation:\n-\n-------------\n-                            H---I---J topicB\n-                           /\n-                  E---F---G  topicA\n-                 /\n-    A---B---C---D  master\n-------------\n-\n-then the command\n-\n-    git rebase --onto master topicA topicB\n-\n-would result in:\n-\n-------------\n-                 H'--I'--J'  topicB\n-                /\n-                | E---F---G  topicA\n-                |/\n-    A---B---C---D  master\n-------------\n-\n-This is useful when topicB does not depend on topicA.\n-\n-A range of commits could also be removed with rebase.  If we have\n-the following situation:\n-\n-------------\n-    E---F---G---H---I---J  topicA\n-------------\n-\n-then the command\n-\n-    git rebase --onto topicA~5 topicA~3 topicA\n-\n-would result in the removal of commits F and G:\n-\n-------------\n-    E---H'---I'---J'  topicA\n-------------\n-\n-This is useful if F and G were flawed in some way, or should not be\n-part of topicA.  Note that the argument to `--onto` and the `<upstream>`\n-parameter can be any valid commit-ish.\n-\n MODE OPTIONS\n ------------\n \n@@ -240,6 +159,8 @@ As a special case, you may use \"A\\...B\" as a shortcut for the\n merge base of A and B if there is exactly one merge base. You can\n leave out at most one of A and B, in which case it defaults to HEAD.\n \n+See TRANSPLANTING A TOPIC BRANCH WITH --ONTO below for examples.\n+\n --keep-base::\n \tSet the starting point at which to create the new commits to the\n \tmerge base of `<upstream>` and `<branch>`. Running\n@@ -1018,6 +939,91 @@ consistent (they compile, pass the testsuite, etc.) you should use\n after each commit, test, and amend the commit if fixes are necessary.\n \n \n+TRANSPLANTING A TOPIC BRANCH WITH --ONTO\n+----------------------------------------\n+\n+Here is how you would transplant a topic branch based on one\n+branch to another, to pretend that you forked the topic branch\n+from the latter branch, using `rebase --onto`.\n+\n+First let's assume your 'topic' is based on branch 'next'.\n+For example, a feature developed in 'topic' depends on some\n+functionality which is found in 'next'.\n+\n+------------\n+    o---o---o---o---o  master\n+         \\\n+          o---o---o---o---o  next\n+                           \\\n+                            o---o---o  topic\n+------------\n+\n+We want to make 'topic' forked from branch 'master'; for example,\n+because the functionality on which 'topic' depends was merged into the\n+more stable 'master' branch. We want our tree to look like this:\n+\n+------------\n+    o---o---o---o---o  master\n+        |            \\\n+        |             o'--o'--o'  topic\n+         \\\n+          o---o---o---o---o  next\n+------------\n+\n+We can get this using the following command:\n+\n+    git rebase --onto master next topic\n+\n+\n+Another example of --onto option is to rebase part of a\n+branch.  If we have the following situation:\n+\n+------------\n+                            H---I---J topicB\n+                           /\n+                  E---F---G  topicA\n+                 /\n+    A---B---C---D  master\n+------------\n+\n+then the command\n+\n+    git rebase --onto master topicA topicB\n+\n+would result in:\n+\n+------------\n+                 H'--I'--J'  topicB\n+                /\n+                | E---F---G  topicA\n+                |/\n+    A---B---C---D  master\n+------------\n+\n+This is useful when topicB does not depend on topicA.\n+\n+A range of commits could also be removed with rebase.  If we have\n+the following situation:\n+\n+------------\n+    E---F---G---H---I---J  topicA\n+------------\n+\n+then the command\n+\n+    git rebase --onto topicA~5 topicA~3 topicA\n+\n+would result in the removal of commits F and G:\n+\n+------------\n+    E---H'---I'---J'  topicA\n+------------\n+\n+This is useful if F and G were flawed in some way, or should not be\n+part of topicA.  Note that the argument to `--onto` and the `<upstream>`\n+parameter can be any valid commit-ish.\n+\n+\n RECOVERING FROM UPSTREAM REBASE\n -------------------------------\n \n-- \ngitgitgadget\n\n"},{"id":"523993","messageId":"9c7f2716bc8dca2a73f7c8a994ccb8ed4a66fd9a.1754949075.git.gitgitgadget@gmail.com","threadId":"63930","inReplyTo":"pull.1949.v6.git.1754949075.gitgitgadget@gmail.com","subject":"[PATCH v6 5/5] doc: git-rebase: update discussion of internals","fromName":"Julia Evans via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-08-11T21:51:15Z","receivedAt":"2025-08-11T21:51:25Z","isPatch":true,"sender":{"key":"julia@jvns.ca","avatar":"https://avatars.githubusercontent.com/u/817739?v=4"},"body":"From: Julia Evans <julia@jvns.ca>\n\n- make it clearer that we're talking about a multistep process\n- give a more technically accurate description how rebase works with the\n  merge backend.\n- condense the explanation of how git rebase skips commits with the same\n  textual changes into a single bullet point and remove the explanatory\n  diagram. Lots of things which are more complicated are already being\n  explained without a diagram.\n- remove the explanation of how exactly `--fork-point` and `--root`\n  work since that information is in the OPTIONS section\n- put all discussion of `ORIG_HEAD` inside the note\n\nSigned-off-by: Julia Evans <julia@jvns.ca>\n---\n Documentation/git-rebase.adoc | 63 +++++++++++------------------------\n 1 file changed, 20 insertions(+), 43 deletions(-)\n\ndiff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc\nindex d041d87f270b..d4fc80ebb20c 100644\n--- a/Documentation/git-rebase.adoc\n+++ b/Documentation/git-rebase.adoc\n@@ -68,51 +68,28 @@ linkgit:git-config[1] for details) and the `--fork-point` option is\n assumed.  If you are currently not on any branch or if the current\n branch does not have a configured upstream, the rebase will abort.\n \n-All changes made by commits in the current branch but that are not\n-in `<upstream>` are saved to a temporary area.  This is the same set\n-of commits that would be shown by `git log <upstream>..HEAD`; or by\n-`git log 'fork_point'..HEAD`, if `--fork-point` is active (see the\n-description on `--fork-point` below); or by `git log HEAD`, if the\n-`--root` option is specified.\n-\n-The current branch is reset to `<upstream>` or `<newbase>` if the\n-`--onto` option was supplied.  This has the exact same effect as\n-`git reset --hard <upstream>` (or `<newbase>`). `ORIG_HEAD` is set\n-to point at the tip of the branch before the reset.\n+Here is a simplified description of what `git rebase <upstream>` does:\n+\n+1. Make a list of all new commits on your current branch since it branched\n+   off from `<upstream>`. This is the same set of commits that would be shown\n+   by `git log  <upstream>..HEAD`. You can use `--fork-point` or  `--root` to\n+   change how this list of commits is constructed.\n+2. Check whether any of those commits are duplicates of commits already\n+   in `<upstream>` and remove them from the list.\n+3. Check out `<upstream>` with the equivalent of `git checkout --detach <upstream>`.\n+4. Replay the commits, one by one, in order. This is similar to running\n+   `git cherry-pick <commit>` for each commit. See REBASING MERGES for how merges\n+   are handled.\n+5. Update your branch to point to the final commit with the equivalent\n+   of `git checkout -C <branch>`.\n \n [NOTE]\n-`ORIG_HEAD` is not guaranteed to still point to the previous branch tip\n-at the end of the rebase if other commands that write that pseudo-ref\n-(e.g. `git reset`) are used during the rebase. The previous branch tip,\n-however, is accessible using the reflog of the current branch\n-(i.e. `@{1}`, see linkgit:gitrevisions[7]).\n-\n-The commits that were previously saved into the temporary area are\n-then reapplied to the current branch, one by one, in order. Note that\n-any commits in `HEAD` which introduce the same textual changes as a commit\n-in `HEAD..<upstream>` are omitted (i.e., a patch already accepted upstream\n-with a different commit message or timestamp will be skipped).\n-\n-If the upstream branch already contains a change you have made (e.g.,\n-because you mailed a patch which was applied upstream), then that commit\n-will be skipped and warnings will be issued (if the 'merge' backend is\n-used).  For example, running `git rebase master` on the following\n-history (in which `A'` and `A` introduce the same set of changes, but\n-have different committer information):\n-\n-------------\n-          A---B---C topic\n-         /\n-    D---E---A'---F master\n-------------\n-\n-will result in:\n-\n-------------\n-                   B'---C' topic\n-                  /\n-    D---E---A'---F master\n-------------\n+When starting the rebase, `ORIG_HEAD` is set to point to the commit at the tip\n+of the to-be-rebased branch. However, `ORIG_HEAD` is not guaranteed to still\n+point to that commit at the end of the rebase if other commands that change\n+`ORIG_HEAD` (like `git reset`) are used during the rebase. The previous branch\n+tip, however, is accessible using the reflog of the current branch (i.e. `@{1}`,\n+see linkgit:gitrevisions[7].\n \n MODE OPTIONS\n ------------\n-- \ngitgitgadget\n"},{"id":"523995","messageId":"xmqqpld1zfhn.fsf@gitster.g","threadId":"63930","inReplyTo":"pull.1949.v6.git.1754949075.gitgitgadget@gmail.com","subject":"Re: [PATCH v6 0/5] doc: git-rebase: clarify DESCRIPTION section","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2025-08-11T21:59:48Z","receivedAt":"2025-08-11T21:59:51Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Julia Evans via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n\n>  * move \"You can also use git rebase to reorder or combine commits:\" to the\n>    beginning\n>  * replace \"detailed description\" with \"simplified description\" -- I thought\n>    that I could write something that was relatively readable and also\n>    accurate, but as usual Git has proven me wrong :). I tried to leave in\n>    the details that I think seem relevant to using git: for example git\n>    checkout --detach is relevant because it explains why git reflog works\n>    well after a rebase.\n>  * replace the git switch with git checkout that I'd missed previously\n>\n> I didn't use the git log --cherry-pick option in the explanation because I\n> had personally never heard of that option before today, and I don't want\n> people to have to read the git log man page to be able to understand the\n> explanation. I also left out --reapply-cherry-picks just because I don't\n> understand the use case so I couldn't evaluate how likely it is to be\n> relevant to the person reading.\n\nI agree with the above decision to leave unnecessary implementation\ndetails out, and I also agree with the decision to talk about\nrebasing done on the detached HEAD.  I will find out if I agree with\nthe remainder of details that are kept (and left out) later by\nreading the patches ;-)\n\nThanks.\n\n"},{"id":"523997","messageId":"xmqqh5ydzf00.fsf@gitster.g","threadId":"63930","inReplyTo":"9c7f2716bc8dca2a73f7c8a994ccb8ed4a66fd9a.1754949075.git.gitgitgadget@gmail.com","subject":"Re: [PATCH v6 5/5] doc: git-rebase: update discussion of internals","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2025-08-11T22:10:23Z","receivedAt":"2025-08-11T22:10:26Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Julia Evans via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n\n> +Here is a simplified description of what `git rebase <upstream>` does:\n\nNow this is a \"this is roughly how it works\", we can afford to give\na simplified picture that may not exactly match the implementation,\nwhich is great freedom to have while writing documentation for first\ntime users.\n\n> +1. Make a list of all new commits on your current branch since it branched\n> +   off from `<upstream>`. This is the same set of commits that would be shown\n> +   by `git log  <upstream>..HEAD`. You can use `--fork-point` or  `--root` to\n> +   change how this list of commits is constructed.\n> +2. Check whether any of those commits are duplicates of commits already\n> +   in `<upstream>` and remove them from the list.\n\nSo, I do not mind #2 described as a separate step.  Conceptually, it\nis between \"create a list of all commits in the range and filter out\nwhat have already been applied\" and \"create a list of all commits\nthat are not in the upstream yet\".  We may be able to rephrase \"all\nnew commits on your current branch\" somewhat to make it unnecessary\nto describe #2, though.  If we are willing to stop talking about\n\"This is the same set of ...\", then the description becomes very\nsimple:\n\n    Make a list of all commits on your current branch since it\n    branched off from `<upstream>` that do not have equivalent\n    change in `<upstream>`.\n\n> +3. Check out `<upstream>` with the equivalent of `git checkout --detach <upstream>`.\n\nThe line is getting overly long here and a few lines below.  If your\neditor has the feature, tell it to auto-wrap at around 66-72 column.\n\n> +4. Replay the commits, one by one, in order. This is similar to running\n> +   `git cherry-pick <commit>` for each commit. See REBASING MERGES for how merges\n> +   are handled.\n> +5. Update your branch to point to the final commit with the equivalent\n> +   of `git checkout -C <branch>`.\n\nForce-create-branch while checking out is `git checkout -B\n<branch>`, not -C.\n"},{"id":"524005","messageId":"fb35edc9-8c90-4a71-9c75-4c83a8f1718f@app.fastmail.com","threadId":"63930","inReplyTo":"xmqqh5ydzf00.fsf@gitster.g","subject":"Re: [PATCH v6 5/5] doc: git-rebase: update discussion of internals","fromName":"Julia Evans","fromEmail":"julia@jvns.ca","sentAt":"2025-08-11T22:42:15Z","receivedAt":"2025-08-11T22:42:48Z","isPatch":true,"sender":{"key":"julia@jvns.ca","avatar":"https://avatars.githubusercontent.com/u/817739?v=4"},"body":"> So, I do not mind #2 described as a separate step.  Conceptually, it\n> is between \"create a list of all commits in the range and filter out\n> what have already been applied\" and \"create a list of all commits\n> that are not in the upstream yet\".  We may be able to rephrase \"all\n> new commits on your current branch\" somewhat to make it unnecessary\n> to describe #2, though.  If we are willing to stop talking about\n> \"This is the same set of ...\", then the description becomes very\n> simple:\n\nTo me it feels relevant that `git rebase` is using two separate mechanisms to\ncompare commits: the sha and (I think?) what `git patch-id` does. As a user\nit feels like an important distinction because normally when I look at my git\ncommits I only use the sha (via something like `git log --graph`) to see what\nthe new commits on a branch are.\n\nMaybe the second part can be rephrased like this to emphasize that it's using a\ndifferent mechanism than the SHA:\n\n> 2. Check whether any of those commits contain the same changes (according to\n   `git patch-id`) as a commit already in `<upstream>` and remove them from\n   the list.\n\n\n> The line is getting overly long here and a few lines below.  If your\n> editor has the feature, tell it to auto-wrap at around 66-72 column.\n\nWill fix, and I'll add a pre-commit hook to check for that.\n\n> Force-create-branch while checking out is `git checkout -B\n> <branch>`, not -C.\n\nWill fix.\n"},{"id":"524019","messageId":"CAOLa=ZSCJ6NuNPeF7yN63rjgfKojsenGxyO5yfrKkX8TKTdi8Q@mail.gmail.com","threadId":"63930","inReplyTo":"46477AC9-8363-453D-8A57-F599A451D36D@gmail.com","subject":"Re: [PATCH v4 1/5] doc: git-rebase: start with an example","fromName":"Karthik Nayak","fromEmail":"karthik.188@gmail.com","sentAt":"2025-08-12T09:05:30Z","receivedAt":"2025-08-12T09:05:34Z","isPatch":true,"sender":{"key":"karthik.188@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1786334?v=4"},"body":"Ben Knoble <ben.knoble@gmail.com> writes:\n\n>> Le 11 août 2025 à 05:29, Karthik Nayak <karthik.188@gmail.com> a écrit :\n>>\n>> ﻿\"Julia Evans via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n>>>\n>>> Signed-off-by: Julia Evans <julia@jvns.ca>\n>>> ---\n>>> Documentation/git-rebase.adoc | 49 ++++++++++++++++-------------------\n>>> 1 file changed, 23 insertions(+), 26 deletions(-)\n>>>\n>>> diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc\n>>> index 956d3048f5a6..449f01fba560 100644\n>>> --- a/Documentation/git-rebase.adoc\n>>> +++ b/Documentation/git-rebase.adoc\n>>> @@ -16,6 +16,29 @@ SYNOPSIS\n>>>\n>>> DESCRIPTION\n>>> -----------\n>>> +Transplant a series of commits onto a different starting point.\n>>> +\n>>> +For example, imagine that you have been working on the `topic` branch in this\n>>> +history, and you want to \"catch up\" to the work done on the `master` branch.\n>>> +\n>>> +------------\n>>> +          A---B---C topic\n>>> +         /\n>>> +    D---E---F---G master\n>>> +------------\n>>> +\n>>> +You want to transplant the commits you made on `topic` since it diverged from\n>>> +`master` (i.e. A, B, and C), on top of the current `master`.  You can do this\n>>> +by running `git rebase master` while the `topic` branch is checked out.  If you\n>>> +want to rebase `topic` while on another branch, `git rebase master topic` is a\n>>> +shortcut for `git checkout topic && git rebase master`.\n>>> +\n>>\n>> Nit: now that `git-switch(1)` is no longer experimental, we should start\n>> recommending it over `git-checkout(1)` as necessary. So perhaps, we\n>> could s/checkout/switch here?\n>\n> Junio previously recommended checkout (a prior version used switch): I suspect because checkout will detach head without extra syntax (where switch will not)?\n\nI totally missed that, that makes sense!\n"},{"id":"524020","messageId":"CAOLa=ZQwwcfEQNbZqp3o6YfTWMhUr=s0Vw5jP87pUELsktLRaw@mail.gmail.com","threadId":"63930","inReplyTo":"84258154-322c-4ef0-9ebb-44858a5d58fc@gmail.com","subject":"Re: [PATCH v4 1/5] doc: git-rebase: start with an example","fromName":"Karthik Nayak","fromEmail":"karthik.188@gmail.com","sentAt":"2025-08-12T09:07:20Z","receivedAt":"2025-08-12T09:07:22Z","isPatch":true,"sender":{"key":"karthik.188@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1786334?v=4"},"body":"Phillip Wood <phillip.wood123@gmail.com> writes:\n\n> On 11/08/2025 10:13, Karthik Nayak wrote:\n>> \"Julia Evans via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n>>> +\n>>> +You want to transplant the commits you made on `topic` since it diverged from\n>>> +`master` (i.e. A, B, and C), on top of the current `master`.  You can do this\n>>> +by running `git rebase master` while the `topic` branch is checked out.  If you\n>>> +want to rebase `topic` while on another branch, `git rebase master topic` is a\n>>> +shortcut for `git checkout topic && git rebase master`.\n>>> +\n>>\n>> Nit: now that `git-switch(1)` is no longer experimental, we should start\n>> recommending it over `git-checkout(1)` as necessary. So perhaps, we\n>> could s/checkout/switch here?\n>\n> Junio has already expressed a preference for \"checkout\" here c.f.\n> <xmqqldnte6h3.fsf@gitster.g>. I think that is technically correct as\n> \"topic\" can be a commitish and \"git switch <object-id>\" fails without\n> \"--detach\". Also rebase does not do any of the extra checks that \"git\n> switch\" does before switching branches (I'm not saying that is\n> necessarily a good thing).\n>\n\nI missed that, but since we do mention that `topic` is a branch, it\nstill makes sense to use 'git switch'. But either way this is okay.\n\n> Thanks\n>\n> Phillip\n"},{"id":"524038","messageId":"pull.1949.v7.git.1755006568.gitgitgadget@gmail.com","threadId":"63930","inReplyTo":"pull.1949.v6.git.1754949075.gitgitgadget@gmail.com","subject":"[PATCH v7 0/5] doc: git-rebase: clarify DESCRIPTION section","fromName":"Julia Evans via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-08-12T13:49:23Z","receivedAt":"2025-08-12T13:49:32Z","isPatch":true,"sender":{"key":"julia@jvns.ca","avatar":"https://avatars.githubusercontent.com/u/817739?v=4"},"body":" * Rephrase \"duplicates of commits\" to clarify that in step 2, rebase is\n   using git patch-id (or the equivalent) to compare commits instead of\n   using the SHA.\n * wrap some text correctly\n * s/git checkout -C/git checkout -B/\n\nJulia Evans (5):\n  doc: git-rebase: start with an example\n  doc: git rebase: dedup merge conflict discussion\n  doc: git rebase: clarify arguments syntax\n  doc: git-rebase: move --onto explanation down\n  doc: git-rebase: update discussion of internals\n\n Documentation/git-rebase.adoc | 304 +++++++++++++++-------------------\n 1 file changed, 138 insertions(+), 166 deletions(-)\n\n\nbase-commit: 2c2ba49d55ff26c1082b8137b1ec5eeccb4337d1\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-1949%2Fjvns%2Fclarify-rebase-v7\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1949/jvns/clarify-rebase-v7\nPull-Request: https://github.com/gitgitgadget/git/pull/1949\n\nRange-diff vs v6:\n\n 1:  e7a8fbbe53c = 1:  e7a8fbbe53c doc: git-rebase: start with an example\n 2:  ad63f69918d = 2:  ad63f69918d doc: git rebase: dedup merge conflict discussion\n 3:  7ee6b0afe88 = 3:  7ee6b0afe88 doc: git rebase: clarify arguments syntax\n 4:  4686417b28e = 4:  4686417b28e doc: git-rebase: move --onto explanation down\n 5:  9c7f2716bc8 ! 5:  79f29ad1e68 doc: git-rebase: update discussion of internals\n     @@ Documentation/git-rebase.adoc: linkgit:git-config[1] for details) and the `--for\n      +   off from `<upstream>`. This is the same set of commits that would be shown\n      +   by `git log  <upstream>..HEAD`. You can use `--fork-point` or  `--root` to\n      +   change how this list of commits is constructed.\n     -+2. Check whether any of those commits are duplicates of commits already\n     -+   in `<upstream>` and remove them from the list.\n     -+3. Check out `<upstream>` with the equivalent of `git checkout --detach <upstream>`.\n     ++2. Check whether any of those commits contain the same changes (according to\n     ++   `git patch-id`) as a commit already in `<upstream>` and remove them from\n     ++   the list.\n     ++3. Check out `<upstream>` with the equivalent of\n     ++   `git checkout --detach <upstream>`.\n      +4. Replay the commits, one by one, in order. This is similar to running\n      +   `git cherry-pick <commit>` for each commit. See REBASING MERGES for how merges\n      +   are handled.\n      +5. Update your branch to point to the final commit with the equivalent\n     -+   of `git checkout -C <branch>`.\n     ++   of `git checkout -B <branch>`.\n       \n       [NOTE]\n      -`ORIG_HEAD` is not guaranteed to still point to the previous branch tip\n\n-- \ngitgitgadget\n"},{"id":"524039","messageId":"e7a8fbbe53c9cf5cb7b8d822e72ff4219de37e1c.1755006568.git.gitgitgadget@gmail.com","threadId":"63930","inReplyTo":"pull.1949.v7.git.1755006568.gitgitgadget@gmail.com","subject":"[PATCH v7 1/5] doc: git-rebase: start with an example","fromName":"Julia Evans via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-08-12T13:49:24Z","receivedAt":"2025-08-12T13:49:32Z","isPatch":true,"sender":{"key":"julia@jvns.ca","avatar":"https://avatars.githubusercontent.com/u/817739?v=4"},"body":"From: Julia Evans <julia@jvns.ca>\n\n- Start with an example that mirrors the example in the `git-merge` man\n  page, to make it easier for folks to understand the difference between\n  a rebase and a merge.\n- Mention that rebase can combine or reorder commits\n\nSigned-off-by: Julia Evans <julia@jvns.ca>\n---\n Documentation/git-rebase.adoc | 52 +++++++++++++++++------------------\n 1 file changed, 26 insertions(+), 26 deletions(-)\n\ndiff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc\nindex 956d3048f5a6..bb5a3ff7f828 100644\n--- a/Documentation/git-rebase.adoc\n+++ b/Documentation/git-rebase.adoc\n@@ -16,6 +16,32 @@ SYNOPSIS\n \n DESCRIPTION\n -----------\n+Transplant a series of commits onto a different starting point.\n+You can also use `git rebase` to reorder or combine commits: see INTERACTIVE\n+MODE below for how to do that.\n+\n+For example, imagine that you have been working on the `topic` branch in this\n+history, and you want to \"catch up\" to the work done on the `master` branch.\n+\n+------------\n+          A---B---C topic\n+         /\n+    D---E---F---G master\n+------------\n+\n+You want to transplant the commits you made on `topic` since it diverged from\n+`master` (i.e. A, B, and C), on top of the current `master`.  You can do this\n+by running `git rebase master` while the `topic` branch is checked out.  If you\n+want to rebase `topic` while on another branch, `git rebase master topic` is a\n+shortcut for `git checkout topic && git rebase master`.\n+\n+------------\n+                  A'--B'--C' topic\n+                 /\n+    D---E---F---G master\n+------------\n+\n+\n If `<branch>` is specified, `git rebase` will perform an automatic\n `git switch <branch>` before doing anything else.  Otherwise\n it remains on the current branch.\n@@ -58,32 +84,6 @@ that caused the merge failure with `git rebase --skip`.  To check out the\n original `<branch>` and remove the `.git/rebase-apply` working files, use\n the command `git rebase --abort` instead.\n \n-Assume the following history exists and the current branch is \"topic\":\n-\n-------------\n-          A---B---C topic\n-         /\n-    D---E---F---G master\n-------------\n-\n-From this point, the result of either of the following commands:\n-\n-\n-    git rebase master\n-    git rebase master topic\n-\n-would be:\n-\n-------------\n-                  A'--B'--C' topic\n-                 /\n-    D---E---F---G master\n-------------\n-\n-*NOTE:* The latter form is just a short-hand of `git checkout topic`\n-followed by `git rebase master`. When rebase exits `topic` will\n-remain the checked-out branch.\n-\n If the upstream branch already contains a change you have made (e.g.,\n because you mailed a patch which was applied upstream), then that commit\n will be skipped and warnings will be issued (if the 'merge' backend is\n-- \ngitgitgadget\n\n"},{"id":"524043","messageId":"ad63f69918df0130b6b0236d04e27f8529115cd4.1755006568.git.gitgitgadget@gmail.com","threadId":"63930","inReplyTo":"pull.1949.v7.git.1755006568.gitgitgadget@gmail.com","subject":"[PATCH v7 2/5] doc: git rebase: dedup merge conflict discussion","fromName":"Julia Evans via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-08-12T13:49:25Z","receivedAt":"2025-08-12T13:49:33Z","isPatch":true,"sender":{"key":"julia@jvns.ca","avatar":"https://avatars.githubusercontent.com/u/817739?v=4"},"body":"From: Julia Evans <julia@jvns.ca>\n\nPreviously there were two explanations, this combines them both into a\nsingle explanation.\n\nSigned-off-by: Julia Evans <julia@jvns.ca>\n---\n Documentation/git-rebase.adoc | 49 ++++++++++++++---------------------\n 1 file changed, 20 insertions(+), 29 deletions(-)\n\ndiff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc\nindex bb5a3ff7f828..e82ceb9cbfce 100644\n--- a/Documentation/git-rebase.adoc\n+++ b/Documentation/git-rebase.adoc\n@@ -42,6 +42,26 @@ shortcut for `git checkout topic && git rebase master`.\n ------------\n \n \n+If there is a merge conflict during this process, `git rebase` will stop at the\n+first problematic commit and leave conflict markers. If this happens, you can do\n+one of these things:\n+\n+1. Resolve the conflict. You can use `git diff` to find the markers (<<<<<<)\n+   and make edits to resolve the conflict. For each file you edit, you need to\n+   tell Git that the conflict has been resolved. You can mark the conflict as\n+   resolved with  `git add <filename>`. After resolving all of the conflicts,\n+   you can continue the rebasing process with\n+\n+   git rebase --continue\n+\n+2. Stop the `git rebase` and return your branch to its original state with\n+\n+   git rebase --abort\n+\n+3. Skip the commit that caused the merge conflict with\n+\n+   git rebase --skip\n+\n If `<branch>` is specified, `git rebase` will perform an automatic\n `git switch <branch>` before doing anything else.  Otherwise\n it remains on the current branch.\n@@ -77,13 +97,6 @@ any commits in `HEAD` which introduce the same textual changes as a commit\n in `HEAD..<upstream>` are omitted (i.e., a patch already accepted upstream\n with a different commit message or timestamp will be skipped).\n \n-It is possible that a merge failure will prevent this process from being\n-completely automatic.  You will have to resolve any such merge failure\n-and run `git rebase --continue`.  Another option is to bypass the commit\n-that caused the merge failure with `git rebase --skip`.  To check out the\n-original `<branch>` and remove the `.git/rebase-apply` working files, use\n-the command `git rebase --abort` instead.\n-\n If the upstream branch already contains a change you have made (e.g.,\n because you mailed a patch which was applied upstream), then that commit\n will be skipped and warnings will be issued (if the 'merge' backend is\n@@ -186,28 +199,6 @@ This is useful if F and G were flawed in some way, or should not be\n part of topicA.  Note that the argument to `--onto` and the `<upstream>`\n parameter can be any valid commit-ish.\n \n-In case of conflict, `git rebase` will stop at the first problematic commit\n-and leave conflict markers in the tree.  You can use `git diff` to locate\n-the markers (<<<<<<) and make edits to resolve the conflict.  For each\n-file you edit, you need to tell Git that the conflict has been resolved,\n-typically this would be done with\n-\n-\n-    git add <filename>\n-\n-\n-After resolving the conflict manually and updating the index with the\n-desired resolution, you can continue the rebasing process with\n-\n-\n-    git rebase --continue\n-\n-\n-Alternatively, you can undo the 'git rebase' with\n-\n-\n-    git rebase --abort\n-\n MODE OPTIONS\n ------------\n \n-- \ngitgitgadget\n\n"},{"id":"524040","messageId":"7ee6b0afe88fe4f5346776192a0df99c6b64de19.1755006568.git.gitgitgadget@gmail.com","threadId":"63930","inReplyTo":"pull.1949.v7.git.1755006568.gitgitgadget@gmail.com","subject":"[PATCH v7 3/5] doc: git rebase: clarify arguments syntax","fromName":"Julia Evans via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-08-12T13:49:26Z","receivedAt":"2025-08-12T13:49:34Z","isPatch":true,"sender":{"key":"julia@jvns.ca","avatar":"https://avatars.githubusercontent.com/u/817739?v=4"},"body":"From: Julia Evans <julia@jvns.ca>\n\nRemove duplicate explanation of `git rebase <upstream> <branch>` which\nis already explained above.\n\nSigned-off-by: Julia Evans <julia@jvns.ca>\n---\n Documentation/git-rebase.adoc | 6 +-----\n 1 file changed, 1 insertion(+), 5 deletions(-)\n\ndiff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc\nindex e82ceb9cbfce..6d02648a9b3c 100644\n--- a/Documentation/git-rebase.adoc\n+++ b/Documentation/git-rebase.adoc\n@@ -62,11 +62,7 @@ one of these things:\n \n    git rebase --skip\n \n-If `<branch>` is specified, `git rebase` will perform an automatic\n-`git switch <branch>` before doing anything else.  Otherwise\n-it remains on the current branch.\n-\n-If `<upstream>` is not specified, the upstream configured in\n+If you don't specify an `<upstream>` to rebase onto, the upstream configured in\n `branch.<name>.remote` and `branch.<name>.merge` options will be used (see\n linkgit:git-config[1] for details) and the `--fork-point` option is\n assumed.  If you are currently not on any branch or if the current\n-- \ngitgitgadget\n\n"},{"id":"524041","messageId":"4686417b28e4ab386983ad68e4d4d4798a467811.1755006568.git.gitgitgadget@gmail.com","threadId":"63930","inReplyTo":"pull.1949.v7.git.1755006568.gitgitgadget@gmail.com","subject":"[PATCH v7 4/5] doc: git-rebase: move --onto explanation down","fromName":"Julia Evans via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-08-12T13:49:27Z","receivedAt":"2025-08-12T13:49:35Z","isPatch":true,"sender":{"key":"julia@jvns.ca","avatar":"https://avatars.githubusercontent.com/u/817739?v=4"},"body":"From: Julia Evans <julia@jvns.ca>\n\nThere's a very clear explanation with examples of using --onto which is\ncurrently buried in the very long DESCRIPTION section. This moves it to\nits own section, so that we can reference the explanation from the\n`--onto` option by name.\n\nSigned-off-by: Julia Evans <julia@jvns.ca>\n---\n Documentation/git-rebase.adoc | 168 ++++++++++++++++++----------------\n 1 file changed, 87 insertions(+), 81 deletions(-)\n\ndiff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc\nindex 6d02648a9b3c..d041d87f270b 100644\n--- a/Documentation/git-rebase.adoc\n+++ b/Documentation/git-rebase.adoc\n@@ -114,87 +114,6 @@ will result in:\n     D---E---A'---F master\n ------------\n \n-Here is how you would transplant a topic branch based on one\n-branch to another, to pretend that you forked the topic branch\n-from the latter branch, using `rebase --onto`.\n-\n-First let's assume your 'topic' is based on branch 'next'.\n-For example, a feature developed in 'topic' depends on some\n-functionality which is found in 'next'.\n-\n-------------\n-    o---o---o---o---o  master\n-         \\\n-          o---o---o---o---o  next\n-                           \\\n-                            o---o---o  topic\n-------------\n-\n-We want to make 'topic' forked from branch 'master'; for example,\n-because the functionality on which 'topic' depends was merged into the\n-more stable 'master' branch. We want our tree to look like this:\n-\n-------------\n-    o---o---o---o---o  master\n-        |            \\\n-        |             o'--o'--o'  topic\n-         \\\n-          o---o---o---o---o  next\n-------------\n-\n-We can get this using the following command:\n-\n-    git rebase --onto master next topic\n-\n-\n-Another example of --onto option is to rebase part of a\n-branch.  If we have the following situation:\n-\n-------------\n-                            H---I---J topicB\n-                           /\n-                  E---F---G  topicA\n-                 /\n-    A---B---C---D  master\n-------------\n-\n-then the command\n-\n-    git rebase --onto master topicA topicB\n-\n-would result in:\n-\n-------------\n-                 H'--I'--J'  topicB\n-                /\n-                | E---F---G  topicA\n-                |/\n-    A---B---C---D  master\n-------------\n-\n-This is useful when topicB does not depend on topicA.\n-\n-A range of commits could also be removed with rebase.  If we have\n-the following situation:\n-\n-------------\n-    E---F---G---H---I---J  topicA\n-------------\n-\n-then the command\n-\n-    git rebase --onto topicA~5 topicA~3 topicA\n-\n-would result in the removal of commits F and G:\n-\n-------------\n-    E---H'---I'---J'  topicA\n-------------\n-\n-This is useful if F and G were flawed in some way, or should not be\n-part of topicA.  Note that the argument to `--onto` and the `<upstream>`\n-parameter can be any valid commit-ish.\n-\n MODE OPTIONS\n ------------\n \n@@ -240,6 +159,8 @@ As a special case, you may use \"A\\...B\" as a shortcut for the\n merge base of A and B if there is exactly one merge base. You can\n leave out at most one of A and B, in which case it defaults to HEAD.\n \n+See TRANSPLANTING A TOPIC BRANCH WITH --ONTO below for examples.\n+\n --keep-base::\n \tSet the starting point at which to create the new commits to the\n \tmerge base of `<upstream>` and `<branch>`. Running\n@@ -1018,6 +939,91 @@ consistent (they compile, pass the testsuite, etc.) you should use\n after each commit, test, and amend the commit if fixes are necessary.\n \n \n+TRANSPLANTING A TOPIC BRANCH WITH --ONTO\n+----------------------------------------\n+\n+Here is how you would transplant a topic branch based on one\n+branch to another, to pretend that you forked the topic branch\n+from the latter branch, using `rebase --onto`.\n+\n+First let's assume your 'topic' is based on branch 'next'.\n+For example, a feature developed in 'topic' depends on some\n+functionality which is found in 'next'.\n+\n+------------\n+    o---o---o---o---o  master\n+         \\\n+          o---o---o---o---o  next\n+                           \\\n+                            o---o---o  topic\n+------------\n+\n+We want to make 'topic' forked from branch 'master'; for example,\n+because the functionality on which 'topic' depends was merged into the\n+more stable 'master' branch. We want our tree to look like this:\n+\n+------------\n+    o---o---o---o---o  master\n+        |            \\\n+        |             o'--o'--o'  topic\n+         \\\n+          o---o---o---o---o  next\n+------------\n+\n+We can get this using the following command:\n+\n+    git rebase --onto master next topic\n+\n+\n+Another example of --onto option is to rebase part of a\n+branch.  If we have the following situation:\n+\n+------------\n+                            H---I---J topicB\n+                           /\n+                  E---F---G  topicA\n+                 /\n+    A---B---C---D  master\n+------------\n+\n+then the command\n+\n+    git rebase --onto master topicA topicB\n+\n+would result in:\n+\n+------------\n+                 H'--I'--J'  topicB\n+                /\n+                | E---F---G  topicA\n+                |/\n+    A---B---C---D  master\n+------------\n+\n+This is useful when topicB does not depend on topicA.\n+\n+A range of commits could also be removed with rebase.  If we have\n+the following situation:\n+\n+------------\n+    E---F---G---H---I---J  topicA\n+------------\n+\n+then the command\n+\n+    git rebase --onto topicA~5 topicA~3 topicA\n+\n+would result in the removal of commits F and G:\n+\n+------------\n+    E---H'---I'---J'  topicA\n+------------\n+\n+This is useful if F and G were flawed in some way, or should not be\n+part of topicA.  Note that the argument to `--onto` and the `<upstream>`\n+parameter can be any valid commit-ish.\n+\n+\n RECOVERING FROM UPSTREAM REBASE\n -------------------------------\n \n-- \ngitgitgadget\n\n"},{"id":"524042","messageId":"79f29ad1e683f312cd3bbe71909fe5d552b4ae15.1755006568.git.gitgitgadget@gmail.com","threadId":"63930","inReplyTo":"pull.1949.v7.git.1755006568.gitgitgadget@gmail.com","subject":"[PATCH v7 5/5] doc: git-rebase: update discussion of internals","fromName":"Julia Evans via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-08-12T13:49:28Z","receivedAt":"2025-08-12T13:49:36Z","isPatch":true,"sender":{"key":"julia@jvns.ca","avatar":"https://avatars.githubusercontent.com/u/817739?v=4"},"body":"From: Julia Evans <julia@jvns.ca>\n\n- make it clearer that we're talking about a multistep process\n- give a more technically accurate description how rebase works with the\n  merge backend.\n- condense the explanation of how git rebase skips commits with the same\n  textual changes into a single bullet point and remove the explanatory\n  diagram. Lots of things which are more complicated are already being\n  explained without a diagram.\n- remove the explanation of how exactly `--fork-point` and `--root`\n  work since that information is in the OPTIONS section\n- put all discussion of `ORIG_HEAD` inside the note\n\nSigned-off-by: Julia Evans <julia@jvns.ca>\n---\n Documentation/git-rebase.adoc | 65 ++++++++++++-----------------------\n 1 file changed, 22 insertions(+), 43 deletions(-)\n\ndiff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc\nindex d041d87f270b..cce2577a8ade 100644\n--- a/Documentation/git-rebase.adoc\n+++ b/Documentation/git-rebase.adoc\n@@ -68,51 +68,30 @@ linkgit:git-config[1] for details) and the `--fork-point` option is\n assumed.  If you are currently not on any branch or if the current\n branch does not have a configured upstream, the rebase will abort.\n \n-All changes made by commits in the current branch but that are not\n-in `<upstream>` are saved to a temporary area.  This is the same set\n-of commits that would be shown by `git log <upstream>..HEAD`; or by\n-`git log 'fork_point'..HEAD`, if `--fork-point` is active (see the\n-description on `--fork-point` below); or by `git log HEAD`, if the\n-`--root` option is specified.\n-\n-The current branch is reset to `<upstream>` or `<newbase>` if the\n-`--onto` option was supplied.  This has the exact same effect as\n-`git reset --hard <upstream>` (or `<newbase>`). `ORIG_HEAD` is set\n-to point at the tip of the branch before the reset.\n+Here is a simplified description of what `git rebase <upstream>` does:\n+\n+1. Make a list of all new commits on your current branch since it branched\n+   off from `<upstream>`. This is the same set of commits that would be shown\n+   by `git log  <upstream>..HEAD`. You can use `--fork-point` or  `--root` to\n+   change how this list of commits is constructed.\n+2. Check whether any of those commits contain the same changes (according to\n+   `git patch-id`) as a commit already in `<upstream>` and remove them from\n+   the list.\n+3. Check out `<upstream>` with the equivalent of\n+   `git checkout --detach <upstream>`.\n+4. Replay the commits, one by one, in order. This is similar to running\n+   `git cherry-pick <commit>` for each commit. See REBASING MERGES for how merges\n+   are handled.\n+5. Update your branch to point to the final commit with the equivalent\n+   of `git checkout -B <branch>`.\n \n [NOTE]\n-`ORIG_HEAD` is not guaranteed to still point to the previous branch tip\n-at the end of the rebase if other commands that write that pseudo-ref\n-(e.g. `git reset`) are used during the rebase. The previous branch tip,\n-however, is accessible using the reflog of the current branch\n-(i.e. `@{1}`, see linkgit:gitrevisions[7]).\n-\n-The commits that were previously saved into the temporary area are\n-then reapplied to the current branch, one by one, in order. Note that\n-any commits in `HEAD` which introduce the same textual changes as a commit\n-in `HEAD..<upstream>` are omitted (i.e., a patch already accepted upstream\n-with a different commit message or timestamp will be skipped).\n-\n-If the upstream branch already contains a change you have made (e.g.,\n-because you mailed a patch which was applied upstream), then that commit\n-will be skipped and warnings will be issued (if the 'merge' backend is\n-used).  For example, running `git rebase master` on the following\n-history (in which `A'` and `A` introduce the same set of changes, but\n-have different committer information):\n-\n-------------\n-          A---B---C topic\n-         /\n-    D---E---A'---F master\n-------------\n-\n-will result in:\n-\n-------------\n-                   B'---C' topic\n-                  /\n-    D---E---A'---F master\n-------------\n+When starting the rebase, `ORIG_HEAD` is set to point to the commit at the tip\n+of the to-be-rebased branch. However, `ORIG_HEAD` is not guaranteed to still\n+point to that commit at the end of the rebase if other commands that change\n+`ORIG_HEAD` (like `git reset`) are used during the rebase. The previous branch\n+tip, however, is accessible using the reflog of the current branch (i.e. `@{1}`,\n+see linkgit:gitrevisions[7].\n \n MODE OPTIONS\n ------------\n-- \ngitgitgadget\n"},{"id":"524045","messageId":"xmqq7bz8y5my.fsf@gitster.g","threadId":"63930","inReplyTo":"CAOLa=ZSCJ6NuNPeF7yN63rjgfKojsenGxyO5yfrKkX8TKTdi8Q@mail.gmail.com","subject":"Re: [PATCH v4 1/5] doc: git-rebase: start with an example","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2025-08-12T14:30:13Z","receivedAt":"2025-08-12T14:30:16Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Karthik Nayak <karthik.188@gmail.com> writes:\n\n>>> Nit: now that `git-switch(1)` is no longer experimental, we should start\n>>> recommending it over `git-checkout(1)` as necessary. So perhaps, we\n>>> could s/checkout/switch here?\n\nBesides, the reason why it is no longer experimental is *not*\nbecause it has proved to be so much better than \"checkout\" and the\nusers are encouraged to use it.\n\nIt is no longer experimental only because it and its set of options\nare now engraved in users' mustle memory deep enough that we can no\nlonger change it without disrupting users.  We were hoping to\nimprove its end-user experience relative to \"checkout\", and allowed\nit to deviate from the precendent that was set by \"git checkout\",\nand that was the reason why \"this is experimental. UI and behaviour\nis subject to change\" label was on it.\n\nThe experiment unfortunately was not a great success.  There were\nonly a few meaningful differences invented during the experiment.\n"},{"id":"524073","messageId":"CALnO6CBqChfU62TJuk9mBd=gSbPKDEyBKv8r-rCygsRDD2yALQ@mail.gmail.com","threadId":"63930","inReplyTo":"CAOLa=ZQwwcfEQNbZqp3o6YfTWMhUr=s0Vw5jP87pUELsktLRaw@mail.gmail.com","subject":"Re: [PATCH v4 1/5] doc: git-rebase: start with an example","fromName":"D. Ben Knoble","fromEmail":"ben.knoble@gmail.com","sentAt":"2025-08-12T17:07:48Z","receivedAt":"2025-08-12T17:08:01Z","isPatch":true,"sender":{"key":"ben.knoble@gmail.com","avatar":"https://avatars.githubusercontent.com/u/22802209?v=4"},"body":"On Tue, Aug 12, 2025 at 5:11 AM Karthik Nayak <karthik.188@gmail.com> wrote:\n>\n> Phillip Wood <phillip.wood123@gmail.com> writes:\n>\n> > On 11/08/2025 10:13, Karthik Nayak wrote:\n> >> \"Julia Evans via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n> >>> +\n> >>> +You want to transplant the commits you made on `topic` since it diverged from\n> >>> +`master` (i.e. A, B, and C), on top of the current `master`.  You can do this\n> >>> +by running `git rebase master` while the `topic` branch is checked out.  If you\n> >>> +want to rebase `topic` while on another branch, `git rebase master topic` is a\n> >>> +shortcut for `git checkout topic && git rebase master`.\n> >>> +\n> >>\n> >> Nit: now that `git-switch(1)` is no longer experimental, we should start\n> >> recommending it over `git-checkout(1)` as necessary. So perhaps, we\n> >> could s/checkout/switch here?\n> >\n> > Junio has already expressed a preference for \"checkout\" here c.f.\n> > <xmqqldnte6h3.fsf@gitster.g>. I think that is technically correct as\n> > \"topic\" can be a commitish and \"git switch <object-id>\" fails without\n> > \"--detach\". Also rebase does not do any of the extra checks that \"git\n> > switch\" does before switching branches (I'm not saying that is\n> > necessarily a good thing).\n> >\n>\n> I missed that, but since we do mention that `topic` is a branch, it\n> still makes sense to use 'git switch'. But either way this is okay.\n\nIn the general case, it may not be a branch though. (Of course, that's\ntoo confusing a detail for this section anyway.)\n\n-- \nD. Ben Knoble\n"},{"id":"524078","messageId":"xmqqfrdwtnvq.fsf@gitster.g","threadId":"63930","inReplyTo":"CALnO6CBqChfU62TJuk9mBd=gSbPKDEyBKv8r-rCygsRDD2yALQ@mail.gmail.com","subject":"Re: [PATCH v4 1/5] doc: git-rebase: start with an example","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2025-08-12T18:07:21Z","receivedAt":"2025-08-12T18:07:24Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"D. Ben Knoble\" <ben.knoble@gmail.com> writes:\n\n>> > Junio has already expressed a preference for \"checkout\" here c.f.\n>> > <xmqqldnte6h3.fsf@gitster.g>. I think that is technically correct as\n>> > \"topic\" can be a commitish and \"git switch <object-id>\" fails without\n>> > \"--detach\".\n\nI wanted the new documentation text to use what was already used in\nthe parts of the document that are not touched; otherwise we end up\nwith text that uses checkout in some places and switch in others,\nwhich would invite confusions among uninitiated readers, who\nrightfully would wonder what criteria were used to decide which one\namong these two different commands to use.  And teaching that these\ntwo commands are quasi-equivalent with possibly subtle differences\nis not what the documentation of \"git rebase\" needs to do---it is a\ndistraction.\n\nI do not mind a new proposal to do a documentation sweep, aiming for\nGit 3.0 timeframe, to examine all mentions of \"git checkout\" in the\ndocumentation and replace them with \"git switch\" or \"git restore\"\nwhen appropriate (there are of course ones that are not for obvious\nreasons, like the ones in \"git checkout\" documentation itself, and\npossibly in \"git switch\" and \"git restore\" documentation pages that\nmay say things like \"'git switch X' is similar to 'git checkout Y'\").\n\nBut let's leave that outside this topic.\n\nThanks.\n\n"},{"id":"524124","messageId":"52504ef0-7d4c-4298-af11-10477673e9d0@gmail.com","threadId":"63930","inReplyTo":"pull.1949.v6.git.1754949075.gitgitgadget@gmail.com","subject":"Re: [PATCH v6 0/5] doc: git-rebase: clarify DESCRIPTION section","fromName":"Phillip Wood","fromEmail":"phillip.wood123@gmail.com","sentAt":"2025-08-13T13:31:32Z","receivedAt":"2025-08-13T13:31:37Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"Hi Julia\n\nOn 11/08/2025 22:51, Julia Evans via GitGitGadget wrote:\n>   * move \"You can also use git rebase to reorder or combine commits:\" to the\n>     beginning\n\nGreat\n\n>   * replace \"detailed description\" with \"simplified description\" -- I thought\n>     that I could write something that was relatively readable and also\n>     accurate, but as usual Git has proven me wrong :). I tried to leave in\n>     the details that I think seem relevant to using git: for example git\n>     checkout --detach is relevant because it explains why git reflog works\n>     well after a rebase.\n>   * replace the git switch with git checkout that I'd missed previously\n> \n> I didn't use the git log --cherry-pick option in the explanation because I\n> had personally never heard of that option before today, and I don't want\n> people to have to read the git log man page to be able to understand the\n> explanation. I also left out --reapply-cherry-picks just because I don't\n> understand the use case so I couldn't evaluate how likely it is to be\n> relevant to the person reading.\nThe use case for --reapply-cherry-picks is mostly that it is faster to \ntry picking a commit and then drop it if it results in a empty change \nthan it is to do the patch-id comparisons to avoid picking the commit in \nthe first place. This is especially true on partial clones where the \ncherry-pick detection is really slow. I'm happy to leave it out but I \nwonder if we should drop the references to --fork-point and --root as \nwell given they're also both pretty niche. I'd also be very happy to go \nwith Junio's suggestion to replace steps 1 & 2 with a general \ndescription that does not mention 'git log' at all.\n\nThanks\n\nPhillip\n\n> \n> Julia Evans (5):\n>    doc: git-rebase: start with an example\n>    doc: git rebase: dedup merge conflict discussion\n>    doc: git rebase: clarify arguments syntax\n>    doc: git-rebase: move --onto explanation down\n>    doc: git-rebase: update discussion of internals\n> \n>   Documentation/git-rebase.adoc | 302 +++++++++++++++-------------------\n>   1 file changed, 136 insertions(+), 166 deletions(-)\n> \n> \n> base-commit: 2c2ba49d55ff26c1082b8137b1ec5eeccb4337d1\n> Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1949%2Fjvns%2Fclarify-rebase-v6\n> Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1949/jvns/clarify-rebase-v6\n> Pull-Request: https://github.com/gitgitgadget/git/pull/1949\n> \n> Range-diff vs v5:\n> \n>   1:  c2f2e05078f ! 1:  e7a8fbbe53c doc: git-rebase: start with an example\n>       @@ Documentation/git-rebase.adoc: SYNOPSIS\n>         DESCRIPTION\n>         -----------\n>        +Transplant a series of commits onto a different starting point.\n>       ++You can also use `git rebase` to reorder or combine commits: see INTERACTIVE\n>       ++MODE below for how to do that.\n>        +\n>        +For example, imagine that you have been working on the `topic` branch in this\n>        +history, and you want to \"catch up\" to the work done on the `master` branch.\n>       @@ Documentation/git-rebase.adoc: SYNOPSIS\n>        +    D---E---F---G master\n>        +------------\n>        +\n>       -+You can also use `git rebase` to reorder or combine commits: see INTERACTIVE\n>       -+MODE below for how to do that.\n>        +\n>         If `<branch>` is specified, `git rebase` will perform an automatic\n>         `git switch <branch>` before doing anything else.  Otherwise\n>   2:  5459b7ff560 ! 2:  ad63f69918d doc: git rebase: dedup merge conflict discussion\n>       @@ Commit message\n>        \n>         ## Documentation/git-rebase.adoc ##\n>        @@ Documentation/git-rebase.adoc: shortcut for `git checkout topic && git rebase master`.\n>       - You can also use `git rebase` to reorder or combine commits: see INTERACTIVE\n>       - MODE below for how to do that.\n>       + ------------\n>       +\n>         \n>        +If there is a merge conflict during this process, `git rebase` will stop at the\n>        +first problematic commit and leave conflict markers. If this happens, you can do\n>   3:  948c205f1e6 = 3:  7ee6b0afe88 doc: git rebase: clarify arguments syntax\n>   4:  e229b9fccb2 = 4:  4686417b28e doc: git-rebase: move --onto explanation down\n>   5:  5ab235b067b ! 5:  9c7f2716bc8 doc: git-rebase: update discussion of internals\n>       @@ Documentation/git-rebase.adoc: linkgit:git-config[1] for details) and the `--for\n>        -`--onto` option was supplied.  This has the exact same effect as\n>        -`git reset --hard <upstream>` (or `<newbase>`). `ORIG_HEAD` is set\n>        -to point at the tip of the branch before the reset.\n>       -+Here is a more detailed description of what `git rebase <upstream>` does:\n>       ++Here is a simplified description of what `git rebase <upstream>` does:\n>        +\n>       -+1. Make a list of all commits in the current branch that are not in\n>       -+   `<upstream>`. This is the same set of commits that would be shown by `git log\n>       -+   <upstream>..HEAD`. You can use `--fork-point` or `--root` to change how this\n>       -+   list of commits is constructed.\n>       ++1. Make a list of all new commits on your current branch since it branched\n>       ++   off from `<upstream>`. This is the same set of commits that would be shown\n>       ++   by `git log  <upstream>..HEAD`. You can use `--fork-point` or  `--root` to\n>       ++   change how this list of commits is constructed.\n>        +2. Check whether any of those commits are duplicates of commits already\n>       -+   in `<upstream>`, remove them from the list, and print out a warning about\n>       -+   each removed commit. You can use `--reapply-cherry-picks` to include\n>       -+   duplicate commits.\n>       -+3. Check out `<upstream>` (or `<newbase>` if the `--onto` option was\n>       -+   supplied) with the equivalent of `git checkout --detach <upstream>`.\n>       ++   in `<upstream>` and remove them from the list.\n>       ++3. Check out `<upstream>` with the equivalent of `git checkout --detach <upstream>`.\n>        +4. Replay the commits, one by one, in order. This is similar to running\n>        +   `git cherry-pick <commit>` for each commit. See REBASING MERGES for how merges\n>        +   are handled.\n>        +5. Update your branch to point to the final commit with the equivalent\n>       -+   of `git switch -C <branch>`.\n>       ++   of `git checkout -C <branch>`.\n>         \n>         [NOTE]\n>        -`ORIG_HEAD` is not guaranteed to still point to the previous branch tip\n> \n\n"},{"id":"524132","messageId":"aa1c2758-79f9-47f6-87d4-16b19fa5bd63@app.fastmail.com","threadId":"63930","inReplyTo":"52504ef0-7d4c-4298-af11-10477673e9d0@gmail.com","subject":"Re: [PATCH v6 0/5] doc: git-rebase: clarify DESCRIPTION section","fromName":"Julia Evans","fromEmail":"julia@jvns.ca","sentAt":"2025-08-13T15:33:11Z","receivedAt":"2025-08-13T15:33:33Z","isPatch":true,"sender":{"key":"julia@jvns.ca","avatar":"https://avatars.githubusercontent.com/u/817739?v=4"},"body":"> The use case for --reapply-cherry-picks is mostly that it is faster to \n> try picking a commit and then drop it if it results in a empty change \n> than it is to do the patch-id comparisons to avoid picking the commit in \n> the first place. This is especially true on partial clones where the \n> cherry-pick detection is really slow.\n\nThat makes sense, thank you!\n\n> I'm happy to leave it out but I \n> wonder if we should drop the references to --fork-point and --root as \n> well given they're also both pretty niche. I'd also be very happy to go \n> with Junio's suggestion to replace steps 1 & 2 with a general \n> description that does not mention 'git log' at all.\n\nI like the idea of leaving out `--fork-point` and `--root`.\n\nNow that I know the use case for `--reapply-cherry-picks`: what I like about\nleaving in the `git log` description is that I think it makes it easier for\nfolks to build a mental model of why a `git rebase` might  be slow: there's a\n\"fast step\" (the `git log` step) and a \"slow step\" (the `git patch-id` step).\nThen even if we don't mention `--reapply-cherry-picks` in this section, a user\ncould infer that there might be a way to speed up the \"slow step\", and find the\n`--reapply-cherry-picks` option to speed it up. Maybe we could mention that the\n`git patch-id` step can be slow in some cases.\n\n(also I might have misunderstood the \"fast step\" and the \"slow step\" thing,\nI'd be interested to know if so)\n"},{"id":"524147","messageId":"CALnO6CBOWTCd-cREfGYL8DPPd=S-s3Y6s0cgwvBzCJZr6E6hvA@mail.gmail.com","threadId":"63930","inReplyTo":"10372e00-3bb1-453a-bb62-332aaa935b24@gmail.com","subject":"symmetric difference with --left-only vs. range notation","fromName":"D. Ben Knoble","fromEmail":"ben.knoble@gmail.com","sentAt":"2025-08-13T18:55:30Z","receivedAt":"2025-08-13T18:55:43Z","isPatch":false,"sender":{"key":"ben.knoble@gmail.com","avatar":"https://avatars.githubusercontent.com/u/22802209?v=4"},"body":"On Sun, Aug 10, 2025 at 11:42 AM Phillip Wood <phillip.wood123@gmail.com> wrote:\n>\n> Hi Julia\n>\n> On 09/08/2025 02:14, Julia Evans via GitGitGadget wrote:\n> > From: Julia Evans <julia@jvns.ca>\n> >\n> > +Here is a more detailed description of what `git rebase <upstream>` does:\n> > +\n> > +First, it makes a list of all commits in the current branch that are not in\n> > +`<upstream>`. This is the same set of commits that would be shown by `git log\n> > +<upstream>..HEAD`.\n>\n> The existing text is not quite accurate here, it should really say `git\n> log --cherry-pick --right-only <upstream>...HEAD` as we drop any commits\n> from the branch that have already been cherry-picked to <upstream>.\n\nThis reminds me, I've been meaning to ask: is there a meaningful\ndifference between the following 2 commands?\n\n    git rev-list --count --left-only @{u}...\n    git rev-list --count ..@{u}\n\nIn my estimation, since we're not using --cherry-pick here, the first\nsays \"list (count) the commits on upstream but not in HEAD, since the\nmerge-base (which is reachable from both)\" while the second says \"list\n(count) the commits on upstream but not in HEAD.\" Is there ever a\nsituation where those sets aren't the same?\n\nOf course the symmetric difference is not always the same as the range\nnotation, but when we add --left-only [or --right-only, by symmetry\n;)], does this collapse to the 2-dot notation?\n\nI've been assuming the latter is more performant, too, but if that's\nnot the case, that's also good to know.\n"},{"id":"524154","messageId":"xmqq8qjmc33y.fsf@gitster.g","threadId":"63930","inReplyTo":"CALnO6CBOWTCd-cREfGYL8DPPd=S-s3Y6s0cgwvBzCJZr6E6hvA@mail.gmail.com","subject":"Re: symmetric difference with --left-only vs. range notation","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2025-08-13T21:40:17Z","receivedAt":"2025-08-13T21:40:21Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"D. Ben Knoble\" <ben.knoble@gmail.com> writes:\n\n>     git rev-list --count --left-only @{u}...\n>     git rev-list --count ..@{u}\n>\n> In my estimation, since we're not using --cherry-pick here, the first\n> says \"list (count) the commits on upstream but not in HEAD, since the\n> merge-base (which is reachable from both)\" while the second says \"list\n> (count) the commits on upstream but not in HEAD.\" Is there ever a\n> situation where those sets aren't the same?\n\nI don't think of any; let us know when you find a case that the\nabove does not hold true ;-).\n"},{"id":"524168","messageId":"CAOLa=ZQa9pNsTasx6oxN54Xiz37_o+qjikZVOJpyyBr9c16gAw@mail.gmail.com","threadId":"63930","inReplyTo":"xmqqfrdwtnvq.fsf@gitster.g","subject":"Re: [PATCH v4 1/5] doc: git-rebase: start with an example","fromName":"Karthik Nayak","fromEmail":"karthik.188@gmail.com","sentAt":"2025-08-14T07:23:33Z","receivedAt":"2025-08-14T07:23:35Z","isPatch":true,"sender":{"key":"karthik.188@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1786334?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> \"D. Ben Knoble\" <ben.knoble@gmail.com> writes:\n>\n>>> > Junio has already expressed a preference for \"checkout\" here c.f.\n>>> > <xmqqldnte6h3.fsf@gitster.g>. I think that is technically correct as\n>>> > \"topic\" can be a commitish and \"git switch <object-id>\" fails without\n>>> > \"--detach\".\n>\n> I wanted the new documentation text to use what was already used in\n> the parts of the document that are not touched; otherwise we end up\n> with text that uses checkout in some places and switch in others,\n> which would invite confusions among uninitiated readers, who\n> rightfully would wonder what criteria were used to decide which one\n> among these two different commands to use.  And teaching that these\n> two commands are quasi-equivalent with possibly subtle differences\n> is not what the documentation of \"git rebase\" needs to do---it is a\n> distraction.\n>\n> I do not mind a new proposal to do a documentation sweep, aiming for\n> Git 3.0 timeframe, to examine all mentions of \"git checkout\" in the\n> documentation and replace them with \"git switch\" or \"git restore\"\n> when appropriate (there are of course ones that are not for obvious\n> reasons, like the ones in \"git checkout\" documentation itself, and\n> possibly in \"git switch\" and \"git restore\" documentation pages that\n> may say things like \"'git switch X' is similar to 'git checkout Y'\").\n>\n\nI think this is the best way to tackle this.\n\n> But let's leave that outside this topic.\n>\n\nAgreed.\n\n> Thanks.\n"},{"id":"524186","messageId":"xmqq5xepzjnu.fsf@gitster.g","threadId":"63930","inReplyTo":"aa1c2758-79f9-47f6-87d4-16b19fa5bd63@app.fastmail.com","subject":"Re: [PATCH v6 0/5] doc: git-rebase: clarify DESCRIPTION section","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2025-08-14T21:18:45Z","receivedAt":"2025-08-14T21:18:48Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Julia Evans\" <julia@jvns.ca> writes:\n\n>> well given they're also both pretty niche. I'd also be very happy to go \n>> with Junio's suggestion to replace steps 1 & 2 with a general \n>> description that does not mention 'git log' at all.\n>\n> I like the idea of leaving out `--fork-point` and `--root`.\n>\n> Now that I know the use case for `--reapply-cherry-picks`: what I like about\n> leaving in the `git log` description is that I think it makes it easier for\n> folks to build a mental model of why a `git rebase` might be slow: there's a\n> \"fast step\" (the `git log` step) and a \"slow step\" (the `git patch-id` step).\n\nBut that is not what goes on, is it?  What you wrote as if they were\ntwo separate steps (1 to enumerate, 2 to filter) is not what happens\nin practice.  Whether it is done via the \"format-patch --stdout | am\"\npipeline in run_am(), or via the \"rev-list --reverse | xargs -n1\ncherry-pick\" pipeline in run_sequencer_rebase(), the upstream of\nthese conceptual pipelines that enumerates what is to be replayed is\nrun just once, i.e. there is only one step that \"enumerates what is\nto be replayed\", without a separate filtering step.\n\nIn other words, there is no \"a fast step followed by a slow step\".\n\nPerhaps squashing the first two steps into one and phrasing them as\na single step is sufficient to give a conceptual overview (what you\nhave in v7 as \"a simplified description of what the command does\").\n\n 1. Make a list of all commits on your current branch since it\n    branched off from `<upstream>` that do not have equivalent\n    change in `<upstream>`.\n\nIf you want to keep 1 & 2 separate, then rephrase the introductory\nsentence to clarify that we are giving a white lie for the sake of\neasier understanding, e.g.\n\n    Here is what conceptually happens in \"git rebase\":\n\nor something.\n"},{"id":"524187","messageId":"xmqq1ppdzj76.fsf@gitster.g","threadId":"63930","inReplyTo":"79f29ad1e683f312cd3bbe71909fe5d552b4ae15.1755006568.git.gitgitgadget@gmail.com","subject":"Re: [PATCH v7 5/5] doc: git-rebase: update discussion of internals","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2025-08-14T21:28:45Z","receivedAt":"2025-08-14T21:28:47Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Julia Evans via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n\n> +Here is a simplified description of what `git rebase <upstream>` does:\n> +\n> +1. Make a list of all new commits on your current branch since it branched\n> +   off from `<upstream>`. This is the same set of commits that would be shown\n> +   by `git log  <upstream>..HEAD`. You can use `--fork-point` or  `--root` to\n> +   change how this list of commits is constructed.\n> +2. Check whether any of those commits contain the same changes (according to\n> +   `git patch-id`) as a commit already in `<upstream>` and remove them from\n> +   the list.\n\nI'd suggest three things\n\n * Rewrite the introductory text to\n\n    Here is what \"git rebase <upstream> [<branch>]\" conceptually does:\n\n * Add step 0. to make \"your current branch\" in the next step valid.\n\n    0. When <branch> is given, check it out and make it your current\n    branch.\n\n * Combine the steps 1 & 2. and stop talking about \"git log\" whose\n   invocation cannot be precisely described here anyway.\n\nOther than that, the remainder of the series (v7 [1-4/5]) looked\ngood.\n\nTHanks.\n"},{"id":"524237","messageId":"50bdac9c-ce4f-4682-846f-6d6b3f278123@gmail.com","threadId":"63930","inReplyTo":"aa1c2758-79f9-47f6-87d4-16b19fa5bd63@app.fastmail.com","subject":"Re: [PATCH v6 0/5] doc: git-rebase: clarify DESCRIPTION section","fromName":"Phillip Wood","fromEmail":"phillip.wood123@gmail.com","sentAt":"2025-08-15T10:25:03Z","receivedAt":"2025-08-15T10:25:27Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"On 13/08/2025 16:33, Julia Evans wrote:\n> \n>> I'm happy to leave it out but I\n>> wonder if we should drop the references to --fork-point and --root as\n>> well given they're also both pretty niche. I'd also be very happy to go\n>> with Junio's suggestion to replace steps 1 & 2 with a general\n>> description that does not mention 'git log' at all.\n> \n> I like the idea of leaving out `--fork-point` and `--root`.\n> \n> Now that I know the use case for `--reapply-cherry-picks`: what I like about\n> leaving in the `git log` description is that I think it makes it easier for\n> folks to build a mental model of why a `git rebase` might  be slow: there's a\n> \"fast step\" (the `git log` step) and a \"slow step\" (the `git patch-id` step).\n> Then even if we don't mention `--reapply-cherry-picks` in this section, a user\n> could infer that there might be a way to speed up the \"slow step\", and find the\n> `--reapply-cherry-picks` option to speed it up. \n\nPossibly though I think they'd need a reasonably good understanding of \nhow the cherry-pick detection works - do most folks really know what a \npatch-id is and that detecting cherry-picks means generating a diff for \neach commit on either side of the merge base?\n\n> Maybe we could mention that the\n> `git patch-id` step can be slow in some cases.\n\nThat might be worth it depending on how much detail we want. I think it \nis only really a problem on large fast-moving repositories where a lot \nof upstream commits get added between rebases and on partial clones. The \nlatter is due to a sub-optimal implementation that does not batch the \nfetches for missing blobs, though I guess if your repository is big \nenough to warrant a partial clone you'd be likely to hit the first issue \neven if the fetching was more efficient. If we say it can be slow we \nshould perhaps mention that this step can be skipped\n\n> (also I might have misunderstood the \"fast step\" and the \"slow step\" thing,\n> I'd be interested to know if so)\n\nI've commented on this in my reply to Junio - I think it depends where \nyou draw the stop boundaries.\n\nThanks\n\nPhillip\n"},{"id":"524238","messageId":"c9a4d7ef-8cdf-4d5b-b0af-f43ffc6b7450@gmail.com","threadId":"63930","inReplyTo":"xmqq5xepzjnu.fsf@gitster.g","subject":"Re: [PATCH v6 0/5] doc: git-rebase: clarify DESCRIPTION section","fromName":"Phillip Wood","fromEmail":"phillip.wood123@gmail.com","sentAt":"2025-08-15T10:25:13Z","receivedAt":"2025-08-15T10:25:28Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"On 14/08/2025 22:18, Junio C Hamano wrote:\n> \"Julia Evans\" <julia@jvns.ca> writes:\n> \n>>> well given they're also both pretty niche. I'd also be very happy to go\n>>> with Junio's suggestion to replace steps 1 & 2 with a general\n>>> description that does not mention 'git log' at all.\n>>\n>> I like the idea of leaving out `--fork-point` and `--root`.\n>>\n>> Now that I know the use case for `--reapply-cherry-picks`: what I like about\n>> leaving in the `git log` description is that I think it makes it easier for\n>> folks to build a mental model of why a `git rebase` might be slow: there's a\n>> \"fast step\" (the `git log` step) and a \"slow step\" (the `git patch-id` step).\n >\n> But that is not what goes on, is it?  What you wrote as if they were\n> two separate steps (1 to enumerate, 2 to filter) is not what happens\n> in practice.  Whether it is done via the \"format-patch --stdout | am\"\n> pipeline in run_am(), or via the \"rev-list --reverse | xargs -n1\n> cherry-pick\" pipeline in run_sequencer_rebase(), the upstream of\n> these conceptual pipelines that enumerates what is to be replayed is\n> run just once, i.e. there is only one step that \"enumerates what is\n> to be replayed\", without a separate filtering step.\n> \n> In other words, there is no \"a fast step followed by a slow step\".\n\nAlthough the cherry-pick detection happens inside \"git log\" that command \nhas a fast step (find the commits on both sides of the merge base) and a \nslow step (detect cherry-picks) so I think it depends where one draws \nthe step boundaries. The cherry-pick detection is known to be slow when \nthere are a lot of new upstream commits which was the motivation for \nadding --reapply-cherry-picks in 0fcb4f6b62 (rebase --merge: optionally \nskip upstreamed commits, 2020-04-11)\n\n> Perhaps squashing the first two steps into one and phrasing them as\n> a single step is sufficient to give a conceptual overview (what you\n> have in v7 as \"a simplified description of what the command does\").\n> \n>   1. Make a list of all commits on your current branch since it\n>      branched off from `<upstream>` that do not have equivalent\n>      change in `<upstream>`.\n> \n> If you want to keep 1 & 2 separate, then rephrase the introductory\n> sentence to clarify that we are giving a white lie for the sake of\n> easier understanding, e.g.\n> \n>      Here is what conceptually happens in \"git rebase\":\n\nEither of those sounds reasonable to me\n\nThanks\n\nPhillip\n\n"},{"id":"524253","messageId":"xmqqa540twpc.fsf@gitster.g","threadId":"63930","inReplyTo":"c9a4d7ef-8cdf-4d5b-b0af-f43ffc6b7450@gmail.com","subject":"Re: [PATCH v6 0/5] doc: git-rebase: clarify DESCRIPTION section","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2025-08-15T15:45:51Z","receivedAt":"2025-08-15T15:45:55Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Phillip Wood <phillip.wood123@gmail.com> writes:\n\n> Although the cherry-pick detection happens inside \"git log\" that\n> command has a fast step (find the commits on both sides of the merge\n> base) and a slow step (detect cherry-picks) so I think it depends\n> where one draws the step boundaries. The cherry-pick detection is\n> known to be slow when there are a lot of new upstream commits which\n> was the motivation for adding --reapply-cherry-picks in 0fcb4f6b62\n> (rebase --merge: optionally skip upstreamed commits, 2020-04-11)\n\nCorrect, in the description of \"reapply-cherry-picks\", it may need\nto be discussed to guide the readers decide when to use the option.\n\nBut would it really help understanding of readers to give such level\nof detail in \"here is roughly how it works\" description?  I am not\nsure about that.\n\n\n"},{"id":"524256","messageId":"9293393d-e8c2-42e8-9b06-af40c576e841@gmail.com","threadId":"63930","inReplyTo":"xmqqa540twpc.fsf@gitster.g","subject":"Re: [PATCH v6 0/5] doc: git-rebase: clarify DESCRIPTION section","fromName":"Phillip Wood","fromEmail":"phillip.wood123@gmail.com","sentAt":"2025-08-15T15:54:45Z","receivedAt":"2025-08-15T15:54:48Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"On 15/08/2025 16:45, Junio C Hamano wrote:\n> Phillip Wood <phillip.wood123@gmail.com> writes:\n> \n>> Although the cherry-pick detection happens inside \"git log\" that\n>> command has a fast step (find the commits on both sides of the merge\n>> base) and a slow step (detect cherry-picks) so I think it depends\n>> where one draws the step boundaries. The cherry-pick detection is\n>> known to be slow when there are a lot of new upstream commits which\n>> was the motivation for adding --reapply-cherry-picks in 0fcb4f6b62\n>> (rebase --merge: optionally skip upstreamed commits, 2020-04-11)\n> \n> Correct, in the description of \"reapply-cherry-picks\", it may need\n> to be discussed to guide the readers decide when to use the option.\n> \n> But would it really help understanding of readers to give such level\n> of detail in \"here is roughly how it works\" description?  I am not\n> sure about that.\n\nI'd certainly be happy to see these two steps in the description \nsimplified and combined as you've suggested elsewhere.\n\nThanks\n\nPhillip\n"},{"id":"524257","messageId":"30eabeb1-b89f-4e05-a3bd-bd24dc3a3354@app.fastmail.com","threadId":"63930","inReplyTo":"9293393d-e8c2-42e8-9b06-af40c576e841@gmail.com","subject":"Re: [PATCH v6 0/5] doc: git-rebase: clarify DESCRIPTION section","fromName":"Julia Evans","fromEmail":"julia@jvns.ca","sentAt":"2025-08-15T15:56:30Z","receivedAt":"2025-08-15T15:56:53Z","isPatch":true,"sender":{"key":"julia@jvns.ca","avatar":"https://avatars.githubusercontent.com/u/817739?v=4"},"body":">>> Although the cherry-pick detection happens inside \"git log\" that\n>>> command has a fast step (find the commits on both sides of the merge\n>>> base) and a slow step (detect cherry-picks) so I think it depends\n>>> where one draws the step boundaries. The cherry-pick detection is\n>>> known to be slow when there are a lot of new upstream commits which\n>>> was the motivation for adding --reapply-cherry-picks in 0fcb4f6b62\n>>> (rebase --merge: optionally skip upstreamed commits, 2020-04-11)\n>> \n>> Correct, in the description of \"reapply-cherry-picks\", it may need\n>> to be discussed to guide the readers decide when to use the option.\n>> \n>> But would it really help understanding of readers to give such level\n>> of detail in \"here is roughly how it works\" description?  I am not\n>> sure about that.\n>\n> I'd certainly be happy to see these two steps in the description \n> simplified and combined as you've suggested elsewhere.\n\nI'll combine them then: that seems like the simplest solution.\n\nbest,\n- Julia\n"},{"id":"524263","messageId":"pull.1949.v8.git.1755276750.gitgitgadget@gmail.com","threadId":"63930","inReplyTo":"pull.1949.v7.git.1755006568.gitgitgadget@gmail.com","subject":"[PATCH v8 0/5] doc: git-rebase: clarify DESCRIPTION section","fromName":"Julia Evans via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-08-15T16:52:25Z","receivedAt":"2025-08-15T16:52:34Z","isPatch":true,"sender":{"key":"julia@jvns.ca","avatar":"https://avatars.githubusercontent.com/u/817739?v=4"},"body":"Combine point 1 and 2 in \"a simplified description of what git rebase\n<upstream> does:\" into a shorter summary.\n\nJulia Evans (5):\n  doc: git-rebase: start with an example\n  doc: git rebase: dedup merge conflict discussion\n  doc: git rebase: clarify arguments syntax\n  doc: git-rebase: move --onto explanation down\n  doc: git-rebase: update discussion of internals\n\n Documentation/git-rebase.adoc | 298 +++++++++++++++-------------------\n 1 file changed, 133 insertions(+), 165 deletions(-)\n\n\nbase-commit: 2c2ba49d55ff26c1082b8137b1ec5eeccb4337d1\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-1949%2Fjvns%2Fclarify-rebase-v8\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1949/jvns/clarify-rebase-v8\nPull-Request: https://github.com/gitgitgadget/git/pull/1949\n\nRange-diff vs v7:\n\n 1:  e7a8fbbe53c = 1:  e7a8fbbe53c doc: git-rebase: start with an example\n 2:  ad63f69918d = 2:  ad63f69918d doc: git rebase: dedup merge conflict discussion\n 3:  7ee6b0afe88 = 3:  7ee6b0afe88 doc: git rebase: clarify arguments syntax\n 4:  4686417b28e = 4:  4686417b28e doc: git-rebase: move --onto explanation down\n 5:  79f29ad1e68 ! 5:  cb85642bb9d doc: git-rebase: update discussion of internals\n     @@ Documentation/git-rebase.adoc: linkgit:git-config[1] for details) and the `--for\n      -to point at the tip of the branch before the reset.\n      +Here is a simplified description of what `git rebase <upstream>` does:\n      +\n     -+1. Make a list of all new commits on your current branch since it branched\n     -+   off from `<upstream>`. This is the same set of commits that would be shown\n     -+   by `git log  <upstream>..HEAD`. You can use `--fork-point` or  `--root` to\n     -+   change how this list of commits is constructed.\n     -+2. Check whether any of those commits contain the same changes (according to\n     -+   `git patch-id`) as a commit already in `<upstream>` and remove them from\n     -+   the list.\n     -+3. Check out `<upstream>` with the equivalent of\n     ++1. Make a list of all commits on your current branch since it branched\n     ++   off from `<upstream>` that do not have an equivalent commit in\n     ++   `<upstream>`.\n     ++2. Check out `<upstream>` with the equivalent of\n      +   `git checkout --detach <upstream>`.\n     -+4. Replay the commits, one by one, in order. This is similar to running\n     ++3. Replay the commits, one by one, in order. This is similar to running\n      +   `git cherry-pick <commit>` for each commit. See REBASING MERGES for how merges\n      +   are handled.\n     -+5. Update your branch to point to the final commit with the equivalent\n     ++4. Update your branch to point to the final commit with the equivalent\n      +   of `git checkout -B <branch>`.\n       \n       [NOTE]\n\n-- \ngitgitgadget\n"},{"id":"524264","messageId":"e7a8fbbe53c9cf5cb7b8d822e72ff4219de37e1c.1755276750.git.gitgitgadget@gmail.com","threadId":"63930","inReplyTo":"pull.1949.v8.git.1755276750.gitgitgadget@gmail.com","subject":"[PATCH v8 1/5] doc: git-rebase: start with an example","fromName":"Julia Evans via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-08-15T16:52:26Z","receivedAt":"2025-08-15T16:52:34Z","isPatch":true,"sender":{"key":"julia@jvns.ca","avatar":"https://avatars.githubusercontent.com/u/817739?v=4"},"body":"From: Julia Evans <julia@jvns.ca>\n\n- Start with an example that mirrors the example in the `git-merge` man\n  page, to make it easier for folks to understand the difference between\n  a rebase and a merge.\n- Mention that rebase can combine or reorder commits\n\nSigned-off-by: Julia Evans <julia@jvns.ca>\n---\n Documentation/git-rebase.adoc | 52 +++++++++++++++++------------------\n 1 file changed, 26 insertions(+), 26 deletions(-)\n\ndiff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc\nindex 956d3048f5a6..bb5a3ff7f828 100644\n--- a/Documentation/git-rebase.adoc\n+++ b/Documentation/git-rebase.adoc\n@@ -16,6 +16,32 @@ SYNOPSIS\n \n DESCRIPTION\n -----------\n+Transplant a series of commits onto a different starting point.\n+You can also use `git rebase` to reorder or combine commits: see INTERACTIVE\n+MODE below for how to do that.\n+\n+For example, imagine that you have been working on the `topic` branch in this\n+history, and you want to \"catch up\" to the work done on the `master` branch.\n+\n+------------\n+          A---B---C topic\n+         /\n+    D---E---F---G master\n+------------\n+\n+You want to transplant the commits you made on `topic` since it diverged from\n+`master` (i.e. A, B, and C), on top of the current `master`.  You can do this\n+by running `git rebase master` while the `topic` branch is checked out.  If you\n+want to rebase `topic` while on another branch, `git rebase master topic` is a\n+shortcut for `git checkout topic && git rebase master`.\n+\n+------------\n+                  A'--B'--C' topic\n+                 /\n+    D---E---F---G master\n+------------\n+\n+\n If `<branch>` is specified, `git rebase` will perform an automatic\n `git switch <branch>` before doing anything else.  Otherwise\n it remains on the current branch.\n@@ -58,32 +84,6 @@ that caused the merge failure with `git rebase --skip`.  To check out the\n original `<branch>` and remove the `.git/rebase-apply` working files, use\n the command `git rebase --abort` instead.\n \n-Assume the following history exists and the current branch is \"topic\":\n-\n-------------\n-          A---B---C topic\n-         /\n-    D---E---F---G master\n-------------\n-\n-From this point, the result of either of the following commands:\n-\n-\n-    git rebase master\n-    git rebase master topic\n-\n-would be:\n-\n-------------\n-                  A'--B'--C' topic\n-                 /\n-    D---E---F---G master\n-------------\n-\n-*NOTE:* The latter form is just a short-hand of `git checkout topic`\n-followed by `git rebase master`. When rebase exits `topic` will\n-remain the checked-out branch.\n-\n If the upstream branch already contains a change you have made (e.g.,\n because you mailed a patch which was applied upstream), then that commit\n will be skipped and warnings will be issued (if the 'merge' backend is\n-- \ngitgitgadget\n\n"},{"id":"524265","messageId":"ad63f69918df0130b6b0236d04e27f8529115cd4.1755276751.git.gitgitgadget@gmail.com","threadId":"63930","inReplyTo":"pull.1949.v8.git.1755276750.gitgitgadget@gmail.com","subject":"[PATCH v8 2/5] doc: git rebase: dedup merge conflict discussion","fromName":"Julia Evans via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-08-15T16:52:27Z","receivedAt":"2025-08-15T16:52:35Z","isPatch":true,"sender":{"key":"julia@jvns.ca","avatar":"https://avatars.githubusercontent.com/u/817739?v=4"},"body":"From: Julia Evans <julia@jvns.ca>\n\nPreviously there were two explanations, this combines them both into a\nsingle explanation.\n\nSigned-off-by: Julia Evans <julia@jvns.ca>\n---\n Documentation/git-rebase.adoc | 49 ++++++++++++++---------------------\n 1 file changed, 20 insertions(+), 29 deletions(-)\n\ndiff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc\nindex bb5a3ff7f828..e82ceb9cbfce 100644\n--- a/Documentation/git-rebase.adoc\n+++ b/Documentation/git-rebase.adoc\n@@ -42,6 +42,26 @@ shortcut for `git checkout topic && git rebase master`.\n ------------\n \n \n+If there is a merge conflict during this process, `git rebase` will stop at the\n+first problematic commit and leave conflict markers. If this happens, you can do\n+one of these things:\n+\n+1. Resolve the conflict. You can use `git diff` to find the markers (<<<<<<)\n+   and make edits to resolve the conflict. For each file you edit, you need to\n+   tell Git that the conflict has been resolved. You can mark the conflict as\n+   resolved with  `git add <filename>`. After resolving all of the conflicts,\n+   you can continue the rebasing process with\n+\n+   git rebase --continue\n+\n+2. Stop the `git rebase` and return your branch to its original state with\n+\n+   git rebase --abort\n+\n+3. Skip the commit that caused the merge conflict with\n+\n+   git rebase --skip\n+\n If `<branch>` is specified, `git rebase` will perform an automatic\n `git switch <branch>` before doing anything else.  Otherwise\n it remains on the current branch.\n@@ -77,13 +97,6 @@ any commits in `HEAD` which introduce the same textual changes as a commit\n in `HEAD..<upstream>` are omitted (i.e., a patch already accepted upstream\n with a different commit message or timestamp will be skipped).\n \n-It is possible that a merge failure will prevent this process from being\n-completely automatic.  You will have to resolve any such merge failure\n-and run `git rebase --continue`.  Another option is to bypass the commit\n-that caused the merge failure with `git rebase --skip`.  To check out the\n-original `<branch>` and remove the `.git/rebase-apply` working files, use\n-the command `git rebase --abort` instead.\n-\n If the upstream branch already contains a change you have made (e.g.,\n because you mailed a patch which was applied upstream), then that commit\n will be skipped and warnings will be issued (if the 'merge' backend is\n@@ -186,28 +199,6 @@ This is useful if F and G were flawed in some way, or should not be\n part of topicA.  Note that the argument to `--onto` and the `<upstream>`\n parameter can be any valid commit-ish.\n \n-In case of conflict, `git rebase` will stop at the first problematic commit\n-and leave conflict markers in the tree.  You can use `git diff` to locate\n-the markers (<<<<<<) and make edits to resolve the conflict.  For each\n-file you edit, you need to tell Git that the conflict has been resolved,\n-typically this would be done with\n-\n-\n-    git add <filename>\n-\n-\n-After resolving the conflict manually and updating the index with the\n-desired resolution, you can continue the rebasing process with\n-\n-\n-    git rebase --continue\n-\n-\n-Alternatively, you can undo the 'git rebase' with\n-\n-\n-    git rebase --abort\n-\n MODE OPTIONS\n ------------\n \n-- \ngitgitgadget\n\n"},{"id":"524266","messageId":"7ee6b0afe88fe4f5346776192a0df99c6b64de19.1755276751.git.gitgitgadget@gmail.com","threadId":"63930","inReplyTo":"pull.1949.v8.git.1755276750.gitgitgadget@gmail.com","subject":"[PATCH v8 3/5] doc: git rebase: clarify arguments syntax","fromName":"Julia Evans via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-08-15T16:52:28Z","receivedAt":"2025-08-15T16:52:36Z","isPatch":true,"sender":{"key":"julia@jvns.ca","avatar":"https://avatars.githubusercontent.com/u/817739?v=4"},"body":"From: Julia Evans <julia@jvns.ca>\n\nRemove duplicate explanation of `git rebase <upstream> <branch>` which\nis already explained above.\n\nSigned-off-by: Julia Evans <julia@jvns.ca>\n---\n Documentation/git-rebase.adoc | 6 +-----\n 1 file changed, 1 insertion(+), 5 deletions(-)\n\ndiff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc\nindex e82ceb9cbfce..6d02648a9b3c 100644\n--- a/Documentation/git-rebase.adoc\n+++ b/Documentation/git-rebase.adoc\n@@ -62,11 +62,7 @@ one of these things:\n \n    git rebase --skip\n \n-If `<branch>` is specified, `git rebase` will perform an automatic\n-`git switch <branch>` before doing anything else.  Otherwise\n-it remains on the current branch.\n-\n-If `<upstream>` is not specified, the upstream configured in\n+If you don't specify an `<upstream>` to rebase onto, the upstream configured in\n `branch.<name>.remote` and `branch.<name>.merge` options will be used (see\n linkgit:git-config[1] for details) and the `--fork-point` option is\n assumed.  If you are currently not on any branch or if the current\n-- \ngitgitgadget\n\n"},{"id":"524267","messageId":"4686417b28e4ab386983ad68e4d4d4798a467811.1755276751.git.gitgitgadget@gmail.com","threadId":"63930","inReplyTo":"pull.1949.v8.git.1755276750.gitgitgadget@gmail.com","subject":"[PATCH v8 4/5] doc: git-rebase: move --onto explanation down","fromName":"Julia Evans via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-08-15T16:52:29Z","receivedAt":"2025-08-15T16:52:38Z","isPatch":true,"sender":{"key":"julia@jvns.ca","avatar":"https://avatars.githubusercontent.com/u/817739?v=4"},"body":"From: Julia Evans <julia@jvns.ca>\n\nThere's a very clear explanation with examples of using --onto which is\ncurrently buried in the very long DESCRIPTION section. This moves it to\nits own section, so that we can reference the explanation from the\n`--onto` option by name.\n\nSigned-off-by: Julia Evans <julia@jvns.ca>\n---\n Documentation/git-rebase.adoc | 168 ++++++++++++++++++----------------\n 1 file changed, 87 insertions(+), 81 deletions(-)\n\ndiff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc\nindex 6d02648a9b3c..d041d87f270b 100644\n--- a/Documentation/git-rebase.adoc\n+++ b/Documentation/git-rebase.adoc\n@@ -114,87 +114,6 @@ will result in:\n     D---E---A'---F master\n ------------\n \n-Here is how you would transplant a topic branch based on one\n-branch to another, to pretend that you forked the topic branch\n-from the latter branch, using `rebase --onto`.\n-\n-First let's assume your 'topic' is based on branch 'next'.\n-For example, a feature developed in 'topic' depends on some\n-functionality which is found in 'next'.\n-\n-------------\n-    o---o---o---o---o  master\n-         \\\n-          o---o---o---o---o  next\n-                           \\\n-                            o---o---o  topic\n-------------\n-\n-We want to make 'topic' forked from branch 'master'; for example,\n-because the functionality on which 'topic' depends was merged into the\n-more stable 'master' branch. We want our tree to look like this:\n-\n-------------\n-    o---o---o---o---o  master\n-        |            \\\n-        |             o'--o'--o'  topic\n-         \\\n-          o---o---o---o---o  next\n-------------\n-\n-We can get this using the following command:\n-\n-    git rebase --onto master next topic\n-\n-\n-Another example of --onto option is to rebase part of a\n-branch.  If we have the following situation:\n-\n-------------\n-                            H---I---J topicB\n-                           /\n-                  E---F---G  topicA\n-                 /\n-    A---B---C---D  master\n-------------\n-\n-then the command\n-\n-    git rebase --onto master topicA topicB\n-\n-would result in:\n-\n-------------\n-                 H'--I'--J'  topicB\n-                /\n-                | E---F---G  topicA\n-                |/\n-    A---B---C---D  master\n-------------\n-\n-This is useful when topicB does not depend on topicA.\n-\n-A range of commits could also be removed with rebase.  If we have\n-the following situation:\n-\n-------------\n-    E---F---G---H---I---J  topicA\n-------------\n-\n-then the command\n-\n-    git rebase --onto topicA~5 topicA~3 topicA\n-\n-would result in the removal of commits F and G:\n-\n-------------\n-    E---H'---I'---J'  topicA\n-------------\n-\n-This is useful if F and G were flawed in some way, or should not be\n-part of topicA.  Note that the argument to `--onto` and the `<upstream>`\n-parameter can be any valid commit-ish.\n-\n MODE OPTIONS\n ------------\n \n@@ -240,6 +159,8 @@ As a special case, you may use \"A\\...B\" as a shortcut for the\n merge base of A and B if there is exactly one merge base. You can\n leave out at most one of A and B, in which case it defaults to HEAD.\n \n+See TRANSPLANTING A TOPIC BRANCH WITH --ONTO below for examples.\n+\n --keep-base::\n \tSet the starting point at which to create the new commits to the\n \tmerge base of `<upstream>` and `<branch>`. Running\n@@ -1018,6 +939,91 @@ consistent (they compile, pass the testsuite, etc.) you should use\n after each commit, test, and amend the commit if fixes are necessary.\n \n \n+TRANSPLANTING A TOPIC BRANCH WITH --ONTO\n+----------------------------------------\n+\n+Here is how you would transplant a topic branch based on one\n+branch to another, to pretend that you forked the topic branch\n+from the latter branch, using `rebase --onto`.\n+\n+First let's assume your 'topic' is based on branch 'next'.\n+For example, a feature developed in 'topic' depends on some\n+functionality which is found in 'next'.\n+\n+------------\n+    o---o---o---o---o  master\n+         \\\n+          o---o---o---o---o  next\n+                           \\\n+                            o---o---o  topic\n+------------\n+\n+We want to make 'topic' forked from branch 'master'; for example,\n+because the functionality on which 'topic' depends was merged into the\n+more stable 'master' branch. We want our tree to look like this:\n+\n+------------\n+    o---o---o---o---o  master\n+        |            \\\n+        |             o'--o'--o'  topic\n+         \\\n+          o---o---o---o---o  next\n+------------\n+\n+We can get this using the following command:\n+\n+    git rebase --onto master next topic\n+\n+\n+Another example of --onto option is to rebase part of a\n+branch.  If we have the following situation:\n+\n+------------\n+                            H---I---J topicB\n+                           /\n+                  E---F---G  topicA\n+                 /\n+    A---B---C---D  master\n+------------\n+\n+then the command\n+\n+    git rebase --onto master topicA topicB\n+\n+would result in:\n+\n+------------\n+                 H'--I'--J'  topicB\n+                /\n+                | E---F---G  topicA\n+                |/\n+    A---B---C---D  master\n+------------\n+\n+This is useful when topicB does not depend on topicA.\n+\n+A range of commits could also be removed with rebase.  If we have\n+the following situation:\n+\n+------------\n+    E---F---G---H---I---J  topicA\n+------------\n+\n+then the command\n+\n+    git rebase --onto topicA~5 topicA~3 topicA\n+\n+would result in the removal of commits F and G:\n+\n+------------\n+    E---H'---I'---J'  topicA\n+------------\n+\n+This is useful if F and G were flawed in some way, or should not be\n+part of topicA.  Note that the argument to `--onto` and the `<upstream>`\n+parameter can be any valid commit-ish.\n+\n+\n RECOVERING FROM UPSTREAM REBASE\n -------------------------------\n \n-- \ngitgitgadget\n\n"},{"id":"524268","messageId":"cb85642bb9df3fcf9792fd18f2dcf448839eae2c.1755276751.git.gitgitgadget@gmail.com","threadId":"63930","inReplyTo":"pull.1949.v8.git.1755276750.gitgitgadget@gmail.com","subject":"[PATCH v8 5/5] doc: git-rebase: update discussion of internals","fromName":"Julia Evans via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-08-15T16:52:30Z","receivedAt":"2025-08-15T16:52:39Z","isPatch":true,"sender":{"key":"julia@jvns.ca","avatar":"https://avatars.githubusercontent.com/u/817739?v=4"},"body":"From: Julia Evans <julia@jvns.ca>\n\n- make it clearer that we're talking about a multistep process\n- give a more technically accurate description how rebase works with the\n  merge backend.\n- condense the explanation of how git rebase skips commits with the same\n  textual changes into a single bullet point and remove the explanatory\n  diagram. Lots of things which are more complicated are already being\n  explained without a diagram.\n- remove the explanation of how exactly `--fork-point` and `--root`\n  work since that information is in the OPTIONS section\n- put all discussion of `ORIG_HEAD` inside the note\n\nSigned-off-by: Julia Evans <julia@jvns.ca>\n---\n Documentation/git-rebase.adoc | 61 +++++++++++------------------------\n 1 file changed, 18 insertions(+), 43 deletions(-)\n\ndiff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc\nindex d041d87f270b..2a44f8a0ceda 100644\n--- a/Documentation/git-rebase.adoc\n+++ b/Documentation/git-rebase.adoc\n@@ -68,51 +68,26 @@ linkgit:git-config[1] for details) and the `--fork-point` option is\n assumed.  If you are currently not on any branch or if the current\n branch does not have a configured upstream, the rebase will abort.\n \n-All changes made by commits in the current branch but that are not\n-in `<upstream>` are saved to a temporary area.  This is the same set\n-of commits that would be shown by `git log <upstream>..HEAD`; or by\n-`git log 'fork_point'..HEAD`, if `--fork-point` is active (see the\n-description on `--fork-point` below); or by `git log HEAD`, if the\n-`--root` option is specified.\n-\n-The current branch is reset to `<upstream>` or `<newbase>` if the\n-`--onto` option was supplied.  This has the exact same effect as\n-`git reset --hard <upstream>` (or `<newbase>`). `ORIG_HEAD` is set\n-to point at the tip of the branch before the reset.\n+Here is a simplified description of what `git rebase <upstream>` does:\n+\n+1. Make a list of all commits on your current branch since it branched\n+   off from `<upstream>` that do not have an equivalent commit in\n+   `<upstream>`.\n+2. Check out `<upstream>` with the equivalent of\n+   `git checkout --detach <upstream>`.\n+3. Replay the commits, one by one, in order. This is similar to running\n+   `git cherry-pick <commit>` for each commit. See REBASING MERGES for how merges\n+   are handled.\n+4. Update your branch to point to the final commit with the equivalent\n+   of `git checkout -B <branch>`.\n \n [NOTE]\n-`ORIG_HEAD` is not guaranteed to still point to the previous branch tip\n-at the end of the rebase if other commands that write that pseudo-ref\n-(e.g. `git reset`) are used during the rebase. The previous branch tip,\n-however, is accessible using the reflog of the current branch\n-(i.e. `@{1}`, see linkgit:gitrevisions[7]).\n-\n-The commits that were previously saved into the temporary area are\n-then reapplied to the current branch, one by one, in order. Note that\n-any commits in `HEAD` which introduce the same textual changes as a commit\n-in `HEAD..<upstream>` are omitted (i.e., a patch already accepted upstream\n-with a different commit message or timestamp will be skipped).\n-\n-If the upstream branch already contains a change you have made (e.g.,\n-because you mailed a patch which was applied upstream), then that commit\n-will be skipped and warnings will be issued (if the 'merge' backend is\n-used).  For example, running `git rebase master` on the following\n-history (in which `A'` and `A` introduce the same set of changes, but\n-have different committer information):\n-\n-------------\n-          A---B---C topic\n-         /\n-    D---E---A'---F master\n-------------\n-\n-will result in:\n-\n-------------\n-                   B'---C' topic\n-                  /\n-    D---E---A'---F master\n-------------\n+When starting the rebase, `ORIG_HEAD` is set to point to the commit at the tip\n+of the to-be-rebased branch. However, `ORIG_HEAD` is not guaranteed to still\n+point to that commit at the end of the rebase if other commands that change\n+`ORIG_HEAD` (like `git reset`) are used during the rebase. The previous branch\n+tip, however, is accessible using the reflog of the current branch (i.e. `@{1}`,\n+see linkgit:gitrevisions[7].\n \n MODE OPTIONS\n ------------\n-- \ngitgitgadget\n"},{"id":"524278","messageId":"xmqqh5y8nvmv.fsf@gitster.g","threadId":"63930","inReplyTo":"4686417b28e4ab386983ad68e4d4d4798a467811.1755276751.git.gitgitgadget@gmail.com","subject":"Re: [PATCH v8 4/5] doc: git-rebase: move --onto explanation down","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2025-08-15T21:05:28Z","receivedAt":"2025-08-15T21:05:31Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Julia Evans via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n\n> From: Julia Evans <julia@jvns.ca>\n>\n> There's a very clear explanation with examples of using --onto which is\n> currently buried in the very long DESCRIPTION section. This moves it to\n> its own section, so that we can reference the explanation from the\n> `--onto` option by name.\n>\n> Signed-off-by: Julia Evans <julia@jvns.ca>\n> ---\n>  Documentation/git-rebase.adoc | 168 ++++++++++++++++++----------------\n>  1 file changed, 87 insertions(+), 81 deletions(-)\n\nDeduplicating is very good idea.\n\nI gave a read-through over the result of the entire series,\nincluding the parts that did not change, to see if the new\norganization is easy to read and coherently tells the story\nwe want to tell, and what I saw was mostly very pleasing, except for\none thing.\n\nThe new location of this section on \"--onto\" felt a bit off.\nPerhaps it is just me, but in case others have different opinions,\nI'd raise it here.\n\nThe overall structure of the document with these patches becomes:\n\n - description that gives a simplified \"what is achieved\".\n\n - \"mode options\" that control what to do during a rebase once the\n   user is given control back\n\n - \"options\" that is given upfront\n\n - notes about incompatible options\n\n - discussions about apply/merge backends and how they differ\n\n - overall notes on advanced topics\n\n   - interactive mode basics\n\n   - splitting commits\n\n   - use of --onto\n\n   - dealing with rebased upstream\n\n   - rebasing merges\n\nIs it so exotic to use \"--onto\" to replay a topic to somewhere other\nthan the direct descendant of the fork point, to make it a part of\nadvanced topics?  I somehow doubt it.  It is a very basic and common\nthing to do while correcting a mistake of choosing a wrong base\ncommit.  You often realize that your topic is basically good but has\nto work well with a different base commit.\n\nI wonder if it gives the same understanding with a much shorter text\nand illustration if we get rid of that section, and mention --onto\nas a part of the early examples in the description section.  That\nway, we can reuse the \"set up\" of user's brain and context we\nalready made with the existing example.\n\nFor example, after showing the rebase of A..C on top of G, we can\nmention that the range can be transplanted on top of commit other\nthan G, say D.  Perhaps we can say that 'D' is still part of the\nmaintenance track, and the topic being a fix for a bug that happened\nbefore D, it should not have forked from E that is a feature\nenhancement commit that is not eligible for being on the maintenance\ntrack.  That would be a good reason why the user may want to move\nA..C on top of D instead of E.\n"},{"id":"524345","messageId":"51468411-8251-4f13-90f2-5cd5184d7c52@gmail.com","threadId":"63930","inReplyTo":"xmqqh5y8nvmv.fsf@gitster.g","subject":"Re: [PATCH v8 4/5] doc: git-rebase: move --onto explanation down","fromName":"Phillip Wood","fromEmail":"phillip.wood123@gmail.com","sentAt":"2025-08-18T13:42:57Z","receivedAt":"2025-08-18T13:43:01Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"On 15/08/2025 22:05, Junio C Hamano wrote:\n> \"Julia Evans via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n> \n>> From: Julia Evans <julia@jvns.ca>\n>>\n>> There's a very clear explanation with examples of using --onto which is\n>> currently buried in the very long DESCRIPTION section. This moves it to\n>> its own section, so that we can reference the explanation from the\n>> `--onto` option by name.\n>>\n>> Signed-off-by: Julia Evans <julia@jvns.ca>\n>> ---\n>>   Documentation/git-rebase.adoc | 168 ++++++++++++++++++----------------\n>>   1 file changed, 87 insertions(+), 81 deletions(-)\n> \n> Deduplicating is very good idea.\n> \n> I gave a read-through over the result of the entire series,\n> including the parts that did not change, to see if the new\n> organization is easy to read and coherently tells the story\n> we want to tell, and what I saw was mostly very pleasing, except for\n> one thing.\n\nYes the reworked DESCRIPTION section is very good.\n\n> The new location of this section on \"--onto\" felt a bit off.\n> Perhaps it is just me, but in case others have different opinions,\n> I'd raise it here.\n\nI agree that \"--onto\" is a fairly commonly used option and so it might \nbe nice to mention it in the general description. The existing examples \nare all good reasons why one might want to use \"--onto\" so I'm slightly \nwary of replacing them with a single example in the description. Maybe \nwe could just add a sentence to the description explaining that it is \npossible to transplant the commits to a different base using \"--onto\". \nThat would also keep the description fairly concise.\n\nI've just built the html version and it would be nice if we could add a \nlink to the TRANSPLANTING A TOPIC BRANCH WITH --ONTO when we mention it \nin the description of \"--onto\". The same goes for the mention of \nINTERACTIVE MODE in the DESCRIPTION section.\n\nThanks\n\nPhillip\n\n> The overall structure of the document with these patches becomes:\n> \n>   - description that gives a simplified \"what is achieved\".\n> \n>   - \"mode options\" that control what to do during a rebase once the\n>     user is given control back\n> \n>   - \"options\" that is given upfront\n> \n>   - notes about incompatible options\n> \n>   - discussions about apply/merge backends and how they differ\n> \n>   - overall notes on advanced topics\n> \n>     - interactive mode basics\n> \n>     - splitting commits\n> \n>     - use of --onto\n> \n>     - dealing with rebased upstream\n> \n>     - rebasing merges\n> \n> Is it so exotic to use \"--onto\" to replay a topic to somewhere other\n> than the direct descendant of the fork point, to make it a part of\n> advanced topics?  I somehow doubt it.  It is a very basic and common\n> thing to do while correcting a mistake of choosing a wrong base\n> commit.  You often realize that your topic is basically good but has\n> to work well with a different base commit.\n> \n> I wonder if it gives the same understanding with a much shorter text\n> and illustration if we get rid of that section, and mention --onto\n> as a part of the early examples in the description section.  That\n> way, we can reuse the \"set up\" of user's brain and context we\n> already made with the existing example.\n> \n> For example, after showing the rebase of A..C on top of G, we can\n> mention that the range can be transplanted on top of commit other\n> than G, say D.  Perhaps we can say that 'D' is still part of the\n> maintenance track, and the topic being a fix for a bug that happened\n> before D, it should not have forked from E that is a feature\n> enhancement commit that is not eligible for being on the maintenance\n> track.  That would be a good reason why the user may want to move\n> A..C on top of D instead of E.\n\n"},{"id":"524346","messageId":"a14efbe9-0d7c-4631-9f03-6adf979b690b@gmail.com","threadId":"63930","inReplyTo":"pull.1949.v8.git.1755276750.gitgitgadget@gmail.com","subject":"Re: [PATCH v8 0/5] doc: git-rebase: clarify DESCRIPTION section","fromName":"Phillip Wood","fromEmail":"phillip.wood123@gmail.com","sentAt":"2025-08-18T13:43:15Z","receivedAt":"2025-08-18T13:43:18Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"On 15/08/2025 17:52, Julia Evans via GitGitGadget wrote:\n> Combine point 1 and 2 in \"a simplified description of what git rebase\n> <upstream> does:\" into a shorter summary.\n\nThis looks great, I've left a couple of comments in reply to Junio but \nI'd be happy enough to see this merged as-is.\n\nI'm going to be off the list for a week from tomorrow so I wont be \ncommenting any more this week.\n\nThanks for working on this\n\nPhillip\n\n> Julia Evans (5):\n>    doc: git-rebase: start with an example\n>    doc: git rebase: dedup merge conflict discussion\n>    doc: git rebase: clarify arguments syntax\n>    doc: git-rebase: move --onto explanation down\n>    doc: git-rebase: update discussion of internals\n> \n>   Documentation/git-rebase.adoc | 298 +++++++++++++++-------------------\n>   1 file changed, 133 insertions(+), 165 deletions(-)\n> \n> \n> base-commit: 2c2ba49d55ff26c1082b8137b1ec5eeccb4337d1\n> Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1949%2Fjvns%2Fclarify-rebase-v8\n> Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1949/jvns/clarify-rebase-v8\n> Pull-Request: https://github.com/gitgitgadget/git/pull/1949\n> \n> Range-diff vs v7:\n> \n>   1:  e7a8fbbe53c = 1:  e7a8fbbe53c doc: git-rebase: start with an example\n>   2:  ad63f69918d = 2:  ad63f69918d doc: git rebase: dedup merge conflict discussion\n>   3:  7ee6b0afe88 = 3:  7ee6b0afe88 doc: git rebase: clarify arguments syntax\n>   4:  4686417b28e = 4:  4686417b28e doc: git-rebase: move --onto explanation down\n>   5:  79f29ad1e68 ! 5:  cb85642bb9d doc: git-rebase: update discussion of internals\n>       @@ Documentation/git-rebase.adoc: linkgit:git-config[1] for details) and the `--for\n>        -to point at the tip of the branch before the reset.\n>        +Here is a simplified description of what `git rebase <upstream>` does:\n>        +\n>       -+1. Make a list of all new commits on your current branch since it branched\n>       -+   off from `<upstream>`. This is the same set of commits that would be shown\n>       -+   by `git log  <upstream>..HEAD`. You can use `--fork-point` or  `--root` to\n>       -+   change how this list of commits is constructed.\n>       -+2. Check whether any of those commits contain the same changes (according to\n>       -+   `git patch-id`) as a commit already in `<upstream>` and remove them from\n>       -+   the list.\n>       -+3. Check out `<upstream>` with the equivalent of\n>       ++1. Make a list of all commits on your current branch since it branched\n>       ++   off from `<upstream>` that do not have an equivalent commit in\n>       ++   `<upstream>`.\n>       ++2. Check out `<upstream>` with the equivalent of\n>        +   `git checkout --detach <upstream>`.\n>       -+4. Replay the commits, one by one, in order. This is similar to running\n>       ++3. Replay the commits, one by one, in order. This is similar to running\n>        +   `git cherry-pick <commit>` for each commit. See REBASING MERGES for how merges\n>        +   are handled.\n>       -+5. Update your branch to point to the final commit with the equivalent\n>       ++4. Update your branch to point to the final commit with the equivalent\n>        +   of `git checkout -B <branch>`.\n>         \n>         [NOTE]\n> \n\n"},{"id":"524353","messageId":"xmqq4iu4k18z.fsf@gitster.g","threadId":"63930","inReplyTo":"51468411-8251-4f13-90f2-5cd5184d7c52@gmail.com","subject":"Re: [PATCH v8 4/5] doc: git-rebase: move --onto explanation down","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2025-08-18T17:06:52Z","receivedAt":"2025-08-18T17:06:55Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Phillip Wood <phillip.wood123@gmail.com> writes:\n\n>> The new location of this section on \"--onto\" felt a bit off.\n>> Perhaps it is just me, but in case others have different opinions,\n>> I'd raise it here.\n>\n> I agree that \"--onto\" is a fairly commonly used option and so it might\n> be nice to mention it in the general description.\n\nThat would independently be a good idea.\n\n> The existing\n> examples are all good reasons why one might want to use \"--onto\" so\n> I'm slightly wary of replacing them with a single example in the\n> description.\n\nThen perhaps we should find a better place to put it.  The section\non advanced topics notes are mostly about operations using sequencer\nmachinery, except for the onto section.  Perhaps immediately after\nthe apply/merge comparison?\n"},{"id":"524448","messageId":"106c4a6c-9239-4c67-8bed-5ec2c0987f21@app.fastmail.com","threadId":"63930","inReplyTo":"xmqq4iu4k18z.fsf@gitster.g","subject":"Re: [PATCH v8 4/5] doc: git-rebase: move --onto explanation down","fromName":"Julia Evans","fromEmail":"julia@jvns.ca","sentAt":"2025-08-19T15:03:36Z","receivedAt":"2025-08-19T15:03:59Z","isPatch":true,"sender":{"key":"julia@jvns.ca","avatar":"https://avatars.githubusercontent.com/u/817739?v=4"},"body":">> The existing\n>> examples are all good reasons why one might want to use \"--onto\" so\n>> I'm slightly wary of replacing them with a single example in the\n>> description.\n>\n> Then perhaps we should find a better place to put it.  The section\n> on advanced topics notes are mostly about operations using sequencer\n> machinery, except for the onto section.  Perhaps immediately after\n> the apply/merge comparison?\n\nI'm happy to move it anywhere: I couldn't figure out how the sections\nwere meant to be organized (I didn't know that \"operations about \nsequencer machinery\" was meant to be a theme) so I chose where\nto put it pretty arbitrarily.\n"},{"id":"524473","messageId":"xmqqwm6zccy4.fsf@gitster.g","threadId":"63930","inReplyTo":"106c4a6c-9239-4c67-8bed-5ec2c0987f21@app.fastmail.com","subject":"Re: [PATCH v8 4/5] doc: git-rebase: move --onto explanation down","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2025-08-19T19:45:55Z","receivedAt":"2025-08-19T19:45:57Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Julia Evans\" <julia@jvns.ca> writes:\n\n>>> The existing\n>>> examples are all good reasons why one might want to use \"--onto\" so\n>>> I'm slightly wary of replacing them with a single example in the\n>>> description.\n>>\n>> Then perhaps we should find a better place to put it.  The section\n>> on advanced topics notes are mostly about operations using sequencer\n>> machinery, except for the onto section.  Perhaps immediately after\n>> the apply/merge comparison?\n>\n> I'm happy to move it anywhere: I couldn't figure out how the sections\n> were meant to be organized (I didn't know that \"operations about \n> sequencer machinery\" was meant to be a theme) so I chose where\n> to put it pretty arbitrarily.\n\nI do not think it was meant to be a theme, but the topics there\nended up being around it as they were placed there organically.\n\nIf we were moving it, how about somewhere fairly early, like before\nwe start talking about mode options, where we teach the very basic\nconcept \"rebase is to transplant a range history on top of a commit\nthat is different from where that history currently builds on\"?  The\nprimary difference with and without \"--onto\" is if you explicitly\nspecify where to transplant your history, independent from how you\nspecify the range of history to be transplanted, or a single\n<upstream> implicitly specifies both.\n\n"},{"id":"524743","messageId":"pull.1949.v9.git.1755909782.gitgitgadget@gmail.com","threadId":"63930","inReplyTo":"pull.1949.v8.git.1755276750.gitgitgadget@gmail.com","subject":"[PATCH v9 0/5] doc: git-rebase: clarify DESCRIPTION section","fromName":"Julia Evans via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-08-23T00:42:57Z","receivedAt":"2025-08-23T00:43:06Z","isPatch":true,"sender":{"key":"julia@jvns.ca","avatar":"https://avatars.githubusercontent.com/u/817739?v=4"},"body":"Move the \"TRANSPLANTING A TOPIC BRANCH WITH --ONTO\" back up: now it's in the\nexact same place it was before, just now with a section heading.\n\nJulia Evans (5):\n  doc: git-rebase: start with an example\n  doc: git rebase: dedup merge conflict discussion\n  doc: git rebase: clarify arguments syntax\n  doc: git-rebase: move --onto explanation down\n  doc: git-rebase: update discussion of internals\n\n Documentation/git-rebase.adoc | 149 +++++++++++++---------------------\n 1 file changed, 58 insertions(+), 91 deletions(-)\n\n\nbase-commit: 64cbe5e2e8a7b0f92c780b210e602496bd5cad0f\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-1949%2Fjvns%2Fclarify-rebase-v9\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1949/jvns/clarify-rebase-v9\nPull-Request: https://github.com/gitgitgadget/git/pull/1949\n\nRange-diff vs v8:\n\n 1:  e7a8fbbe53c = 1:  ea1438e094e doc: git-rebase: start with an example\n 2:  ad63f69918d = 2:  339b7a1bc5b doc: git rebase: dedup merge conflict discussion\n 3:  7ee6b0afe88 = 3:  f42c2c794a9 doc: git rebase: clarify arguments syntax\n 4:  4686417b28e ! 4:  9c2a54ab9fa doc: git-rebase: move --onto explanation down\n     @@ Documentation/git-rebase.adoc: will result in:\n           D---E---A'---F master\n       ------------\n       \n     --Here is how you would transplant a topic branch based on one\n     --branch to another, to pretend that you forked the topic branch\n     --from the latter branch, using `rebase --onto`.\n     --\n     --First let's assume your 'topic' is based on branch 'next'.\n     --For example, a feature developed in 'topic' depends on some\n     --functionality which is found in 'next'.\n     --\n     --------------\n     --    o---o---o---o---o  master\n     --         \\\n     --          o---o---o---o---o  next\n     --                           \\\n     --                            o---o---o  topic\n     --------------\n     --\n     --We want to make 'topic' forked from branch 'master'; for example,\n     --because the functionality on which 'topic' depends was merged into the\n     --more stable 'master' branch. We want our tree to look like this:\n     --\n     --------------\n     --    o---o---o---o---o  master\n     --        |            \\\n     --        |             o'--o'--o'  topic\n     --         \\\n     --          o---o---o---o---o  next\n     --------------\n     --\n     --We can get this using the following command:\n     --\n     --    git rebase --onto master next topic\n     --\n     --\n     --Another example of --onto option is to rebase part of a\n     --branch.  If we have the following situation:\n     --\n     --------------\n     --                            H---I---J topicB\n     --                           /\n     --                  E---F---G  topicA\n     --                 /\n     --    A---B---C---D  master\n     --------------\n     --\n     --then the command\n     --\n     --    git rebase --onto master topicA topicB\n     --\n     --would result in:\n     --\n     --------------\n     --                 H'--I'--J'  topicB\n     --                /\n     --                | E---F---G  topicA\n     --                |/\n     --    A---B---C---D  master\n     --------------\n     --\n     --This is useful when topicB does not depend on topicA.\n     --\n     --A range of commits could also be removed with rebase.  If we have\n     --the following situation:\n     --\n     --------------\n     --    E---F---G---H---I---J  topicA\n     --------------\n     --\n     --then the command\n     --\n     --    git rebase --onto topicA~5 topicA~3 topicA\n     --\n     --would result in the removal of commits F and G:\n     --\n     --------------\n     --    E---H'---I'---J'  topicA\n     --------------\n     --\n     --This is useful if F and G were flawed in some way, or should not be\n     --part of topicA.  Note that the argument to `--onto` and the `<upstream>`\n     --parameter can be any valid commit-ish.\n     --\n     - MODE OPTIONS\n     - ------------\n     - \n     ++TRANSPLANTING A TOPIC BRANCH WITH --ONTO\n     ++----------------------------------------\n     ++\n     + Here is how you would transplant a topic branch based on one\n     + branch to another, to pretend that you forked the topic branch\n     + from the latter branch, using `rebase --onto`.\n      @@ Documentation/git-rebase.adoc: As a special case, you may use \"A\\...B\" as a shortcut for the\n       merge base of A and B if there is exactly one merge base. You can\n       leave out at most one of A and B, in which case it defaults to HEAD.\n       \n     -+See TRANSPLANTING A TOPIC BRANCH WITH --ONTO below for examples.\n     ++See TRANSPLANTING A TOPIC BRANCH WITH --ONTO above for examples.\n      +\n       --keep-base::\n       \tSet the starting point at which to create the new commits to the\n       \tmerge base of `<upstream>` and `<branch>`. Running\n     -@@ Documentation/git-rebase.adoc: consistent (they compile, pass the testsuite, etc.) you should use\n     - after each commit, test, and amend the commit if fixes are necessary.\n     - \n     - \n     -+TRANSPLANTING A TOPIC BRANCH WITH --ONTO\n     -+----------------------------------------\n     -+\n     -+Here is how you would transplant a topic branch based on one\n     -+branch to another, to pretend that you forked the topic branch\n     -+from the latter branch, using `rebase --onto`.\n     -+\n     -+First let's assume your 'topic' is based on branch 'next'.\n     -+For example, a feature developed in 'topic' depends on some\n     -+functionality which is found in 'next'.\n     -+\n     -+------------\n     -+    o---o---o---o---o  master\n     -+         \\\n     -+          o---o---o---o---o  next\n     -+                           \\\n     -+                            o---o---o  topic\n     -+------------\n     -+\n     -+We want to make 'topic' forked from branch 'master'; for example,\n     -+because the functionality on which 'topic' depends was merged into the\n     -+more stable 'master' branch. We want our tree to look like this:\n     -+\n     -+------------\n     -+    o---o---o---o---o  master\n     -+        |            \\\n     -+        |             o'--o'--o'  topic\n     -+         \\\n     -+          o---o---o---o---o  next\n     -+------------\n     -+\n     -+We can get this using the following command:\n     -+\n     -+    git rebase --onto master next topic\n     -+\n     -+\n     -+Another example of --onto option is to rebase part of a\n     -+branch.  If we have the following situation:\n     -+\n     -+------------\n     -+                            H---I---J topicB\n     -+                           /\n     -+                  E---F---G  topicA\n     -+                 /\n     -+    A---B---C---D  master\n     -+------------\n     -+\n     -+then the command\n     -+\n     -+    git rebase --onto master topicA topicB\n     -+\n     -+would result in:\n     -+\n     -+------------\n     -+                 H'--I'--J'  topicB\n     -+                /\n     -+                | E---F---G  topicA\n     -+                |/\n     -+    A---B---C---D  master\n     -+------------\n     -+\n     -+This is useful when topicB does not depend on topicA.\n     -+\n     -+A range of commits could also be removed with rebase.  If we have\n     -+the following situation:\n     -+\n     -+------------\n     -+    E---F---G---H---I---J  topicA\n     -+------------\n     -+\n     -+then the command\n     -+\n     -+    git rebase --onto topicA~5 topicA~3 topicA\n     -+\n     -+would result in the removal of commits F and G:\n     -+\n     -+------------\n     -+    E---H'---I'---J'  topicA\n     -+------------\n     -+\n     -+This is useful if F and G were flawed in some way, or should not be\n     -+part of topicA.  Note that the argument to `--onto` and the `<upstream>`\n     -+parameter can be any valid commit-ish.\n     -+\n     -+\n     - RECOVERING FROM UPSTREAM REBASE\n     - -------------------------------\n     - \n 5:  cb85642bb9d ! 5:  5a1dd8df29b doc: git-rebase: update discussion of internals\n     @@ Documentation/git-rebase.adoc: linkgit:git-config[1] for details) and the `--for\n      +tip, however, is accessible using the reflog of the current branch (i.e. `@{1}`,\n      +see linkgit:gitrevisions[7].\n       \n     - MODE OPTIONS\n     - ------------\n     + TRANSPLANTING A TOPIC BRANCH WITH --ONTO\n     + ----------------------------------------\n\n-- \ngitgitgadget\n"},{"id":"524744","messageId":"ea1438e094e950d75196fdab79e22c174251bb66.1755909782.git.gitgitgadget@gmail.com","threadId":"63930","inReplyTo":"pull.1949.v9.git.1755909782.gitgitgadget@gmail.com","subject":"[PATCH v9 1/5] doc: git-rebase: start with an example","fromName":"Julia Evans via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-08-23T00:42:58Z","receivedAt":"2025-08-23T00:43:07Z","isPatch":true,"sender":{"key":"julia@jvns.ca","avatar":"https://avatars.githubusercontent.com/u/817739?v=4"},"body":"From: Julia Evans <julia@jvns.ca>\n\n- Start with an example that mirrors the example in the `git-merge` man\n  page, to make it easier for folks to understand the difference between\n  a rebase and a merge.\n- Mention that rebase can combine or reorder commits\n\nSigned-off-by: Julia Evans <julia@jvns.ca>\n---\n Documentation/git-rebase.adoc | 52 +++++++++++++++++------------------\n 1 file changed, 26 insertions(+), 26 deletions(-)\n\ndiff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc\nindex 956d3048f5a6..bb5a3ff7f828 100644\n--- a/Documentation/git-rebase.adoc\n+++ b/Documentation/git-rebase.adoc\n@@ -16,6 +16,32 @@ SYNOPSIS\n \n DESCRIPTION\n -----------\n+Transplant a series of commits onto a different starting point.\n+You can also use `git rebase` to reorder or combine commits: see INTERACTIVE\n+MODE below for how to do that.\n+\n+For example, imagine that you have been working on the `topic` branch in this\n+history, and you want to \"catch up\" to the work done on the `master` branch.\n+\n+------------\n+          A---B---C topic\n+         /\n+    D---E---F---G master\n+------------\n+\n+You want to transplant the commits you made on `topic` since it diverged from\n+`master` (i.e. A, B, and C), on top of the current `master`.  You can do this\n+by running `git rebase master` while the `topic` branch is checked out.  If you\n+want to rebase `topic` while on another branch, `git rebase master topic` is a\n+shortcut for `git checkout topic && git rebase master`.\n+\n+------------\n+                  A'--B'--C' topic\n+                 /\n+    D---E---F---G master\n+------------\n+\n+\n If `<branch>` is specified, `git rebase` will perform an automatic\n `git switch <branch>` before doing anything else.  Otherwise\n it remains on the current branch.\n@@ -58,32 +84,6 @@ that caused the merge failure with `git rebase --skip`.  To check out the\n original `<branch>` and remove the `.git/rebase-apply` working files, use\n the command `git rebase --abort` instead.\n \n-Assume the following history exists and the current branch is \"topic\":\n-\n-------------\n-          A---B---C topic\n-         /\n-    D---E---F---G master\n-------------\n-\n-From this point, the result of either of the following commands:\n-\n-\n-    git rebase master\n-    git rebase master topic\n-\n-would be:\n-\n-------------\n-                  A'--B'--C' topic\n-                 /\n-    D---E---F---G master\n-------------\n-\n-*NOTE:* The latter form is just a short-hand of `git checkout topic`\n-followed by `git rebase master`. When rebase exits `topic` will\n-remain the checked-out branch.\n-\n If the upstream branch already contains a change you have made (e.g.,\n because you mailed a patch which was applied upstream), then that commit\n will be skipped and warnings will be issued (if the 'merge' backend is\n-- \ngitgitgadget\n\n"},{"id":"524745","messageId":"339b7a1bc5be0fe3fd56c03c49e4c578d04c33d0.1755909782.git.gitgitgadget@gmail.com","threadId":"63930","inReplyTo":"pull.1949.v9.git.1755909782.gitgitgadget@gmail.com","subject":"[PATCH v9 2/5] doc: git rebase: dedup merge conflict discussion","fromName":"Julia Evans via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-08-23T00:42:59Z","receivedAt":"2025-08-23T00:43:08Z","isPatch":true,"sender":{"key":"julia@jvns.ca","avatar":"https://avatars.githubusercontent.com/u/817739?v=4"},"body":"From: Julia Evans <julia@jvns.ca>\n\nPreviously there were two explanations, this combines them both into a\nsingle explanation.\n\nSigned-off-by: Julia Evans <julia@jvns.ca>\n---\n Documentation/git-rebase.adoc | 49 ++++++++++++++---------------------\n 1 file changed, 20 insertions(+), 29 deletions(-)\n\ndiff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc\nindex bb5a3ff7f828..e82ceb9cbfce 100644\n--- a/Documentation/git-rebase.adoc\n+++ b/Documentation/git-rebase.adoc\n@@ -42,6 +42,26 @@ shortcut for `git checkout topic && git rebase master`.\n ------------\n \n \n+If there is a merge conflict during this process, `git rebase` will stop at the\n+first problematic commit and leave conflict markers. If this happens, you can do\n+one of these things:\n+\n+1. Resolve the conflict. You can use `git diff` to find the markers (<<<<<<)\n+   and make edits to resolve the conflict. For each file you edit, you need to\n+   tell Git that the conflict has been resolved. You can mark the conflict as\n+   resolved with  `git add <filename>`. After resolving all of the conflicts,\n+   you can continue the rebasing process with\n+\n+   git rebase --continue\n+\n+2. Stop the `git rebase` and return your branch to its original state with\n+\n+   git rebase --abort\n+\n+3. Skip the commit that caused the merge conflict with\n+\n+   git rebase --skip\n+\n If `<branch>` is specified, `git rebase` will perform an automatic\n `git switch <branch>` before doing anything else.  Otherwise\n it remains on the current branch.\n@@ -77,13 +97,6 @@ any commits in `HEAD` which introduce the same textual changes as a commit\n in `HEAD..<upstream>` are omitted (i.e., a patch already accepted upstream\n with a different commit message or timestamp will be skipped).\n \n-It is possible that a merge failure will prevent this process from being\n-completely automatic.  You will have to resolve any such merge failure\n-and run `git rebase --continue`.  Another option is to bypass the commit\n-that caused the merge failure with `git rebase --skip`.  To check out the\n-original `<branch>` and remove the `.git/rebase-apply` working files, use\n-the command `git rebase --abort` instead.\n-\n If the upstream branch already contains a change you have made (e.g.,\n because you mailed a patch which was applied upstream), then that commit\n will be skipped and warnings will be issued (if the 'merge' backend is\n@@ -186,28 +199,6 @@ This is useful if F and G were flawed in some way, or should not be\n part of topicA.  Note that the argument to `--onto` and the `<upstream>`\n parameter can be any valid commit-ish.\n \n-In case of conflict, `git rebase` will stop at the first problematic commit\n-and leave conflict markers in the tree.  You can use `git diff` to locate\n-the markers (<<<<<<) and make edits to resolve the conflict.  For each\n-file you edit, you need to tell Git that the conflict has been resolved,\n-typically this would be done with\n-\n-\n-    git add <filename>\n-\n-\n-After resolving the conflict manually and updating the index with the\n-desired resolution, you can continue the rebasing process with\n-\n-\n-    git rebase --continue\n-\n-\n-Alternatively, you can undo the 'git rebase' with\n-\n-\n-    git rebase --abort\n-\n MODE OPTIONS\n ------------\n \n-- \ngitgitgadget\n\n"},{"id":"524746","messageId":"f42c2c794a96c9a2dcb34bd7fe7b202466b3ffe0.1755909782.git.gitgitgadget@gmail.com","threadId":"63930","inReplyTo":"pull.1949.v9.git.1755909782.gitgitgadget@gmail.com","subject":"[PATCH v9 3/5] doc: git rebase: clarify arguments syntax","fromName":"Julia Evans via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-08-23T00:43:00Z","receivedAt":"2025-08-23T00:43:08Z","isPatch":true,"sender":{"key":"julia@jvns.ca","avatar":"https://avatars.githubusercontent.com/u/817739?v=4"},"body":"From: Julia Evans <julia@jvns.ca>\n\nRemove duplicate explanation of `git rebase <upstream> <branch>` which\nis already explained above.\n\nSigned-off-by: Julia Evans <julia@jvns.ca>\n---\n Documentation/git-rebase.adoc | 6 +-----\n 1 file changed, 1 insertion(+), 5 deletions(-)\n\ndiff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc\nindex e82ceb9cbfce..6d02648a9b3c 100644\n--- a/Documentation/git-rebase.adoc\n+++ b/Documentation/git-rebase.adoc\n@@ -62,11 +62,7 @@ one of these things:\n \n    git rebase --skip\n \n-If `<branch>` is specified, `git rebase` will perform an automatic\n-`git switch <branch>` before doing anything else.  Otherwise\n-it remains on the current branch.\n-\n-If `<upstream>` is not specified, the upstream configured in\n+If you don't specify an `<upstream>` to rebase onto, the upstream configured in\n `branch.<name>.remote` and `branch.<name>.merge` options will be used (see\n linkgit:git-config[1] for details) and the `--fork-point` option is\n assumed.  If you are currently not on any branch or if the current\n-- \ngitgitgadget\n\n"},{"id":"524748","messageId":"9c2a54ab9fa9b3dea47f4ab366fc5ff7c8946a3f.1755909782.git.gitgitgadget@gmail.com","threadId":"63930","inReplyTo":"pull.1949.v9.git.1755909782.gitgitgadget@gmail.com","subject":"[PATCH v9 4/5] doc: git-rebase: move --onto explanation down","fromName":"Julia Evans via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-08-23T00:43:01Z","receivedAt":"2025-08-23T00:43:09Z","isPatch":true,"sender":{"key":"julia@jvns.ca","avatar":"https://avatars.githubusercontent.com/u/817739?v=4"},"body":"From: Julia Evans <julia@jvns.ca>\n\nThere's a very clear explanation with examples of using --onto which is\ncurrently buried in the very long DESCRIPTION section. This moves it to\nits own section, so that we can reference the explanation from the\n`--onto` option by name.\n\nSigned-off-by: Julia Evans <julia@jvns.ca>\n---\n Documentation/git-rebase.adoc | 5 +++++\n 1 file changed, 5 insertions(+)\n\ndiff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc\nindex 6d02648a9b3c..b3354e0e4f82 100644\n--- a/Documentation/git-rebase.adoc\n+++ b/Documentation/git-rebase.adoc\n@@ -114,6 +114,9 @@ will result in:\n     D---E---A'---F master\n ------------\n \n+TRANSPLANTING A TOPIC BRANCH WITH --ONTO\n+----------------------------------------\n+\n Here is how you would transplant a topic branch based on one\n branch to another, to pretend that you forked the topic branch\n from the latter branch, using `rebase --onto`.\n@@ -240,6 +243,8 @@ As a special case, you may use \"A\\...B\" as a shortcut for the\n merge base of A and B if there is exactly one merge base. You can\n leave out at most one of A and B, in which case it defaults to HEAD.\n \n+See TRANSPLANTING A TOPIC BRANCH WITH --ONTO above for examples.\n+\n --keep-base::\n \tSet the starting point at which to create the new commits to the\n \tmerge base of `<upstream>` and `<branch>`. Running\n-- \ngitgitgadget\n\n"},{"id":"524747","messageId":"5a1dd8df29baf68c780d76880a5eb586e20102fa.1755909782.git.gitgitgadget@gmail.com","threadId":"63930","inReplyTo":"pull.1949.v9.git.1755909782.gitgitgadget@gmail.com","subject":"[PATCH v9 5/5] doc: git-rebase: update discussion of internals","fromName":"Julia Evans via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-08-23T00:43:02Z","receivedAt":"2025-08-23T00:43:10Z","isPatch":true,"sender":{"key":"julia@jvns.ca","avatar":"https://avatars.githubusercontent.com/u/817739?v=4"},"body":"From: Julia Evans <julia@jvns.ca>\n\n- make it clearer that we're talking about a multistep process\n- give a more technically accurate description how rebase works with the\n  merge backend.\n- condense the explanation of how git rebase skips commits with the same\n  textual changes into a single bullet point and remove the explanatory\n  diagram. Lots of things which are more complicated are already being\n  explained without a diagram.\n- remove the explanation of how exactly `--fork-point` and `--root`\n  work since that information is in the OPTIONS section\n- put all discussion of `ORIG_HEAD` inside the note\n\nSigned-off-by: Julia Evans <julia@jvns.ca>\n---\n Documentation/git-rebase.adoc | 61 +++++++++++------------------------\n 1 file changed, 18 insertions(+), 43 deletions(-)\n\ndiff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc\nindex b3354e0e4f82..d2f760af6866 100644\n--- a/Documentation/git-rebase.adoc\n+++ b/Documentation/git-rebase.adoc\n@@ -68,51 +68,26 @@ linkgit:git-config[1] for details) and the `--fork-point` option is\n assumed.  If you are currently not on any branch or if the current\n branch does not have a configured upstream, the rebase will abort.\n \n-All changes made by commits in the current branch but that are not\n-in `<upstream>` are saved to a temporary area.  This is the same set\n-of commits that would be shown by `git log <upstream>..HEAD`; or by\n-`git log 'fork_point'..HEAD`, if `--fork-point` is active (see the\n-description on `--fork-point` below); or by `git log HEAD`, if the\n-`--root` option is specified.\n-\n-The current branch is reset to `<upstream>` or `<newbase>` if the\n-`--onto` option was supplied.  This has the exact same effect as\n-`git reset --hard <upstream>` (or `<newbase>`). `ORIG_HEAD` is set\n-to point at the tip of the branch before the reset.\n+Here is a simplified description of what `git rebase <upstream>` does:\n+\n+1. Make a list of all commits on your current branch since it branched\n+   off from `<upstream>` that do not have an equivalent commit in\n+   `<upstream>`.\n+2. Check out `<upstream>` with the equivalent of\n+   `git checkout --detach <upstream>`.\n+3. Replay the commits, one by one, in order. This is similar to running\n+   `git cherry-pick <commit>` for each commit. See REBASING MERGES for how merges\n+   are handled.\n+4. Update your branch to point to the final commit with the equivalent\n+   of `git checkout -B <branch>`.\n \n [NOTE]\n-`ORIG_HEAD` is not guaranteed to still point to the previous branch tip\n-at the end of the rebase if other commands that write that pseudo-ref\n-(e.g. `git reset`) are used during the rebase. The previous branch tip,\n-however, is accessible using the reflog of the current branch\n-(i.e. `@{1}`, see linkgit:gitrevisions[7]).\n-\n-The commits that were previously saved into the temporary area are\n-then reapplied to the current branch, one by one, in order. Note that\n-any commits in `HEAD` which introduce the same textual changes as a commit\n-in `HEAD..<upstream>` are omitted (i.e., a patch already accepted upstream\n-with a different commit message or timestamp will be skipped).\n-\n-If the upstream branch already contains a change you have made (e.g.,\n-because you mailed a patch which was applied upstream), then that commit\n-will be skipped and warnings will be issued (if the 'merge' backend is\n-used).  For example, running `git rebase master` on the following\n-history (in which `A'` and `A` introduce the same set of changes, but\n-have different committer information):\n-\n-------------\n-          A---B---C topic\n-         /\n-    D---E---A'---F master\n-------------\n-\n-will result in:\n-\n-------------\n-                   B'---C' topic\n-                  /\n-    D---E---A'---F master\n-------------\n+When starting the rebase, `ORIG_HEAD` is set to point to the commit at the tip\n+of the to-be-rebased branch. However, `ORIG_HEAD` is not guaranteed to still\n+point to that commit at the end of the rebase if other commands that change\n+`ORIG_HEAD` (like `git reset`) are used during the rebase. The previous branch\n+tip, however, is accessible using the reflog of the current branch (i.e. `@{1}`,\n+see linkgit:gitrevisions[7].\n \n TRANSPLANTING A TOPIC BRANCH WITH --ONTO\n ----------------------------------------\n-- \ngitgitgadget\n"}]}