Skip to content

Commit ad02690

Browse files
committed
First draft of undoing merges, figures
1 parent e010448 commit ad02690

File tree

7 files changed

+14303
-5167
lines changed

7 files changed

+14303
-5167
lines changed

en/book/03-git-branching/chapter3.asc

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -418,14 +418,15 @@ image::images/undomerge-reset.png[History after `git reset --merge`.]
418418
We covered `reset` back in <<_reset>>, so it shouldn't be too hard to figure out what's going on here.
419419
Here's a quick refresher: `reset --hard` usually goes through three steps:
420420

421-
1. Move the ref that `HEAD` points to. In this case, we want to move `master` to where it was before the merge commit (`C4`)
421+
1. Move the ref that `HEAD` points to. In this case, we want to move `master` to where it was before the merge commit (`C6`)
422422
2. Make the index look like `HEAD`.
423423
3. Make the working directory look like the index.
424424

425425
In the case of `--merge`, Git is extra careful with steps 2 and 3 to preserve any changes you've made in the working directory or the index, but otherwise works as though this were a `--hard` reset.
426426

427427
The downside of this approach is that it's rewriting history, which can be prolematic with a shared repository.
428428
Check out <<_rebase_peril>> for more on what can happen, but if other people have the commits you're rewriting, you should probably avoid `reset`.
429+
This approach also won't work if any other commits have been created since the merge; moving the refs would effectively lose those changes.
429430

430431
===== Reverse the commit
431432

@@ -434,18 +435,48 @@ Git calls this operation a ``revert'', and in this particular scenario, you'd in
434435

435436
[source,shell]
436437
----
437-
$ git revert -m 1
438+
$ git revert -m 1 HEAD
439+
[master b1d8379] Revert "Merge branch 'topic-branch'"
438440
----
439441

440442
The `-m 1` flag tells Git which parent to keep.
441-
When you invoke a merge into `HEAD` (`git merge experiment`), the new commit has two parents: the first one is `HEAD` (`C4`), and the second is the tip of the branch being merged in (`C3`).
442-
In this case, we want to undo all the changes introduced by merging in parent #2 (`C3`), while keeping all the content from parent #1 (`C4`).
443+
When you invoke a merge into `HEAD` (`git merge topic-branch`), the new commit has two parents: the first one is `HEAD` (`C6`), and the second is the tip of the branch being merged in (`C4`).
444+
In this case, we want to undo all the changes introduced by merging in parent #2 (`C4`), while keeping all the content from parent #1 (`C6`).
443445

444446
The history with the revert commit looks like this:
445447

446448
.History after `git revert -m 1`
449+
image::images/undomerge-revert.png[History after `git revert -m 1`.]
447450

448-
Take a look at <<_undoing>> for more information on Git's various methods of undoing things.
451+
The new commit `^M` has exactly the same contents as `C6`, so starting from here it's as if the merge never happened, except that the now-unmerged commits are still in `HEAD`'s history.
452+
Git will get confused if you try to merge `topic-branch` into `master` again:
453+
454+
[source,shell]
455+
----
456+
$ git merge topic-branch
457+
Already up-to-date.
458+
----
459+
460+
There's nothing in `topic-branch` that isn't already reachable from `master`.
461+
What's worse, if you add work to `topic-branch` and merge again, Git will only bring in the changes _since_ the reverted merge:
462+
463+
.History with a bad merge
464+
image::images/undomerge-revert2.png[History with a bad merge.]
465+
466+
The best way around this is to un-revert the original merge, since now you want to bring in the changes that were reverted out, *then* create a new merge commit:
467+
468+
[source,shell]
469+
----
470+
$ git revert M
471+
[master 09f0126] Revert "Revert "Merge branch 'topic-branch'""
472+
$ git merge topic-branch
473+
----
474+
475+
.History after re-merging a reverted merge
476+
image::images/undomerge-revert3.png[History after re-merging a reverted merge.]
477+
478+
In this example, `M` and `^M` cancel out.
479+
`^^M` effectively merges in the changes from `C3` and `C4`, and `C8` merges in the changes from `C7`, so now `topic-branch` is fully merged.
449480

450481

451482
=== Branch Management

en/book/images/undomerge-reset.png

52 KB
Loading
54 KB
Loading
63.4 KB
Loading
68.6 KB
Loading

en/book/images/undomerge-start.png

36.6 KB
Loading

0 commit comments

Comments
 (0)