@@ -142,6 +142,8 @@ different resolution strategies:
142142 revert of a merge was rebuilt from scratch (i.e. rebasing and fixing,
143143 as you seem to have interpreted), then re-merging the result without
144144 doing anything else fancy would be the right thing to do.
145+ (See the ADDENDUM below for how to rebuild a branch from scratch
146+ without changing its original branching-off point.)
145147
146148However, there are things to keep in mind when reverting a merge (and
147149reverting such a revert).
@@ -177,3 +179,91 @@ the answer is: "oops, I really shouldn't have merged it, because it wasn't
177179ready yet, and I really need to undo _all_ of the merge"). So then you
178180really should revert the merge, but when you want to re-do the merge, you
179181now need to do it by reverting the revert.
182+
183+ ADDENDUM
184+
185+ Sometimes you have to rewrite one of a topic branch's commits *and* you can't
186+ change the topic's branching-off point. Consider the following situation:
187+
188+ P---o---o---M---x---x---W---x
189+ \ /
190+ A---B---C
191+
192+ where commit W reverted commit M because it turned out that commit B was wrong
193+ and needs to be rewritten, but you need the rewritten topic to still branch
194+ from commit P (perhaps P is a branching-off point for yet another branch, and
195+ you want be able to merge the topic into both branches).
196+
197+ The natural thing to do in this case is to checkout the A-B-C branch and use
198+ "rebase -i P" to change commit B. However this does not rewrite commit A,
199+ because "rebase -i" by default fast-forwards over any initial commits selected
200+ with the "pick" command. So you end up with this:
201+
202+ P---o---o---M---x---x---W---x
203+ \ /
204+ A---B---C <-- old branch
205+ \
206+ B'---C' <-- naively rewritten branch
207+
208+ To merge A-B'-C' into the mainline branch you would still have to first revert
209+ commit W in order to pick up the changes in A, but then it's likely that the
210+ changes in B' will conflict with the original B changes re-introduced by the
211+ reversion of W.
212+
213+ However, you can avoid these problems if you recreate the entire branch,
214+ including commit A:
215+
216+ A'---B'---C' <-- completely rewritten branch
217+ /
218+ P---o---o---M---x---x---W---x
219+ \ /
220+ A---B---C
221+
222+ You can merge A'-B'-C' into the mainline branch without worrying about first
223+ reverting W. Mainline's history would look like this:
224+
225+ A'---B'---C'------------------
226+ / \
227+ P---o---o---M---x---x---W---x---M2
228+ \ /
229+ A---B---C
230+
231+ But if you don't actually need to change commit A, then you need some way to
232+ recreate it as a new commit with the same changes in it. The rebase commmand's
233+ --no-ff option provides a way to do this:
234+
235+ $ git rebase [-i] --no-ff P
236+
237+ The --no-ff option creates a new branch A'-B'-C' with all-new commits (all the
238+ SHA IDs will be different) even if in the interactive case you only actually
239+ modify commit B. You can then merge this new branch directly into the mainline
240+ branch and be sure you'll get all of the branch's changes.
241+
242+ You can also use --no-ff in cases where you just add extra commits to the topic
243+ to fix it up. Let's revisit the situation discussed at the start of this howto:
244+
245+ P---o---o---M---x---x---W---x
246+ \ /
247+ A---B---C----------------D---E <-- fixed-up topic branch
248+
249+ At this point, you can use --no-ff to recreate the topic branch:
250+
251+ $ git checkout E
252+ $ git rebase --no-ff P
253+
254+ yielding
255+
256+ A'---B'---C'------------D'---E' <-- recreated topic branch
257+ /
258+ P---o---o---M---x---x---W---x
259+ \ /
260+ A---B---C----------------D---E
261+
262+ You can merge the recreated branch into the mainline without reverting commit W,
263+ and mainline's history will look like this:
264+
265+ A'---B'---C'------------D'---E'
266+ / \
267+ P---o---o---M---x---x---W---x---M2
268+ \ /
269+ A---B---C
0 commit comments