git-p4: Fix regression in p4Where method.
[gitweb.git] / Documentation / git-rebase.txt
index f3459c7de7c9629f2abfdb684a359bb264ea82ed..c8ad86a56fc6bff70cb6e7c74cc8ef10ef2da73e 100644 (file)
@@ -9,7 +9,7 @@ SYNOPSIS
 --------
 [verse]
 'git rebase' [-i | --interactive] [-v | --verbose] [-m | --merge]
-       [-s <strategy> | --strategy=<strategy>]
+       [-s <strategy> | --strategy=<strategy>] [--no-verify]
        [-C<n>] [ --whitespace=<option>] [-p | --preserve-merges]
        [--onto <newbase>] <upstream> [<branch>]
 'git rebase' --continue | --skip | --abort
@@ -26,7 +26,8 @@ of commits that would be shown by `git log <upstream>..HEAD`.
 
 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>).
+`git reset --hard <upstream>` (or <newbase>).  ORIG_HEAD is set
+to point at the tip of the branch before the reset.
 
 The commits that were previously saved into the temporary area are
 then reapplied to the current branch, one by one, in order. Note that
@@ -38,8 +39,8 @@ 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 restore the
-original <branch> and remove the .dotest working files, use the command
-`git rebase --abort` instead.
+original <branch> 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":
 
@@ -91,7 +92,7 @@ branch to another, to pretend that you forked the topic branch
 from the latter branch, using `rebase --onto`.
 
 First let's assume your 'topic' is based on branch 'next'.
-For example feature developed in 'topic' depends on some
+For example, a feature developed in 'topic' depends on some
 functionality which is found in 'next'.
 
 ------------
@@ -102,9 +103,9 @@ functionality which is found in 'next'.
                             o---o---o  topic
 ------------
 
-We would want to make 'topic' forked from branch 'master',
-for example because the functionality 'topic' branch depend on
-got merged into more stable 'master' branch, like this:
+We want to make 'topic' forked from branch 'master'; for example,
+because the functionality on which 'topic' depends was merged into the
+more stable 'master' branch. We want our tree to look like this:
 
 ------------
     o---o---o---o---o  master
@@ -231,6 +232,9 @@ OPTIONS
 --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
@@ -249,18 +253,16 @@ OPTIONS
 
 -p::
 --preserve-merges::
-       Instead of ignoring merges, try to recreate them.  This option
-       only works in interactive mode.
+       Instead of ignoring merges, try to recreate them.
 
 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
@@ -395,9 +397,130 @@ consistent (they compile, pass the testsuite, etc.) you should use
 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 <junkio@cox.net> and
+Written by Junio C Hamano <gitster@pobox.com> and
 Johannes E. Schindelin <johannes.schindelin@gmx.de>
 
 Documentation