142
revert of a merge was rebuilt from scratch (i.e. rebasing and fixing,
143
as you seem to have interpreted), then re-merging the result without
144
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.)
147
148
However, there are things to keep in mind when reverting a merge (and
149
reverting such a revert).
179
ready yet, and I really need to undo _all_ of the merge"). So then you
180
really should revert the merge, but when you want to re-do the merge, you
181
now 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