Code

Don't checkout the full tree if avoidable
[git.git] / Documentation / git-rebase.txt
index f2ef1f7dc093432e8b6c5644cbac5c5e857cb0ca..e8e75790fc21b403f428b8cca72ab42a072e1b38 100644 (file)
@@ -7,17 +7,28 @@ git-rebase - Forward-port local commits to the updated upstream head
 
 SYNOPSIS
 --------
-'git-rebase' [-v] [--merge] [-C<n>] [--onto <newbase>] <upstream> [<branch>]
-
+[verse]
+'git-rebase' [-i | --interactive] [-v | --verbose] [-m | --merge]
+       [-C<n>] [ --whitespace=<option>] [-p | --preserve-merges]
+       [--onto <newbase>] <upstream> [<branch>]
 'git-rebase' --continue | --skip | --abort
 
 DESCRIPTION
 -----------
-git-rebase replaces <branch> with a new branch of the same name.  When
-the --onto option is provided the new branch starts out with a HEAD equal
-to <newbase>, otherwise it is equal to <upstream>.  It then attempts to
-create a new commit for each commit from the original <branch> that does
-not exist in the <upstream> branch.
+If <branch> is specified, git-rebase will perform an automatic
+`git checkout <branch>` before doing anything else.  Otherwise
+it remains on the current branch.
+
+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`.
+
+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>).
+
+The commits that were previously saved into the temporary area are
+then reapplied to the current branch, one by one, in order.
 
 It is possible that a merge failure will prevent this process from being
 completely automatic.  You will have to resolve any such merge failure
@@ -26,9 +37,6 @@ 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.
 
-Note that if <branch> is not specified on the command line, the currently
-checked out branch is used.
-
 Assume the following history exists and the current branch is "topic":
 
 ------------
@@ -123,7 +131,7 @@ the following situation:
 
 then the command
 
-    git-rebase --onto topicA~5 topicA~2 topicA
+    git-rebase --onto topicA~5 topicA~3 topicA
 
 would result in the removal of commits F and G:
 
@@ -142,7 +150,7 @@ file you edit, you need to tell git that the conflict has been resolved,
 typically this would be done with
 
 
-    git update-index <filename>
+    git add <filename>
 
 
 After resolving the conflict manually and updating the index with the
@@ -181,7 +189,7 @@ OPTIONS
 --skip::
        Restart the rebasing process by skipping the current patch.
 
---merge::
+-m, \--merge::
        Use merging strategies to rebase.  When the recursive (default) merge
        strategy is used, this allows rebase to be aware of renames on the
        upstream side.
@@ -202,6 +210,19 @@ OPTIONS
        context exist they all must match.  By default no context is
        ever ignored.
 
+--whitespace=<nowarn|warn|error|error-all|strip>::
+       This flag is passed to the `git-apply` program
+       (see gitlink:git-apply[1]) that applies the patch.
+
+-i, \--interactive::
+       Make a list of the commits which are about to be rebased.  Let the
+       user edit that list before rebasing.  This mode can also be used to
+       split commits (see SPLITTING COMMITS below).
+
+-p, \--preserve-merges::
+       Instead of ignoring merges, try to recreate them.  This option
+       only works in interactive mode.
+
 include::merge-strategies.txt[]
 
 NOTES
@@ -220,9 +241,136 @@ pre-rebase hook script for an example.
 You must be in the top directory of your project to start (or continue)
 a rebase.  Upon completion, <branch> will be the current branch.
 
-Author
+INTERACTIVE MODE
+----------------
+
+Rebasing interactively means that you have a chance to edit the commits
+which are rebased.  You can reorder the commits, and you can
+remove them (weeding out bad or otherwise unwanted patches).
+
+The interactive mode is meant for this type of workflow:
+
+1. have a wonderful idea
+2. hack on the code
+3. prepare a series for submission
+4. submit
+
+where point 2. consists of several instances of
+
+a. regular use
+ 1. finish something worthy of a commit
+ 2. commit
+b. independent fixup
+ 1. realize that something does not work
+ 2. fix that
+ 3. commit it
+
+Sometimes the thing fixed in b.2. cannot be amended to the not-quite
+perfect commit it fixes, because that commit is buried deeply in a
+patch series.  That is exactly what interactive rebase is for: use it
+after plenty of "a"s and "b"s, by rearranging and editing
+commits, and squashing multiple commits into one.
+
+Start it with the last commit you want to retain as-is:
+
+       git rebase -i <after-this-commit>
+
+An editor will be fired up with all the commits in your current branch
+(ignoring merge commits), which come after the given commit.  You can
+reorder the commits in this list to your heart's content, and you can
+remove them.  The list looks more or less like this:
+
+-------------------------------------------
+pick deadbee The oneline of this commit
+pick fa1afe1 The oneline of the next commit
+...
+-------------------------------------------
+
+The oneline descriptions are purely for your pleasure; `git-rebase` will
+not look at them but at the commit names ("deadbee" and "fa1afe1" in this
+example), so do not delete or edit the names.
+
+By replacing the command "pick" with the command "edit", you can tell
+`git-rebase` to stop after applying that commit, so that you can edit
+the files and/or the commit message, amend the commit, and continue
+rebasing.
+
+If you want to fold two or more commits into one, replace the command
+"pick" with "squash" for the second and subsequent commit.  If the
+commits had different authors, it will attribute the squashed commit to
+the author of the first commit.
+
+In both cases, or when a "pick" does not succeed (because of merge
+errors), the loop will stop to let you fix things, and you can continue
+the loop with `git rebase --continue`.
+
+For example, if you want to reorder the last 5 commits, such that what
+was HEAD~4 becomes the new HEAD. To achieve that, you would call
+`git-rebase` like this:
+
+----------------------
+$ git rebase -i HEAD~5
+----------------------
+
+And move the first patch to the end of the list.
+
+You might want to preserve merges, if you have a history like this:
+
+------------------
+           X
+            \
+         A---M---B
+        /
+---o---O---P---Q
+------------------
+
+Suppose you want to rebase the side branch starting at "A" to "Q". Make
+sure that the current HEAD is "B", and call
+
+-----------------------------
+$ git rebase -i -p --onto Q O
+-----------------------------
+
+
+SPLITTING COMMITS
+-----------------
+
+In interactive mode, you can mark commits with the action "edit".  However,
+this does not necessarily mean that 'git rebase' expects the result of this
+edit to be exactly one commit.  Indeed, you can undo the commit, or you can
+add other commits.  This can be used to split a commit into two:
+
+- Start an interactive rebase with 'git rebase -i <commit>^', where
+  <commit> is the commit you want to split.  In fact, any commit range
+  will do, as long as it contains that commit.
+
+- Mark the commit you want to split with the action "edit".
+
+- When it comes to editing that commit, execute 'git reset HEAD^'.  The
+  effect is that the HEAD is rewound by one, and the index follows suit.
+  However, the working tree stays the same.
+
+- Now add the changes to the index that you want to have in the first
+  commit.  You can use gitlink:git-add[1] (possibly interactively) and/or
+  gitlink:git-gui[1] to do that.
+
+- Commit the now-current index with whatever commit message is appropriate
+  now.
+
+- Repeat the last two steps until your working tree is clean.
+
+- Continue the rebase with 'git rebase --continue'.
+
+If you are not absolutely sure that the intermediate revisions are
+consistent (they compile, pass the testsuite, etc.) you should use
+gitlink:git-stash[1] to stash away the not-yet-committed changes
+after each commit, test, and amend the commit if fixes are necessary.
+
+
+Authors
 ------
-Written by Junio C Hamano <junkio@cox.net>
+Written by Junio C Hamano <junkio@cox.net> and
+Johannes E. Schindelin <johannes.schindelin@gmx.de>
 
 Documentation
 --------------
@@ -231,4 +379,3 @@ Documentation by Junio C Hamano and the git-list <git@vger.kernel.org>.
 GIT
 ---
 Part of the gitlink:git[7] suite
-