Skip to content

Commit e010448

Browse files
committed
Partial content for undo-merge section
1 parent 055eccd commit e010448

File tree

3 files changed

+54
-5
lines changed

3 files changed

+54
-5
lines changed

en/book/02-git-basics/chapter2.asc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -626,10 +626,12 @@ image::images/18333fig0202-tn.png[The gitk history visualizer.]
626626

627627
You can see the commit history in the top half of the window along with a nice ancestry graph. The diff viewer in the bottom half of the window shows you the changes introduced at any commit you click.
628628

629+
[[_undoing]]
629630
=== Undoing Things
630631

631632
At any stage, you may want to undo something. Here, we’ll review a few basic tools for undoing changes that you’ve made. Be careful, because you can’t always undo some of these undos. This is one of the few areas in Git where you may lose some work if you do it wrong.
632633

634+
[[_reset]]
633635
==== Reset Demystified
634636

635637
===== The Three Trees

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

Lines changed: 52 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -396,10 +396,57 @@ You can modify that message with details about how you resolved the merge if you
396396

397397
==== Undoing Merges
398398

399-
**TODO**
399+
Now that you know how to create a merge commit, you'll probably make some by mistake.
400+
One of the great things about working with Git is that it's okay to make mistakes, because it's possible (and in many cases easy) to fix them.
401+
402+
Merge commits are no different.
403+
Let's say you started work on a topic branch, accidentally merged it into `master`, and now your commit history looks like this:
404+
405+
.Accidental merge commit
406+
image::images/undomerge-start.png[Accidental merge commit.]
407+
408+
There are two ways to approach this problem, depending on what your desired outcome is.
409+
410+
===== Fix the refs
411+
412+
If the unwanted merge commit only exists on your local repository, the solution is to move the branches so that they point where you want them to.
413+
In most cases, if you follow the errant `git merge` with `git reset --merge ORIG_HEAD`, this will reset the branch pointers so they look like this:
414+
415+
.History after `git reset --merge`
416+
image::images/undomerge-reset.png[History after `git reset --merge`.]
417+
418+
We covered `reset` back in <<_reset>>, so it shouldn't be too hard to figure out what's going on here.
419+
Here's a quick refresher: `reset --hard` usually goes through three steps:
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`)
422+
2. Make the index look like `HEAD`.
423+
3. Make the working directory look like the index.
424+
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+
427+
The downside of this approach is that it's rewriting history, which can be prolematic with a shared repository.
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+
430+
===== Reverse the commit
431+
432+
If moving the branch pointers around isn't going to work for you, Git gives you the option of making a new commit which undoes all the changes from an existing one.
433+
Git calls this operation a ``revert'', and in this particular scenario, you'd invoke it like this:
434+
435+
[source,shell]
436+
----
437+
$ git revert -m 1
438+
----
439+
440+
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+
444+
The history with the revert commit looks like this:
445+
446+
.History after `git revert -m 1`
447+
448+
Take a look at <<_undoing>> for more information on Git's various methods of undoing things.
400449

401-
- `git reset --merge ORIG_HEAD`
402-
- `git revert -m 1 sha`
403450

404451
=== Branch Management
405452

@@ -618,9 +665,8 @@ In Git, there are two main ways to integrate changes from one branch into anothe
618665

619666
==== The Basic Rebase
620667

621-
If you go back to an earlier example from <<_basic_merging>> (see <<rbdiag_a>>), you can see that you diverged your work and made commits on two different branches.
668+
If you go back to an earlier example from <<_basic_merging>>, you can see that you diverged your work and made commits on two different branches.
622669

623-
[[rbdiag_a]]
624670
.Simple divergent history
625671
image::images/18333fig0327-tn.png[Simple divergent history.]
626672

@@ -724,6 +770,7 @@ $ git branch -d server
724770
.Final commit history
725771
image::images/18333fig0335-tn.png[Final commit history.]
726772

773+
[[_rebase_peril]]
727774
==== The Perils of Rebasing
728775

729776
Ahh, but the bliss of rebasing isn’t without its drawbacks, which can be summed up in a single line:

en/book/images/undomerge-start.png

12.2 KB
Loading

0 commit comments

Comments
 (0)