1. 程式人生 > >git什麼情況下會產生衝突以及如何優雅的解決衝突

git什麼情況下會產生衝突以及如何優雅的解決衝突

寫在前面:
現在還只是雜亂的記錄,部分內容在公司,需要時間手工搬運出來…

普通合入引發的衝突

方法1(推薦):使用rebase

  1. git fetch
    下載所有分支的最新的遠端分支(看一下如何下載某個特定分支)
  2. git rebase origin/master
    以origin/master分支為基線,合入master分支的修改。
    手動解決衝突
  3. git add -A;git rebase --continue
    衝突解決完成之後,提交修改
  4. git push origin master:refs/for/master
    推送到遠端伺服器

方法2:使用merge

  1. git fetch
    下載所有分支的最新的遠端分支(看一下如何下載某個特定分支)
  2. git checkout origin/master
    直接切到遠端的master分支
  3. git merge master
    將master分支的修改合入
    手動解決衝突
  4. git add -A;git commit
    提交修改
  5. git push origin HEAD:refs/for/master
    推送到遠端伺服器

cherry-pick

cherry-pick是在服務端進行操作的,完全不涉及本地分支。
cherry-pick的原理可以簡單理解為:
將兩個提commit之間的差異(patch)應用到另一個分支上。那麼,如果如果patch對應的原始檔對應的行在另一個分支已經被改變了,那麼就無法成功應用patch,會提示衝突。必須要在本地手動解決衝突。
假如要將master某個commit提交到dev分支,操作流程如下:

  1. git fetch
    下載所有分支的最新的遠端分支(看一下如何下載某個特定分支)
  2. git checkout -B dev origin/dev
    直接用遠端的dev分支覆蓋本地的dev分支
  3. git checkout dev
    切換到dev分支
  4. git cheery-pick commitId
    手動解決衝突
  5. git add -A;git commit
    提交修改
  6. 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的改變卻並沒有提現出來。