git revert merge 的commit


比如當我們Git revert的時候,

git revert 

 

Git會抱怨:

 

is a merge but no -m option was given

 

這是因為你revert的那個commit是一個merge commit,它有兩個parent, Git不知道base是選哪個parent,就沒法diff,所以就抱怨了,所以你要顯示告訴Git用哪一個parent。

 

git revert sidsad8 -m 1

 

這樣就選parent 1,那么parent 1又是哪一個呢?

 

一般來說,如果你在master上mergezhc_branch,那么parent 1就是master,parent 2就是zhc_branch.

 

Often this will be parent number one, for example if you were on master and did git merge unwanted and then decided to revert the merge of unwanted. The first parent would be your pre-merge master branch and the second parent would be the tip of unwanted.

 

 

Git 撤銷 merge  

 

在使用Git開發過程中偶爾會遇到合並(merge)錯代碼的情形。此時需要撤銷已經合並的分支(branch)。

雖然對git有了一定的了解和使用,但是這種撤銷合並分支的情況還是不太清楚改如何處理,這里有一個比較好的資料。
這里通過本人親身試驗對連接中文章的revert a merge commit 部分
做一定程度的解釋:
先原因文章內容:

Merge Commit

在描述 merge commit 之前,先來簡短地描述一下常規的 commit。每當你做了一批操作(增加、修改、或刪除)之后,你執行 git commit 便會得到一個常規的 Commit。執行 git show <commit> 將會輸出詳細的增刪情況。

Merge commit 則不是這樣。每當你使用 git merge 合並兩個分支,你將會得到一個新的 merge commit。執行 git show <commit> 之后,會有類似的輸出:

commit 83281a8e9aa1ede58d51a6dd78d5414dd9bc8548//本人實際git信息,這里對應git演進圖中的 g

Merge: 312a518 fa87415 //312a518和fa87415 可以在git log中找到對應的提交信息(只是commit一長串字符的頭部分)

Author:XXX

Date:   Wed May 28 10:02:10 2014 +0800

    Merge branch 'dev' into master

    Merge branch 'dev' into master

    Conflicts:

        gitRevert.rtf

其中,Merge 這一行代表的是這個合並 parents它可以用來表明 merge 操作的線索

舉個例子,通常,我們的穩定代碼都在 master 分支,而開發過程使用 dev 分支,當開發完成后,再把 dev 分支 merge 進 master 分支:

a -> b -> c -> f -- g -> h (master) \ / d -> e (dev)

上圖中,g 是 merge commit,其他的都是常規 commit。g 的兩個 parent 分別是 f 和 e

Revert a Merge Commit

當你使用 git revert 撤銷一個 merge commit 時,如果除了 commit 號而不加任何其他參數,git 將會提示錯誤:

$ git revert 83281a8e9aa1ede58d51a6dd78d5414dd9bc8548 //本人實際git信息,這里對應git演進圖中的 g
error: Commit g is a merge but no -m option was given.
fatal: revert failed

在你合並兩個分支並試圖撤銷時,Git 並不知道你到底需要保留哪一個分支上所做的修改。從 Git 的角度來看,master 分支和 dev 在地位上是完全平等的,只是在 workflow 中,master 被人為約定成了「主分支」。

於是 Git 需要你通過 m 或 mainline 參數來指定「主線」。merge commit 的 parents 一定是在兩個不同的線索上,因此可以通過 parent 來表示「主線」。m 參數的值可以是 1 或者 2,對應着 parent 在 merge commit 信息中的順序。

以上面那張圖為例,我們查看 commit g 的內容

$ git show 83281a8e9aa1ede58d51a6dd78d5414dd9bc8548 //本人實際git信息,這里對應git演進圖中的 g

commit 83281a8e9aa1ede58d51a6dd78d5414dd9bc8548

Merge: 312a518 fa87415 //312a518和fa87415 可以在git log中找到對應的提交信息(只是commit一長串字符的頭部分)

......

那么,$ git revert -m 1 g 將會保留 master 分支上的修改,撤銷 dev 分支上的修改。//(1就是1,表示312a518對應的父來源,2表示fa87415對應的父來源)撤銷成功之后,Git 將會生成一個新的 Commit,提交歷史就成了這樣:

a -> b -> c -> f -- g -> h -> G (master)
\ /
d -> e (dev)

其中 G 是撤銷 g 生成的 commit。通過 $ git show G 之后,我們會發現 G 是一個常規提交,內容就是撤銷 merge 時被丟棄的那條線索的所有 commit 的「反操作」的合集。

請注意紅色注釋部分。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM