git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Thomas Rast <trast@student.ethz.ch>
To: git@vger.kernel.org
Cc: Junio C Hamano <junio@pobox.com>
Subject: [PATCH 1/3] Documentation: new upstream rebase recovery section in git-rebase
Date: Sat, 13 Sep 2008 18:11:00 +0200	[thread overview]
Message-ID: <1221322263-25291-2-git-send-email-trast@student.ethz.ch> (raw)
In-Reply-To: <1221322263-25291-1-git-send-email-trast@student.ethz.ch>

Documents how to recover if the upstream that you pull from has
rebased the branches you depend your work on.  Hopefully this can also
serve as a warning to potential rebasers.

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
---

See the series leader for discussion.

 Documentation/git-rebase.txt |  129 ++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 124 insertions(+), 5 deletions(-)

diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt
index 59c1b02..a2f686c 100644
--- a/Documentation/git-rebase.txt
+++ b/Documentation/git-rebase.txt
@@ -257,11 +257,10 @@ 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
@@ -396,6 +395,126 @@ 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 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.
+
+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 pre-rebase ones.
+
+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
-- 
1.6.0.2.408.g3709

  reply	other threads:[~2008-09-13 16:12 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-09-02 20:18 [RFC PATCH] Documentation: new upstream rebase recovery section in git-rebase Thomas Rast
2008-09-02 21:39 ` Junio C Hamano
2008-09-03  5:38   ` Thomas Rast
2008-09-11 15:38     ` [PATCH 0/2.5] " Thomas Rast
2008-09-11 15:38       ` [PATCH 1/2] " Thomas Rast
2008-09-11 15:38         ` [PATCH 2/2] Documentation: Refer to git-rebase(1) to warn against rewriting Thomas Rast
2008-09-11 15:39           ` [RFC PATCH] Documentation: add manpage about workflows Thomas Rast
2008-09-11 16:37             ` Jakub Narebski
2008-09-12  7:26             ` [RFH] Asciidoc non-example blocks [was: Re: [RFC PATCH] Documentation: add manpage about workflows] Thomas Rast
2008-09-20  0:22             ` [RFC PATCH] Documentation: add manpage about workflows Santi Béjar
2008-09-21 20:26             ` Dmitry Potapov
2008-09-30 16:05               ` Thomas Rast
2008-09-30 16:07                 ` Thomas Rast
2008-10-01  9:54                 ` Santi Béjar
2008-10-09 11:42                   ` [RFC PATCH v2] " Thomas Rast
2008-10-09 11:42                     ` [Interdiff] " Thomas Rast
2008-10-09 12:50                     ` Junio C Hamano
2008-10-19 15:20                       ` [RFC PATCH v3] " Thomas Rast
2008-10-19 15:20                         ` [Interdiff] " Thomas Rast
2008-10-19 20:07                         ` Junio C Hamano
2008-09-12  1:15         ` [PATCH 1/2] Documentation: new upstream rebase recovery section in git-rebase Marcus Griep
2008-09-13  5:08         ` Junio C Hamano
2008-09-13 16:10           ` [PATCH 0/3] Documentation: rebase and workflows Thomas Rast
2008-09-13 16:11             ` Thomas Rast [this message]
2008-09-13 16:11               ` [PATCH 2/3] Documentation: Refer to git-rebase(1) to warn against rewriting Thomas Rast
2008-09-13 16:11                 ` [PATCH 3/3] Documentation: add manpage about workflows Thomas Rast
2008-09-13 16:11                   ` Interdiff: [3/3] " Thomas Rast
2008-09-08 22:55 ` [RFC PATCH] Documentation: new upstream rebase recovery section in git-rebase Junio C Hamano
2008-09-09  5:42   ` Thomas Rast

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1221322263-25291-2-git-send-email-trast@student.ethz.ch \
    --to=trast@student.ethz.ch \
    --cc=git@vger.kernel.org \
    --cc=junio@pobox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).