git什麼情況下會產生衝突以及如何優雅的解決衝突
寫在前面:
現在還只是雜亂的記錄,部分內容在公司,需要時間手工搬運出來…
普通合入引發的衝突
方法1(推薦):使用rebase
- git fetch
下載所有分支的最新的遠端分支(看一下如何下載某個特定分支) - git rebase origin/master
以origin/master分支為基線,合入master分支的修改。
手動解決衝突 - git add -A;git rebase --continue
衝突解決完成之後,提交修改 - git push origin master:refs/for/master
推送到遠端伺服器
方法2:使用merge
- git fetch
下載所有分支的最新的遠端分支(看一下如何下載某個特定分支) - git checkout origin/master
直接切到遠端的master分支 - git merge master
將master分支的修改合入
手動解決衝突 - git add -A;git commit
提交修改 - git push origin HEAD:refs/for/master
推送到遠端伺服器
cherry-pick
cherry-pick是在服務端進行操作的,完全不涉及本地分支。
cherry-pick的原理可以簡單理解為:
將兩個提commit之間的差異(patch)應用到另一個分支上。那麼,如果如果patch對應的原始檔對應的行在另一個分支已經被改變了,那麼就無法成功應用patch,會提示衝突。必須要在本地手動解決衝突。
假如要將master某個commit提交到dev分支,操作流程如下:
- git fetch
下載所有分支的最新的遠端分支(看一下如何下載某個特定分支) - git checkout -B dev origin/dev
直接用遠端的dev分支覆蓋本地的dev分支 - git checkout dev
切換到dev分支 - git cheery-pick commitId
手動解決衝突 - git add -A;git commit
提交修改 - git puhs origin dev:refs/for/dev
git pull
網上搜到的解釋都是說pull是fetch+merge操作的合併。
那麼到底是誰merge誰,merge的過程中是否會產生新的提交,產生的提交push的時候又是否會推送到遠端呢?
實踐一下:
1. origin/master比master多一個節點
此時使用git pull拉取分支時,本地master直接更新為和遠端master一樣。
2. orgin/master 和master分叉以後,各自多了一個節點,並且無衝突
然後進行pull操作,會發現在本地的master分支上形成了一個新的提交,對應的message為:Merge branch ‘master’ of https://github.com/copbint/blogs
origin/master並未發生改變。
圖示:
將master推送到遠端。
遠端生成了一個新的提交。
由於master指向的節點,是orgin/master指向的節點的子節點,並無分叉,所以一定不會出現衝突。
再執行git pull將遠端最新程式碼取下來,master和origin/master都指向了最新的提交。即D‘
3. orgin/master 和master分叉以後,各自多了一個節點,有衝突
執行,git pull報衝突:
此時必須手動解決衝突。然後提交修改。此時會產生一個新的commit。
和上面的例子唯一的區別就是需要手動解決衝突,然後提交commit。
如果此時,再提交一個新的commit,然後推送到遠端。會推送幾個commit呢?
實踐了一下,遠端產生了兩個提交。
4. 總結
git pull就是先獲取遠端分支,然後將對應的遠端分支merge到本地分支上來。
如果本地分支和遠端分支已經分叉,則會在本地分支上產生一個新的提交。
如果有衝突,則需要手動解決衝突。
臨時記錄
在某個不用的服務上建立兩個test分支,用完之後可以刪除掉。
test_MASTER_test
test_DEV_test
gerrit的展示不是很準確,commit的內容並不在當前分支也展示出來。而真正改變當前分支的merge …對應commit的改變卻並沒有提現出來。