Git 打補丁-- patch 和 diff 的使用(詳細)

王小樹發表於2018-07-25

一、 patch 和diff 的區別

Git 提供了兩種補丁方案,一是用git diff生成的UNIX標準補丁.diff檔案,二是git format-patch生成的Git專用.patch 檔案。 .diff檔案只是記錄檔案改變的內容,不帶有commit記錄資訊,多個commit可以合併成一個diff檔案。 .patch檔案帶有記錄檔案改變的內容,也帶有commit記錄資訊,每個commit對應一個patch檔案。

在Git下,我們可以使用.diff檔案也可以使用.patch 檔案來打補丁,主要應用場景有:CodeReview、程式碼遷移等。

二、建立patch和diff

1、建立patch 檔案的常用命令列

*某次提交(含)之前的幾次提交:
git format-patch 【commit sha1 id】-n
複製程式碼

n指從sha1 id對應的commit開始算起n個提交。 eg:

git format-patch  2a2fb4539925bfa4a141fe492d9828d030f7c8a8 -2
複製程式碼
*某個提交的patch:
git format-patch 【commit sha1 id】 -1
複製程式碼

eg:

git format-patch  2a2fb4539925bfa4a141fe492d9828d030f7c8a8 -1
複製程式碼
*某兩次提交之間的所有patch:
git format-patch 【commit sha1 id】..【commit sha1 id】 
複製程式碼

eg:

git format-patch  2a2fb4539925bfa4a141fe492d9828d030f7c8a8..89aebfcc73bdac8054be1a242598610d8ed5f3c8
複製程式碼
2、建立diff檔案的常用方法
使用命令列
git diff  【commit sha1 id】 【commit sha1 id】 >  【diff檔名】
複製程式碼

eg:

git diff  2a2fb4539925bfa4a141fe492d9828d030f7c8a8  89aebfcc73bdac8054be1a242598610d8ed5f3c8 > patch.diff
複製程式碼
使用SourceTree

選中要目標commit ,右擊,選擇create patch

Git  打補丁-- patch 和 diff 的使用(詳細)

3、如何獲取commit sha1 id

git 中的每個commit都有對應的一個sha1 id,我們可以通過在終端輸入git log,然後找到對應的commit sha1 id:

Git  打補丁-- patch 和 diff 的使用(詳細)
如圖中2a2fb4539925bfa4a141fe492d9828d030f7c8a8便是sha1 id

如果用Sourcetree的話也很方便,右擊對應的commit,選擇copy SHA-1 toclipboard便複製sha1 id到剪下板中:

Git  打補丁-- patch 和 diff 的使用(詳細)

三、應用patch 和 diff

相關命令列

檢查patch/diff是否能正常打入:
git apply --check 【path/to/xxx.patch】
git apply --check 【path/to/xxx.diff】
複製程式碼
打入patch/diff:
git apply 【path/to/xxx.patch】
git apply 【path/to/xxx.diff】
複製程式碼

或者

git  am 【path/to/xxx.patch】
複製程式碼

使用SourceTree

選擇SourceTree,在螢幕頂部選擇Aciotn-Apply patch

Git  打補丁-- patch 和 diff 的使用(詳細)
選擇patch或者diff的路徑,然後點OK
Git  打補丁-- patch 和 diff 的使用(詳細)

四、衝突解決

在打補丁過程中有時候會出現衝突的情況,有衝突時會打入失敗,如圖:

Git  打補丁-- patch 和 diff 的使用(詳細)

此時需要解決衝突: 1、首先使用 以下命令列,自動合入 patch 中不衝突的程式碼改動,同時保留衝突的部分:

git  apply --reject  xxxx.patch
複製程式碼

可以在終端中顯示出衝突的大致程式碼:

Git  打補丁-- patch 和 diff 的使用(詳細)
同時會生成字尾為 .rej 的檔案,儲存沒有合併進去的部分的內容,可以參考這個進行衝突解決。 2、解決完衝突後刪除字尾為 .rej 的檔案,並執行git add.新增改動到暫存區. 3、接著執行git am --resolved或者git am --continue

說明:在打入patch衝突時,可以執行git am --skip跳過此次衝突,也可以執行git am --abort回退打入patch的動作,還原到操作前的狀態。

關於衝突解決詳情可以參考git am衝突解決

參考連結

https://blog.csdn.net/liuhaomatou/article/details/54410361 https://blog.csdn.net/maybe_windleave/article/details/8703778 https://www.cnblogs.com/y041039/articles/2411600.html

相關文章