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@xxxxxxxxxxxxxxx> --- Documentation/git-rebase.txt | 103 +++++++++++++++++++++++++++++++++++++++-- 1 files changed, 98 insertions(+), 5 deletions(-) diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt index 59c1b02..ba5255d 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,100 @@ 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 +------------------------------- + +This section briefly explains the problems that arise from rebasing or +rewriting published branches, and shows how to recover. As you will +see, the process is rather tedious, so we emphasize again: 'Avoid +rewriting published history.' This goes for `rebase`, `commit +--amend`, `reset HEAD^` and `filter-branch` alike. + +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 master + \ + o---o---o---o---o subsystem + \ + *---*---* topic +------------ + +If 'subsystem' is rebased against master, the following happens: + +------------ + o---o---o---o---o master + | \ + | o'--o'--o'--o'--o' subsystem + \ + o---o---o---o---o---*---*---* topic +------------ + +Note that while we have marked your own commits with a '*', there is +nothing that distinguishes them from the commits that previously were +on 'subsystem'. Luckily, 'git-rebase' knows to skip commits that are +textually the same as commits in the 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 master + \ + o'--o'--o'--o'--o' subsystem + \ + *'--*'--*' topic +------------ + +This becomes a ripple effect to anyone downstream of the first rebase: +anyone downstream from 'topic' now needs to rebase too, and so on. + +Things get more complicated if your upstream used `git rebase +--interactive` (or `commit --amend` or `reset --hard HEAD^`). Label +the example history as follows: + +------------ + o---o---o---o---o master + \ + A---B---C---D---E subsystem + \ + X---Y---Z topic +------------ + +Now suppose the 'subsystem' maintainer decides to clean up his history +with an interactive rebase. He edits commits A and D (marked with a +`*`), decides to remove D entirely and moves B to the front. This +results in + +------------ + o---o---o---o---o master + | \ + | A*--C*--E'--B' subsystem + \ + A---B---C---D---E---X---Y---Z topic +------------ + +'git-rebase' can still tell that E'=E and B'=B, so a plain `git rebase +subsystem` would not duplicate those commits. However, it would +**resurrect** D (which may succeed silently!) and try to apply the +original versions of A and C (probably resulting in conflicts). + +To fix this, you have to manually transplant your own part of the +history to the new branch head. Looking at `git log`, you should be +able to determine that three commits on 'topic' are yours. Again +assuming you are already on 'topic', you can do +------------ + git rebase --onto subsystem HEAD~3 +------------ +to put things right. Of course, this again ripples onwards: +'everyone' downstream from 'subsystem' will have to 'manually' rebase +all their work! + + Authors ------ Written by Junio C Hamano <gitster@xxxxxxxxx> and -- 1.6.0.1.470.g200b -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html