I liked the idea of trying a more ambitious rewrite of the "here's how git rebase works internally" section, so here's an attempt at it. My idea is to give an accurate technical description of how the merge backend works while deferring some of the details (like how exactly --fork-point works or what happens when you rebase a merge) to later in the man page. I've also tried to use a minimum of git jargon, for example saying "Then it checks out <upstream>" instead of mentioning anything about a "detached HEAD" since I know that term can jarring for folks who aren't used to that term. I hedged a bit by saying that rebase is "similar to" running git cherry-pick repeatedly since I think of a rebase as being like doing a bunch of cherry-picks (and very often hear people describing it that way), but I'm sure that there are differences that I'm not aware of. I've also updated the "clarify arguments syntax" commit message. Julia Evans (5): doc: git-rebase: start with an example doc: git rebase: dedup merge conflict discussion doc: git rebase: clarify arguments syntax doc: git-rebase: move --onto explanation down doc: git-rebase: update discussion of internals Documentation/git-rebase.adoc | 300 ++++++++++++++++------------------ 1 file changed, 145 insertions(+), 155 deletions(-) base-commit: 2c2ba49d55ff26c1082b8137b1ec5eeccb4337d1 Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1949%2Fjvns%2Fclarify-rebase-v3 Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1949/jvns/clarify-rebase-v3 Pull-Request: https://github.com/gitgitgadget/git/pull/1949 Range-diff vs v2: 1: 26b742eb49f = 1: 26b742eb49f doc: git-rebase: start with an example 2: 249a5127904 = 2: 249a5127904 doc: git rebase: dedup merge conflict discussion 3: ce7ab74ea0f ! 3: 013a5044ef3 doc: git rebase: clarify arguments syntax @@ Metadata ## Commit message ## doc: git rebase: clarify arguments syntax - This removes the explanation of `git rebase <upstream> <branch>`, since - it was already explained above that it's shorthand for `git switch - <branch> && git rebase <upstream>` + Remove duplicate explanation of `git rebase <upstream> <branch>` which + is already explained above. Signed-off-by: Julia Evans <julia@xxxxxxx> 4: 590d7486d3d = 4: c574a27412d doc: git-rebase: move --onto explanation down 5: ad97cd9e671 ! 5: eabacd3c159 doc: git-rebase: update discussion of internals @@ Metadata ## Commit message ## doc: git-rebase: update discussion of internals - - make it clearer that we're talking about three steps of a process + - make it clearer that we're talking about a multistep process + - give a more technically accurate description how rebase works with the + merge backend. - delete a duplicate explanation of how git rebase skips commits with the same textual changes (it's explained in more detail a few lines further down) - - move the `ORIG_HEAD` note down so that it doesn't interrupt the - discussion of the mechanics. + - remove the explanation of how exactly `--fork-point` and `--root` + work since that information is in the OPTIONS section + - put all discussion of `ORIG_HEAD` inside the note Signed-off-by: Julia Evans <julia@xxxxxxx> @@ Documentation/git-rebase.adoc: linkgit:git-config[1] for details) and the `--for branch does not have a configured upstream, the rebase will abort. -All changes made by commits in the current branch but that are not +-in `<upstream>` are saved to a temporary area. This is the same set +-of commits that would be shown by `git log <upstream>..HEAD`; or by +-`git log 'fork_point'..HEAD`, if `--fork-point` is active (see the +-description on `--fork-point` below); or by `git log HEAD`, if the +-`--root` option is specified. +- +-The current branch is reset to `<upstream>` or `<newbase>` if the +-`--onto` option was supplied. This has the exact same effect as +-`git reset --hard <upstream>` (or `<newbase>`). `ORIG_HEAD` is set +-to point at the tip of the branch before the reset. +Here is a more detailed description of what `git rebase <upstream>` does: + -+First, all changes made by commits in the current branch but that are not - in `<upstream>` are saved to a temporary area. This is the same set - of commits that would be shown by `git log <upstream>..HEAD`; or by - `git log 'fork_point'..HEAD`, if `--fork-point` is active (see the - description on `--fork-point` below); or by `git log HEAD`, if the - `--root` option is specified. - --The current branch is reset to `<upstream>` or `<newbase>` if the -+Then the current branch is reset to `<upstream>` or `<newbase>` if the - `--onto` option was supplied. This has the exact same effect as - `git reset --hard <upstream>` (or `<newbase>`). `ORIG_HEAD` is set - to point at the tip of the branch before the reset. - -+Then the commits that were previously saved into the temporary area are -+reapplied to the current branch, one by one, in order. ++First, it makes a list of all commits in the current branch that are not in ++`<upstream>`. This is the same set of commits that would be shown by `git log ++<upstream>..HEAD`. You can use `--fork-point` or `--root` to change how this ++list of commits is constructed. ++ ++Then it checks out `<upstream>` (or `<newbase>` if the `--onto` option was ++supplied) with the equivalent of `git switch --detach <upstream>`. + ++Then it replays the commits, one by one, in order. This is similar to running ++`git cherry-pick <commit>` for each commit. See REBASING MERGES for how merges ++are handled. ++ ++Finally, it updates your branch to point to the final commit with the equivalent ++of `git switch -C <branch>`. + [NOTE] ++`ORIG_HEAD` is set to point at the tip of the branch before the rebase. `ORIG_HEAD` is not guaranteed to still point to the previous branch tip at the end of the rebase if other commands that write that pseudo-ref -@@ Documentation/git-rebase.adoc: at the end of the rebase if other commands that write that pseudo-ref + (e.g. `git reset`) are used during the rebase. The previous branch tip, however, is accessible using the reflog of the current branch (i.e. `@{1}`, see linkgit:gitrevisions[7]). -- gitgitgadget