You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: en/book/03-git-branching/chapter3.asc
+36-5Lines changed: 36 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -418,14 +418,15 @@ image::images/undomerge-reset.png[History after `git reset --merge`.]
418
418
We covered `reset` back in <<_reset>>, so it shouldn't be too hard to figure out what's going on here.
419
419
Here's a quick refresher: `reset --hard` usually goes through three steps:
420
420
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`)
422
422
2. Make the index look like `HEAD`.
423
423
3. Make the working directory look like the index.
424
424
425
425
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.
426
426
427
427
The downside of this approach is that it's rewriting history, which can be prolematic with a shared repository.
428
428
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.
429
430
430
431
===== Reverse the commit
431
432
@@ -434,18 +435,48 @@ Git calls this operation a ``revert'', and in this particular scenario, you'd in
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`).
443
445
444
446
The history with the revert commit looks like this:
445
447
446
448
.History after `git revert -m 1`
449
+
image::images/undomerge-revert.png[History after `git revert -m 1`.]
447
450
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:
0 commit comments