index b86e80bb669081a9e86b14be61ad7604ec5d275b..3d6d429e5e28d6a4520c3b54adb3ad065a3b774f 100644 (file)
SYNOPSIS
--------
[verse]
-'git rebase' [-i | --interactive] [-v | --verbose] [-m | --merge]
- [-s <strategy> | --strategy=<strategy>]
- [-C<n>] [ --whitespace=<option>] [-p | --preserve-merges]
- [--onto <newbase>] <upstream> [<branch>]
+'git rebase' [-i | --interactive] [options] [--onto <newbase>]
+ <upstream> [<branch>]
+'git rebase' [-i | --interactive] [options] --onto <newbase>
+ --root [<branch>]
+
'git rebase' --continue | --skip | --abort
DESCRIPTION
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`.
+of commits that would be shown by `git log <upstream>..HEAD` (or
+`git log HEAD`, if --root is specified).
The current branch is reset to <upstream>, or <newbase> if the
--onto option was supplied. This has the exact same effect as
--verbose::
Display a diffstat of what changed upstream since the last rebase.
+--no-verify::
+ This option bypasses the pre-rebase hook. See also linkgit:githooks[5].
+
-C<n>::
Ensure at least <n> lines of surrounding context match before
and after each change. When fewer lines of surrounding
--preserve-merges::
Instead of ignoring merges, try to recreate them.
+--root::
+ Rebase all commits reachable from <branch>, instead of
+ limiting them with an <upstream>. This allows you to rebase
+ the root commit(s) on a branch. Must be used with --onto, and
+ will skip changes already contained in <newbase> (instead of
+ <upstream>). When used together with --preserve-merges, 'all'
+ root commits will be rewritten to have <newbase> as parent
+ instead.
+
include::merge-strategies.txt[]
NOTES
-----
-When you rebase a branch, you are changing its history in a way that
-will cause problems for anyone who already has a copy of the branch
-in their repository and tries to pull updates from you. You should
-understand the implications of using 'git-rebase' on a repository that
-you share.
+
+You should understand the implications of using 'git-rebase' on a
+repository that you share. See also RECOVERING FROM UPSTREAM REBASE
+below.
When the git-rebase command is run, it will first execute a "pre-rebase"
hook if one exists. You can use this hook to do sanity checks and
after each commit, test, and amend the commit if fixes are necessary.
+RECOVERING FROM UPSTREAM REBASE
+-------------------------------
+
+Rebasing (or any other form of rewriting) a branch that others have
+based work on is a bad idea: anyone downstream of it is forced to
+manually fix their history. This section explains how to do the fix
+from the downstream's point of view. The real fix, however, would be
+to avoid rebasing the upstream in the first place.
+
+To illustrate, suppose you are in a situation where someone develops a
+'subsystem' branch, and you are working on a 'topic' that is dependent
+on this 'subsystem'. You might end up with a history like the
+following:
+
+------------
+ o---o---o---o---o---o---o---o---o master
+ \
+ o---o---o---o---o subsystem
+ \
+ *---*---* topic
+------------
+
+If 'subsystem' is rebased against 'master', the following happens:
+
+------------
+ o---o---o---o---o---o---o---o master
+ \ \
+ o---o---o---o---o o'--o'--o'--o'--o' subsystem
+ \
+ *---*---* topic
+------------
+
+If you now continue development as usual, and eventually merge 'topic'
+to 'subsystem', the commits from 'subsystem' will remain duplicated forever:
+
+------------
+ o---o---o---o---o---o---o---o master
+ \ \
+ o---o---o---o---o o'--o'--o'--o'--o'--M subsystem
+ \ /
+ *---*---*-..........-*--* topic
+------------
+
+Such duplicates are generally frowned upon because they clutter up
+history, making it harder to follow. To clean things up, you need to
+transplant the commits on 'topic' to the new 'subsystem' tip, i.e.,
+rebase 'topic'. This becomes a ripple effect: anyone downstream from
+'topic' is forced to rebase too, and so on!
+
+There are two kinds of fixes, discussed in the following subsections:
+
+Easy case: The changes are literally the same.::
+
+ This happens if the 'subsystem' rebase was a simple rebase and
+ had no conflicts.
+
+Hard case: The changes are not the same.::
+
+ This happens if the 'subsystem' rebase had conflicts, or used
+ `\--interactive` to omit, edit, or squash commits; or if the
+ upstream used one of `commit \--amend`, `reset`, or
+ `filter-branch`.
+
+
+The easy case
+~~~~~~~~~~~~~
+
+Only works if the changes (patch IDs based on the diff contents) on
+'subsystem' are literally the same before and after the rebase
+'subsystem' did.
+
+In that case, the fix is easy because 'git-rebase' knows to skip
+changes that are already present in the new upstream. So if you say
+(assuming you're on 'topic')
+------------
+ $ git rebase subsystem
+------------
+you will end up with the fixed history
+------------
+ o---o---o---o---o---o---o---o master
+ \
+ o'--o'--o'--o'--o' subsystem
+ \
+ *---*---* topic
+------------
+
+
+The hard case
+~~~~~~~~~~~~~
+
+Things get more complicated if the 'subsystem' changes do not exactly
+correspond to the ones before the rebase.
+
+NOTE: While an "easy case recovery" sometimes appears to be successful
+ even in the hard case, it may have unintended consequences. For
+ example, a commit that was removed via `git rebase
+ \--interactive` will be **resurrected**!
+
+The idea is to manually tell 'git-rebase' "where the old 'subsystem'
+ended and your 'topic' began", that is, what the old merge-base
+between them was. You will have to find a way to name the last commit
+of the old 'subsystem', for example:
+
+* With the 'subsystem' reflog: after 'git-fetch', the old tip of
+ 'subsystem' is at `subsystem@\{1}`. Subsequent fetches will
+ increase the number. (See linkgit:git-reflog[1].)
+
+* Relative to the tip of 'topic': knowing that your 'topic' has three
+ commits, the old tip of 'subsystem' must be `topic~3`.
+
+You can then transplant the old `subsystem..topic` to the new tip by
+saying (for the reflog case, and assuming you are on 'topic' already):
+------------
+ $ git rebase --onto subsystem subsystem@{1}
+------------
+
+The ripple effect of a "hard case" recovery is especially bad:
+'everyone' downstream from 'topic' will now have to perform a "hard
+case" recovery too!
+
+
Authors
------
Written by Junio C Hamano <gitster@pobox.com> and