OSDN Git Service

Add Git official document to help
[tortoisegit/TortoiseGitJp.git] / doc / source / en / TortoiseGit / git_doc / git-rebase.html.xml
diff --git a/doc/source/en/TortoiseGit/git_doc/git-rebase.html.xml b/doc/source/en/TortoiseGit/git_doc/git-rebase.html.xml
new file mode 100644 (file)
index 0000000..43b9c1b
--- /dev/null
@@ -0,0 +1,709 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">\r
+\r
+<article lang="en" id="git-rebase(1)">\r
+<articleinfo>\r
+    <title>git-rebase(1)</title>\r
+        <indexterm>\r
+                <primary>git-rebase(1)</primary>\r
+        </indexterm>\r
+</articleinfo>\r
+<simplesect id="_name">\r
+<title>NAME</title>\r
+<simpara>git-rebase - Forward-port local commits to the updated upstream head</simpara>\r
+</simplesect>\r
+<simplesect id="_synopsis">\r
+<title>SYNOPSIS</title>\r
+<blockquote>\r
+<literallayout><emphasis>git rebase</emphasis> [-i | --interactive] [options] [--onto &lt;newbase&gt;]\r
+        &lt;upstream&gt; [&lt;branch&gt;]\r
+<emphasis>git rebase</emphasis> [-i | --interactive] [options] --onto &lt;newbase&gt;\r
+        --root [&lt;branch&gt;]</literallayout>\r
+</blockquote>\r
+<simpara><emphasis>git rebase</emphasis> --continue | --skip | --abort</simpara>\r
+</simplesect>\r
+<simplesect id="_description">\r
+<title>DESCRIPTION</title>\r
+<simpara>If &lt;branch&gt; is specified, <emphasis>git-rebase</emphasis> will perform an automatic\r
+<literal>git checkout &lt;branch&gt;</literal> before doing anything else.  Otherwise\r
+it remains on the current branch.</simpara>\r
+<simpara>All changes made by commits in the current branch but that are not\r
+in &lt;upstream&gt; are saved to a temporary area.  This is the same set\r
+of commits that would be shown by <literal>git log &lt;upstream&gt;..HEAD</literal> (or\r
+<literal>git log HEAD</literal>, if --root is specified).</simpara>\r
+<simpara>The current branch is reset to &lt;upstream&gt;, or &lt;newbase&gt; if the\r
+--onto option was supplied.  This has the exact same effect as\r
+<literal>git reset --hard &lt;upstream&gt;</literal> (or &lt;newbase&gt;).  ORIG_HEAD is set\r
+to point at the tip of the branch before the reset.</simpara>\r
+<simpara>The commits that were previously saved into the temporary area are\r
+then reapplied to the current branch, one by one, in order. Note that\r
+any commits in HEAD which introduce the same textual changes as a commit\r
+in HEAD..&lt;upstream&gt; are omitted (i.e., a patch already accepted upstream\r
+with a different commit message or timestamp will be skipped).</simpara>\r
+<simpara>It is possible that a merge failure will prevent this process from being\r
+completely automatic.  You will have to resolve any such merge failure\r
+and run <literal>git rebase --continue</literal>.  Another option is to bypass the commit\r
+that caused the merge failure with <literal>git rebase --skip</literal>.  To restore the\r
+original &lt;branch&gt; and remove the .git/rebase-apply working files, use the\r
+command <literal>git rebase --abort</literal> instead.</simpara>\r
+<simpara>Assume the following history exists and the current branch is "topic":</simpara>\r
+<literallayout>          A---B---C topic\r
+         /\r
+    D---E---F---G master</literallayout>\r
+<simpara>From this point, the result of either of the following commands:</simpara>\r
+<literallayout class="monospaced">git rebase master\r
+git rebase master topic</literallayout>\r
+<simpara>would be:</simpara>\r
+<literallayout>                  A'--B'--C' topic\r
+                 /\r
+    D---E---F---G master</literallayout>\r
+<simpara>The latter form is just a short-hand of <literal>git checkout topic</literal>\r
+followed by <literal>git rebase master</literal>.</simpara>\r
+<simpara>If the upstream branch already contains a change you have made (e.g.,\r
+because you mailed a patch which was applied upstream), then that commit\r
+will be skipped. For example, running &#8216;git rebase master` on the\r
+following history (in which A&#8217; and A introduce the same set of changes,\r
+but have different committer information):</simpara>\r
+<literallayout>          A---B---C topic\r
+         /\r
+    D---E---A'---F master</literallayout>\r
+<simpara>will result in:</simpara>\r
+<literallayout>                   B'---C' topic\r
+                  /\r
+    D---E---A'---F master</literallayout>\r
+<simpara>Here is how you would transplant a topic branch based on one\r
+branch to another, to pretend that you forked the topic branch\r
+from the latter branch, using <literal>rebase --onto</literal>.</simpara>\r
+<simpara>First let&#8217;s assume your <emphasis>topic</emphasis> is based on branch <emphasis>next</emphasis>.\r
+For example, a feature developed in <emphasis>topic</emphasis> depends on some\r
+functionality which is found in <emphasis>next</emphasis>.</simpara>\r
+<literallayout>    o---o---o---o---o  master\r
+         \\r
+          o---o---o---o---o  next\r
+                           \\r
+                            o---o---o  topic</literallayout>\r
+<simpara>We want to make <emphasis>topic</emphasis> forked from branch <emphasis>master</emphasis>; for example,\r
+because the functionality on which <emphasis>topic</emphasis> depends was merged into the\r
+more stable <emphasis>master</emphasis> branch. We want our tree to look like this:</simpara>\r
+<literallayout>    o---o---o---o---o  master\r
+        |            \\r
+        |             o'--o'--o'  topic\r
+         \\r
+          o---o---o---o---o  next</literallayout>\r
+<simpara>We can get this using the following command:</simpara>\r
+<literallayout class="monospaced">git rebase --onto master next topic</literallayout>\r
+<simpara>Another example of --onto option is to rebase part of a\r
+branch.  If we have the following situation:</simpara>\r
+<literallayout>                            H---I---J topicB\r
+                           /\r
+                  E---F---G  topicA\r
+                 /\r
+    A---B---C---D  master</literallayout>\r
+<simpara>then the command</simpara>\r
+<literallayout class="monospaced">git rebase --onto master topicA topicB</literallayout>\r
+<simpara>would result in:</simpara>\r
+<literallayout>                 H'--I'--J'  topicB\r
+                /\r
+                | E---F---G  topicA\r
+                |/\r
+    A---B---C---D  master</literallayout>\r
+<simpara>This is useful when topicB does not depend on topicA.</simpara>\r
+<simpara>A range of commits could also be removed with rebase.  If we have\r
+the following situation:</simpara>\r
+<literallayout>    E---F---G---H---I---J  topicA</literallayout>\r
+<simpara>then the command</simpara>\r
+<literallayout class="monospaced">git rebase --onto topicA~5 topicA~3 topicA</literallayout>\r
+<simpara>would result in the removal of commits F and G:</simpara>\r
+<literallayout>    E---H'---I'---J'  topicA</literallayout>\r
+<simpara>This is useful if F and G were flawed in some way, or should not be\r
+part of topicA.  Note that the argument to --onto and the &lt;upstream&gt;\r
+parameter can be any valid commit-ish.</simpara>\r
+<simpara>In case of conflict, <emphasis>git-rebase</emphasis> will stop at the first problematic commit\r
+and leave conflict markers in the tree.  You can use <emphasis>git-diff</emphasis> to locate\r
+the markers (&lt;&lt;&lt;&lt;&lt;&lt;) and make edits to resolve the conflict.  For each\r
+file you edit, you need to tell git that the conflict has been resolved,\r
+typically this would be done with</simpara>\r
+<literallayout class="monospaced">git add &lt;filename&gt;</literallayout>\r
+<simpara>After resolving the conflict manually and updating the index with the\r
+desired resolution, you can continue the rebasing process with</simpara>\r
+<literallayout class="monospaced">git rebase --continue</literallayout>\r
+<simpara>Alternatively, you can undo the <emphasis>git-rebase</emphasis> with</simpara>\r
+<literallayout class="monospaced">git rebase --abort</literallayout>\r
+</simplesect>\r
+<simplesect id="_options">\r
+<title>OPTIONS</title>\r
+<variablelist>\r
+<varlistentry>\r
+<term>\r
+&lt;newbase&gt;\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        Starting point at which to create the new commits. If the\r
+        --onto option is not specified, the starting point is\r
+        &lt;upstream&gt;.  May be any valid commit, and not just an\r
+        existing branch name.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+&lt;upstream&gt;\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        Upstream branch to compare against.  May be any valid commit,\r
+        not just an existing branch name.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+&lt;branch&gt;\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        Working branch; defaults to HEAD.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+--continue\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        Restart the rebasing process after having resolved a merge conflict.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+--abort\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        Restore the original branch and abort the rebase operation.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+--skip\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        Restart the rebasing process by skipping the current patch.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+-m\r
+</term>\r
+<term>\r
+--merge\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        Use merging strategies to rebase.  When the recursive (default) merge\r
+        strategy is used, this allows rebase to be aware of renames on the\r
+        upstream side.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+-s &lt;strategy&gt;\r
+</term>\r
+<term>\r
+--strategy=&lt;strategy&gt;\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        Use the given merge strategy; can be supplied more than\r
+        once to specify them in the order they should be tried.\r
+        If there is no <literal>-s</literal> option, a built-in list of strategies\r
+        is used instead (<emphasis>git-merge-recursive</emphasis> when merging a single\r
+        head, <emphasis>git-merge-octopus</emphasis> otherwise).  This implies --merge.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+-v\r
+</term>\r
+<term>\r
+--verbose\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        Display a diffstat of what changed upstream since the last rebase.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+--no-verify\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        This option bypasses the pre-rebase hook.  See also <xref linkend="githooks(5)"/>.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+-C&lt;n&gt;\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        Ensure at least &lt;n&gt; lines of surrounding context match before\r
+        and after each change.  When fewer lines of surrounding\r
+        context exist they all must match.  By default no context is\r
+        ever ignored.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+--whitespace=&lt;nowarn|warn|error|error-all|strip&gt;\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        This flag is passed to the <emphasis>git-apply</emphasis> program\r
+        (see <xref linkend="git-apply(1)"/>) that applies the patch.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+-i\r
+</term>\r
+<term>\r
+--interactive\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        Make a list of the commits which are about to be rebased.  Let the\r
+        user edit that list before rebasing.  This mode can also be used to\r
+        split commits (see SPLITTING COMMITS below).\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+-p\r
+</term>\r
+<term>\r
+--preserve-merges\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        Instead of ignoring merges, try to recreate them.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+--root\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        Rebase all commits reachable from &lt;branch&gt;, instead of\r
+        limiting them with an &lt;upstream&gt;.  This allows you to rebase\r
+        the root commit(s) on a branch.  Must be used with --onto, and\r
+        will skip changes already contained in &lt;newbase&gt; (instead of\r
+        &lt;upstream&gt;).  When used together with --preserve-merges, <emphasis>all</emphasis>\r
+        root commits will be rewritten to have &lt;newbase&gt; as parent\r
+        instead.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+</variablelist>\r
+</simplesect>\r
+<simplesect id="_merge_strategies">\r
+<title>MERGE STRATEGIES</title>\r
+<variablelist>\r
+<varlistentry>\r
+<term>\r
+resolve\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        This can only resolve two heads (i.e. the current branch\r
+        and another branch you pulled from) using 3-way merge\r
+        algorithm.  It tries to carefully detect criss-cross\r
+        merge ambiguities and is considered generally safe and\r
+        fast.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+recursive\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        This can only resolve two heads using 3-way merge\r
+        algorithm.  When there are more than one common\r
+        ancestors that can be used for 3-way merge, it creates a\r
+        merged tree of the common ancestors and uses that as\r
+        the reference tree for the 3-way merge.  This has been\r
+        reported to result in fewer merge conflicts without\r
+        causing mis-merges by tests done on actual merge commits\r
+        taken from Linux 2.6 kernel development history.\r
+        Additionally this can detect and handle merges involving\r
+        renames.  This is the default merge strategy when\r
+        pulling or merging one branch.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+octopus\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        This resolves more than two-head case, but refuses to do\r
+        complex merge that needs manual resolution.  It is\r
+        primarily meant to be used for bundling topic branch\r
+        heads together.  This is the default merge strategy when\r
+        pulling or merging more than one branches.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+ours\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        This resolves any number of heads, but the result of the\r
+        merge is always the current branch head.  It is meant to\r
+        be used to supersede old development history of side\r
+        branches.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+subtree\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        This is a modified recursive strategy. When merging trees A and\r
+        B, if B corresponds to a subtree of A, B is first adjusted to\r
+        match the tree structure of A, instead of reading the trees at\r
+        the same level. This adjustment is also done to the common\r
+        ancestor tree.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+</variablelist>\r
+</simplesect>\r
+<simplesect id="_notes">\r
+<title>NOTES</title>\r
+<simpara>You should understand the implications of using <emphasis>git-rebase</emphasis> on a\r
+repository that you share.  See also RECOVERING FROM UPSTREAM REBASE\r
+below.</simpara>\r
+<simpara>When the git-rebase command is run, it will first execute a "pre-rebase"\r
+hook if one exists.  You can use this hook to do sanity checks and\r
+reject the rebase if it isn&#8217;t appropriate.  Please see the template\r
+pre-rebase hook script for an example.</simpara>\r
+<simpara>Upon completion, &lt;branch&gt; will be the current branch.</simpara>\r
+</simplesect>\r
+<simplesect id="_interactive_mode">\r
+<title>INTERACTIVE MODE</title>\r
+<simpara>Rebasing interactively means that you have a chance to edit the commits\r
+which are rebased.  You can reorder the commits, and you can\r
+remove them (weeding out bad or otherwise unwanted patches).</simpara>\r
+<simpara>The interactive mode is meant for this type of workflow:</simpara>\r
+<orderedlist numeration="arabic">\r
+<listitem>\r
+<simpara>\r
+have a wonderful idea\r
+</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+hack on the code\r
+</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+prepare a series for submission\r
+</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+submit\r
+</simpara>\r
+</listitem>\r
+</orderedlist>\r
+<simpara>where point 2. consists of several instances of</simpara>\r
+<orderedlist numeration="loweralpha">\r
+<listitem>\r
+<simpara>\r
+regular use\r
+</simpara>\r
+<orderedlist numeration="arabic">\r
+<listitem>\r
+<simpara>\r
+finish something worthy of a commit\r
+</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+commit\r
+</simpara>\r
+</listitem>\r
+</orderedlist>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+independent fixup\r
+</simpara>\r
+<orderedlist numeration="arabic">\r
+<listitem>\r
+<simpara>\r
+realize that something does not work\r
+</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+fix that\r
+</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+commit it\r
+</simpara>\r
+</listitem>\r
+</orderedlist>\r
+</listitem>\r
+</orderedlist>\r
+<simpara>Sometimes the thing fixed in b.2. cannot be amended to the not-quite\r
+perfect commit it fixes, because that commit is buried deeply in a\r
+patch series.  That is exactly what interactive rebase is for: use it\r
+after plenty of "a"s and "b"s, by rearranging and editing\r
+commits, and squashing multiple commits into one.</simpara>\r
+<simpara>Start it with the last commit you want to retain as-is:</simpara>\r
+<literallayout class="monospaced">git rebase -i &lt;after-this-commit&gt;</literallayout>\r
+<simpara>An editor will be fired up with all the commits in your current branch\r
+(ignoring merge commits), which come after the given commit.  You can\r
+reorder the commits in this list to your heart&#8217;s content, and you can\r
+remove them.  The list looks more or less like this:</simpara>\r
+<literallayout>pick deadbee The oneline of this commit\r
+pick fa1afe1 The oneline of the next commit\r
+...</literallayout>\r
+<simpara>The oneline descriptions are purely for your pleasure; <emphasis>git-rebase</emphasis> will\r
+not look at them but at the commit names ("deadbee" and "fa1afe1" in this\r
+example), so do not delete or edit the names.</simpara>\r
+<simpara>By replacing the command "pick" with the command "edit", you can tell\r
+<emphasis>git-rebase</emphasis> to stop after applying that commit, so that you can edit\r
+the files and/or the commit message, amend the commit, and continue\r
+rebasing.</simpara>\r
+<simpara>If you want to fold two or more commits into one, replace the command\r
+"pick" with "squash" for the second and subsequent commit.  If the\r
+commits had different authors, it will attribute the squashed commit to\r
+the author of the first commit.</simpara>\r
+<simpara>In both cases, or when a "pick" does not succeed (because of merge\r
+errors), the loop will stop to let you fix things, and you can continue\r
+the loop with <literal>git rebase --continue</literal>.</simpara>\r
+<simpara>For example, if you want to reorder the last 5 commits, such that what\r
+was HEAD~4 becomes the new HEAD. To achieve that, you would call\r
+<emphasis>git-rebase</emphasis> like this:</simpara>\r
+<literallayout>$ git rebase -i HEAD~5</literallayout>\r
+<simpara>And move the first patch to the end of the list.</simpara>\r
+<simpara>You might want to preserve merges, if you have a history like this:</simpara>\r
+<literallayout>           X\r
+            \\r
+         A---M---B\r
+        /\r
+---o---O---P---Q</literallayout>\r
+<simpara>Suppose you want to rebase the side branch starting at "A" to "Q". Make\r
+sure that the current HEAD is "B", and call</simpara>\r
+<literallayout>$ git rebase -i -p --onto Q O</literallayout>\r
+</simplesect>\r
+<simplesect id="_splitting_commits">\r
+<title>SPLITTING COMMITS</title>\r
+<simpara>In interactive mode, you can mark commits with the action "edit".  However,\r
+this does not necessarily mean that <emphasis>git-rebase</emphasis> expects the result of this\r
+edit to be exactly one commit.  Indeed, you can undo the commit, or you can\r
+add other commits.  This can be used to split a commit into two:</simpara>\r
+<itemizedlist>\r
+<listitem>\r
+<simpara>\r
+Start an interactive rebase with <literal>git rebase -i &lt;commit&gt;^</literal>, where\r
+  &lt;commit&gt; is the commit you want to split.  In fact, any commit range\r
+  will do, as long as it contains that commit.\r
+</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+Mark the commit you want to split with the action "edit".\r
+</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+When it comes to editing that commit, execute <literal>git reset HEAD^</literal>.  The\r
+  effect is that the HEAD is rewound by one, and the index follows suit.\r
+  However, the working tree stays the same.\r
+</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+Now add the changes to the index that you want to have in the first\r
+  commit.  You can use <literal>git add</literal> (possibly interactively) or\r
+  <emphasis>git-gui</emphasis> (or both) to do that.\r
+</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+Commit the now-current index with whatever commit message is appropriate\r
+  now.\r
+</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+Repeat the last two steps until your working tree is clean.\r
+</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+Continue the rebase with <literal>git rebase --continue</literal>.\r
+</simpara>\r
+</listitem>\r
+</itemizedlist>\r
+<simpara>If you are not absolutely sure that the intermediate revisions are\r
+consistent (they compile, pass the testsuite, etc.) you should use\r
+<emphasis>git-stash</emphasis> to stash away the not-yet-committed changes\r
+after each commit, test, and amend the commit if fixes are necessary.</simpara>\r
+</simplesect>\r
+<simplesect id="_recovering_from_upstream_rebase">\r
+<title>RECOVERING FROM UPSTREAM REBASE</title>\r
+<simpara>Rebasing (or any other form of rewriting) a branch that others have\r
+based work on is a bad idea: anyone downstream of it is forced to\r
+manually fix their history.  This section explains how to do the fix\r
+from the downstream&#8217;s point of view.  The real fix, however, would be\r
+to avoid rebasing the upstream in the first place.</simpara>\r
+<simpara>To illustrate, suppose you are in a situation where someone develops a\r
+<emphasis>subsystem</emphasis> branch, and you are working on a <emphasis>topic</emphasis> that is dependent\r
+on this <emphasis>subsystem</emphasis>.  You might end up with a history like the\r
+following:</simpara>\r
+<literallayout>    o---o---o---o---o---o---o---o---o  master\r
+         \\r
+          o---o---o---o---o  subsystem\r
+                           \\r
+                            *---*---*  topic</literallayout>\r
+<simpara>If <emphasis>subsystem</emphasis> is rebased against <emphasis>master</emphasis>, the following happens:</simpara>\r
+<literallayout>    o---o---o---o---o---o---o---o  master\r
+         \                       \\r
+          o---o---o---o---o       o'--o'--o'--o'--o'  subsystem\r
+                           \\r
+                            *---*---*  topic</literallayout>\r
+<simpara>If you now continue development as usual, and eventually merge <emphasis>topic</emphasis>\r
+to <emphasis>subsystem</emphasis>, the commits from <emphasis>subsystem</emphasis> will remain duplicated forever:</simpara>\r
+<literallayout>    o---o---o---o---o---o---o---o  master\r
+         \                       \\r
+          o---o---o---o---o       o'--o'--o'--o'--o'--M  subsystem\r
+                           \                         /\r
+                            *---*---*-..........-*--*  topic</literallayout>\r
+<simpara>Such duplicates are generally frowned upon because they clutter up\r
+history, making it harder to follow.  To clean things up, you need to\r
+transplant the commits on <emphasis>topic</emphasis> to the new <emphasis>subsystem</emphasis> tip, i.e.,\r
+rebase <emphasis>topic</emphasis>.  This becomes a ripple effect: anyone downstream from\r
+<emphasis>topic</emphasis> is forced to rebase too, and so on!</simpara>\r
+<simpara>There are two kinds of fixes, discussed in the following subsections:</simpara>\r
+<variablelist>\r
+<varlistentry>\r
+<term>\r
+Easy case: The changes are literally the same.\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        This happens if the <emphasis>subsystem</emphasis> rebase was a simple rebase and\r
+        had no conflicts.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+<varlistentry>\r
+<term>\r
+Hard case: The changes are not the same.\r
+</term>\r
+<listitem>\r
+<simpara>\r
+        This happens if the <emphasis>subsystem</emphasis> rebase had conflicts, or used\r
+        <literal>--interactive</literal> to omit, edit, or squash commits; or if the\r
+        upstream used one of <literal>commit --amend</literal>, <literal>reset</literal>, or\r
+        <literal>filter-branch</literal>.\r
+</simpara>\r
+</listitem>\r
+</varlistentry>\r
+</variablelist>\r
+<simplesect id="_the_easy_case">\r
+<title>The easy case</title>\r
+<simpara>Only works if the changes (patch IDs based on the diff contents) on\r
+<emphasis>subsystem</emphasis> are literally the same before and after the rebase\r
+<emphasis>subsystem</emphasis> did.</simpara>\r
+<simpara>In that case, the fix is easy because <emphasis>git-rebase</emphasis> knows to skip\r
+changes that are already present in the new upstream.  So if you say\r
+(assuming you&#8217;re on <emphasis>topic</emphasis>)</simpara>\r
+<literallayout>    $ git rebase subsystem</literallayout>\r
+<simpara>you will end up with the fixed history</simpara>\r
+<literallayout>    o---o---o---o---o---o---o---o  master\r
+                                 \\r
+                                  o'--o'--o'--o'--o'  subsystem\r
+                                                   \\r
+                                                    *---*---*  topic</literallayout>\r
+</simplesect>\r
+<simplesect id="_the_hard_case">\r
+<title>The hard case</title>\r
+<simpara>Things get more complicated if the <emphasis>subsystem</emphasis> changes do not exactly\r
+correspond to the ones before the rebase.</simpara>\r
+<note><simpara>While an "easy case recovery" sometimes appears to be successful\r
+      even in the hard case, it may have unintended consequences.  For\r
+      example, a commit that was removed via <literal>git rebase\r
+      --interactive</literal> will be <emphasis role="strong">resurrected</emphasis>!</simpara></note>\r
+<simpara>The idea is to manually tell <emphasis>git-rebase</emphasis> "where the old <emphasis>subsystem</emphasis>\r
+ended and your <emphasis>topic</emphasis> began", that is, what the old merge-base\r
+between them was.  You will have to find a way to name the last commit\r
+of the old <emphasis>subsystem</emphasis>, for example:</simpara>\r
+<itemizedlist>\r
+<listitem>\r
+<simpara>\r
+With the <emphasis>subsystem</emphasis> reflog: after <emphasis>git-fetch</emphasis>, the old tip of\r
+  <emphasis>subsystem</emphasis> is at <literal>subsystem@{1}</literal>.  Subsequent fetches will\r
+  increase the number.  (See <xref linkend="git-reflog(1)"/>.)\r
+</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+Relative to the tip of <emphasis>topic</emphasis>: knowing that your <emphasis>topic</emphasis> has three\r
+  commits, the old tip of <emphasis>subsystem</emphasis> must be <literal>topic~3</literal>.\r
+</simpara>\r
+</listitem>\r
+</itemizedlist>\r
+<simpara>You can then transplant the old <literal>subsystem..topic</literal> to the new tip by\r
+saying (for the reflog case, and assuming you are on <emphasis>topic</emphasis> already):</simpara>\r
+<literallayout>    $ git rebase --onto subsystem subsystem@{1}</literallayout>\r
+<simpara>The ripple effect of a "hard case" recovery is especially bad:\r
+<emphasis>everyone</emphasis> downstream from <emphasis>topic</emphasis> will now have to perform a "hard\r
+case" recovery too!</simpara>\r
+</simplesect>\r
+</simplesect>\r
+<simplesect id="_authors">\r
+<title>Authors</title>\r
+<simpara>Written by Junio C Hamano &lt;<ulink url="mailto:gitster@pobox.com">gitster@pobox.com</ulink>&gt; and\r
+Johannes E. Schindelin &lt;<ulink url="mailto:johannes.schindelin@gmx.de">johannes.schindelin@gmx.de</ulink>&gt;</simpara>\r
+</simplesect>\r
+<simplesect id="_documentation">\r
+<title>Documentation</title>\r
+<simpara>Documentation by Junio C Hamano and the git-list &lt;<ulink url="mailto:git@vger.kernel.org">git@vger.kernel.org</ulink>&gt;.</simpara>\r
+</simplesect>\r
+<simplesect id="_git">\r
+<title>GIT</title>\r
+<simpara>Part of the <xref linkend="git(1)"/> suite</simpara>\r
+</simplesect>\r
+</article>\r