[GIT] Delete wrong merge, then redo

做 merge 的時候難免手殘...
<!--more-->
如果還沒 push 到 server 上,那可以用 git reset –hard HEAD~1 來復原。如果是用 –soft 的話該 merge commit 依然會存在 local repository中,不像用 –hard 會刪除。

$ git log
commit f92ab34564f48ad6ee9f6bdb13c352e63669dccd
Merge: 62f6af0 4f641f3
Author: admin <admin@test.com>
Date:   Fri Jun 23 11:07:53 2017 +0800

    before merge 3d_checkpoint

commit 62f6af03b7dc1f0539836b13910850189a0fcd2a
Author: admin <admin@test.com>
Date:   Thu Apr 20 11:54:58 2017 +0800

    before a wrong push
    .....
    .....
$ git reset --hard HEAD~1
HEAD is now at 62f6af0 before a wrong push
$ git log
commit 62f6af03b7dc1f0539836b13910850189a0fcd2a
Author: admin <admin@test.com>
Date:   Thu Apr 20 11:54:58 2017 +0800

    before a wrong push
    .....
    .....

如果已經 push 到 server 上頭了,可以用這樣的作法。先 checkout merge 前的 commit (意即 detach HEAD),然後重新做 commit,產生出新的 detached HEAD,然後用 –force 參數,將 HEAD push 回 server。

$ git log --graph
*   commit f92ab34564f48ad6ee9f6bdb13c352e63669dccd
|\  Merge: 62f6af0 4f641f3
| | Author: admin <admin@test.com>
| | Date:   Fri Jun 23 11:07:53 2017 +0800
| | 
| |     before merge 3d_checkpoint
| |   
| * commit 4f641f37090d8045cb84e64fe61402373f8fe38a
| | Author: admin <admin@test.com>
| | Date:   Thu Jan 5 12:17:33 2017 +0800
| | 
| |     test
| |   
| * commit aa548710991c0a072759ebeb05883352f73875b7
| | Author: admin <admin@test.com>
| | Date:   Thu Dec 8 17:25:11 2016 +0800
| | 
| |     message
| |   
* | commit 62f6af03b7dc1f0539836b13910850189a0fcd2a
| | Author: admin <admin@test.com>
| | Date:   Thu Apr 20 11:54:58 2017 +0800
| | 
| |     before a wrong push
| |   
* | commit 36b6b053ff9980ce7934f9f9c4a5a849ca7fcc7a
|/  Author: admin <admin@test.com>
|   Date:   Thu Dec 8 17:19:34 2016 +0800
|   
|       use "git mv" to move file out of folder
|  
$ git checkout 62f6af03b7dc1f0539836b13910850189a0fcd2a
Note: checking out '62f6af03b7dc1f0539836b13910850189a0fcd2a'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b <new-branch-name>

HEAD is now at 62f6af0... before a wrong push
$ git merge 3d_checkpoint 
CONFLICT (rename/delete): file_in_folder.txt deleted in 3d_checkpoint and renamed in HEAD. Version HEAD of file_in_folder.txt left in tree.
Automatic merge failed; fix conflicts and then commit the result.
$ git status
HEAD detached at 62f6af0
You have unmerged paths.
  (fix conflicts and run "git commit")

Changes to be committed:

	new file:   checkpoint.txt

Unmerged paths:
  (use "git add <file>..." to mark resolution)

	added by us:     file_in_folder.txt

$ git rm file_in_folder.txt 
file_in_folder.txt: needs merge
rm 'file_in_folder.txt'
$ git status
HEAD detached at 62f6af0
All conflicts fixed but you are still merging.
  (use "git commit" to conclude merge)

Changes to be committed:

	new file:   checkpoint.txt
	deleted:    file_in_folder.txt

$ git commit -m "new and fixed, before merge 3d_checkpoint"
[detached HEAD 8c713b0] new and fixed, before merge 3d_checkpoint
$ git push origin HEAD:3d_test --force
Counting objects: 2, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (2/2), 292 bytes | 0 bytes/s, done.
Total 2 (delta 1), reused 0 (delta 0)
remote: 
remote: To create a merge request for 3d_test, visit:
remote:   https://tools.test.com/testing/gittest/merge_requests/new?merge_request%5Bsource_branch%5D=3d_test
remote: 
To git@tools.test.com:testing/gittest.git
 + f92ab34...8c713b0 HEAD -> 3d_test (forced update)

但要注意的是,這樣做完之後,local repository跟 server上頭的會不一致,記得要再重新 pull 一次