"Julia Evans via GitGitGadget" <gitgitgadget@xxxxxxxxx> writes: > From: Julia Evans <julia@xxxxxxx> > > - make it clearer that we're talking about three steps of a process A good call. "First, then, then" does make it clear where each new step begins. "First, then, finally" would make it even more obvious which step concludes the sequence, though. > - delete a duplicate explanation of how git rebase skips commits with > the same textual changes (it's explained in more detail a few lines > further down) OK. > - move the `ORIG_HEAD` note down so that it doesn't interrupt the > discussion of the mechanics. I thought you moved the "finally we reapply" up, instead of moving the note down ;-) And when viewed that way, a more direct way to justify this change is that you made sure these three steps are kept together. Again, good change. > -All changes made by commits in the current branch but that are not > +Here is a more detailed description of what `git rebase <upstream>` does: > + > +First, all changes made by commits in the current branch but that are not > in `<upstream>` are saved to a temporary area. This is the same set > of commits that would be shown by `git log <upstream>..HEAD`; or by > `git log 'fork_point'..HEAD`, if `--fork-point` is active (see the > description on `--fork-point` below); or by `git log HEAD`, if the > `--root` option is specified. If we are ambitious, we may want to rewrite this first step to put almost no stress on "saving" and "temporary area". Especially when you rebase with merge backend, it would be morally a sequence of cherry-pick, without us having to save anything---we only need to figure out which commits to replay in what order. First, the command figures out changes from which commits to replay in what order. The set of commits are those shown by `git log <base>..HEAD`, where <base> is the <upstream> if given, or computed fork-point if the `--fork-point` option is active, or all commits that lead to `HEAD` if `--root` is given. > -The current branch is reset to `<upstream>` or `<newbase>` if the > +Then the current branch is reset to `<upstream>` or `<newbase>` if the > `--onto` option was supplied. This has the exact same effect as > `git reset --hard <upstream>` (or `<newbase>`). `ORIG_HEAD` is set > to point at the tip of the branch before the reset. "This has the exact same effect as" made my reading hiccup. Then `git reset --hard` rewinds the current branch to the commit given by `--onto`, if specified, or to `<upstream>`. I am not sure if it is worth talking about ORIG_HEAD at this point, as that is part of what `git reset --hard` does with this step. Given especially that we have NOTE that says ORIG_HEAD cannot be relied upon once the replaying of commits begin, mentioning the value of ORIG_HEAD before the replaying begins does not seem to add much value to the explanation. > +Then the commits that were previously saved into the temporary area are > +reapplied to the current branch, one by one, in order. Yup. As I suggested, "Then" -> "Finally". I do not know how much detail we want to give to readers, and I do to prefer to tell some white lie in end-user facing documentation if simplified description helps the initial understanding, so I am not yet decided if I recommend rewriting these "three step" explanation, but FYI, the modern rebase machinery works slightly differently: First the command figures out what to replay, on which commit, and in what order. Then the HEAD is detached ("git checkout --detach <onto>") to the commit the first change is replayed onto. Then the changes are replayed, one by one, in the order. Optionally a mergy history can be rebased while retaining the topology. Finally, the branch being rebased is made to point at the resulting HEAD (i.e. equivalent to "git checkout -B <branch>" to jump back from the detached HEAD state). The difference between the simplified procedure and this "replaying is done while on detached HEAD" procedure gives us a somewhat big usability improvement, as a rebasing will be recorded in a single reflog event for the branch getting rebased, no matter how many commits are on the branch.