diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc index 956d3048f5a618..d2f760af68666b 100644 --- a/Documentation/git-rebase.adoc +++ b/Documentation/git-rebase.adoc @@ -16,49 +16,12 @@ SYNOPSIS DESCRIPTION ----------- -If `` is specified, `git rebase` will perform an automatic -`git switch ` before doing anything else. Otherwise -it remains on the current branch. +Transplant a series of commits onto a different starting point. +You can also use `git rebase` to reorder or combine commits: see INTERACTIVE +MODE below for how to do that. -If `` is not specified, the upstream configured in -`branch..remote` and `branch..merge` options will be used (see -linkgit:git-config[1] for details) and the `--fork-point` option is -assumed. If you are currently not on any branch or if the current -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 `` are saved to a temporary area. This is the same set -of commits that would be shown by `git log ..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 `` or `` if the -`--onto` option was supplied. This has the exact same effect as -`git reset --hard ` (or ``). `ORIG_HEAD` is set -to point at the tip of the branch before the reset. - -[NOTE] -`ORIG_HEAD` is not guaranteed to still point to the previous branch tip -at the end of the rebase if other commands that write that pseudo-ref -(e.g. `git reset`) are used during the rebase. The previous branch tip, -however, is accessible using the reflog of the current branch -(i.e. `@{1}`, see linkgit:gitrevisions[7]). - -The commits that were previously saved into the temporary area are -then reapplied to the current branch, one by one, in order. Note that -any commits in `HEAD` which introduce the same textual changes as a commit -in `HEAD..` are omitted (i.e., a patch already accepted upstream -with a different commit message or timestamp will be skipped). - -It is possible that a merge failure will prevent this process from being -completely automatic. You will have to resolve any such merge failure -and run `git rebase --continue`. Another option is to bypass the commit -that caused the merge failure with `git rebase --skip`. To check out the -original `` and remove the `.git/rebase-apply` working files, use -the command `git rebase --abort` instead. - -Assume the following history exists and the current branch is "topic": +For example, imagine that you have been working on the `topic` branch in this +history, and you want to "catch up" to the work done on the `master` branch. ------------ A---B---C topic @@ -66,13 +29,11 @@ Assume the following history exists and the current branch is "topic": D---E---F---G master ------------ -From this point, the result of either of the following commands: - - - git rebase master - git rebase master topic - -would be: +You want to transplant the commits you made on `topic` since it diverged from +`master` (i.e. A, B, and C), on top of the current `master`. You can do this +by running `git rebase master` while the `topic` branch is checked out. If you +want to rebase `topic` while on another branch, `git rebase master topic` is a +shortcut for `git checkout topic && git rebase master`. ------------ A'--B'--C' topic @@ -80,30 +41,56 @@ would be: D---E---F---G master ------------ -*NOTE:* The latter form is just a short-hand of `git checkout topic` -followed by `git rebase master`. When rebase exits `topic` will -remain the checked-out branch. -If the upstream branch already contains a change you have made (e.g., -because you mailed a patch which was applied upstream), then that commit -will be skipped and warnings will be issued (if the 'merge' backend is -used). For example, running `git rebase master` on the following -history (in which `A'` and `A` introduce the same set of changes, but -have different committer information): +If there is a merge conflict during this process, `git rebase` will stop at the +first problematic commit and leave conflict markers. If this happens, you can do +one of these things: ------------- - A---B---C topic - / - D---E---A'---F master ------------- +1. Resolve the conflict. You can use `git diff` to find the markers (<<<<<<) + and make edits to resolve the conflict. For each file you edit, you need to + tell Git that the conflict has been resolved. You can mark the conflict as + resolved with `git add `. After resolving all of the conflicts, + you can continue the rebasing process with -will result in: + git rebase --continue ------------- - B'---C' topic - / - D---E---A'---F master ------------- +2. Stop the `git rebase` and return your branch to its original state with + + git rebase --abort + +3. Skip the commit that caused the merge conflict with + + git rebase --skip + +If you don't specify an `` to rebase onto, the upstream configured in +`branch..remote` and `branch..merge` options will be used (see +linkgit:git-config[1] for details) and the `--fork-point` option is +assumed. If you are currently not on any branch or if the current +branch does not have a configured upstream, the rebase will abort. + +Here is a simplified description of what `git rebase ` does: + +1. Make a list of all commits on your current branch since it branched + off from `` that do not have an equivalent commit in + ``. +2. Check out `` with the equivalent of + `git checkout --detach `. +3. Replay the commits, one by one, in order. This is similar to running + `git cherry-pick ` for each commit. See REBASING MERGES for how merges + are handled. +4. Update your branch to point to the final commit with the equivalent + of `git checkout -B `. + +[NOTE] +When starting the rebase, `ORIG_HEAD` is set to point to the commit at the tip +of the to-be-rebased branch. However, `ORIG_HEAD` is not guaranteed to still +point to that commit at the end of the rebase if other commands that change +`ORIG_HEAD` (like `git reset`) are used during the rebase. The previous branch +tip, however, is accessible using the reflog of the current branch (i.e. `@{1}`, +see linkgit:gitrevisions[7]. + +TRANSPLANTING A TOPIC BRANCH WITH --ONTO +---------------------------------------- Here is how you would transplant a topic branch based on one branch to another, to pretend that you forked the topic branch @@ -186,28 +173,6 @@ This is useful if F and G were flawed in some way, or should not be part of topicA. Note that the argument to `--onto` and the `` parameter can be any valid commit-ish. -In case of conflict, `git rebase` will stop at the first problematic commit -and leave conflict markers in the tree. You can use `git diff` to locate -the markers (<<<<<<) and make edits to resolve the conflict. For each -file you edit, you need to tell Git that the conflict has been resolved, -typically this would be done with - - - git add - - -After resolving the conflict manually and updating the index with the -desired resolution, you can continue the rebasing process with - - - git rebase --continue - - -Alternatively, you can undo the 'git rebase' with - - - git rebase --abort - MODE OPTIONS ------------ @@ -253,6 +218,8 @@ As a special case, you may use "A\...B" as a shortcut for the merge base of A and B if there is exactly one merge base. You can leave out at most one of A and B, in which case it defaults to HEAD. +See TRANSPLANTING A TOPIC BRANCH WITH --ONTO above for examples. + --keep-base:: Set the starting point at which to create the new commits to the merge base of `` and ``. Running