[Git] 使用 git format-patch 將指定 commit 的內容補丁到任意分支

[Git] 使用 git format-patch 將指定 commit 的內容補丁到任意分支

在公司使用 Git 協同開發時,常常遇到一個問題,

就是平常會從 dev 開一個分支出來,開發新的功能,

但中途可能發現有個 bug 需要修掉。

理論上應該回到 dev 再開一個新的 bug 分支,

但是那樣的話,原本在寫的新功能的部分就會消失,

導致本來可以測試的部分又壞掉…

 

所以我通常會想要從功能分支上,直接開出一個 bug 分支,

這樣它會有新的功能,同時可以修 bug,也不影響我的測試。

但是我不能直接把這個 bug 分支送上 PR (Pull Request),

因為它會把開發中的部分也直接送上去了。

有沒有辦法單把我修 bug 的部分,單獨變成另一個新的 bug 分支,

這樣我就可以單獨對它送出 PR 呢?

 

感覺上應該是有許多種方法,我這邊試的是用 git format-patch 的方式。

首先,用 git log 查看一下,

這個例子裡的前一個 commit a4f9 是有新功能的部分,

最新的 af64 則是修了 bug:

testuser@localhost ~ $ git log

commit af64a3dbd21b332551f4dd7b9d7d0d91b1e612fd
Author: Test User <testuser@test.com>
Date:   Wed Apr 22 09:56:51 2020 +0800

    Fix cli: showvminfo

commit a4f91f12af185c2202a6a09b8a8c805eb957790d
Merge: 1cd2782 14fc670
Author: Test User <testuser@test.com>
Date:   Tue Apr 21 23:12:19 2020 +0800

    Merge branch 'dev' into feature/041613-convert-cmdline

 

我想把 af64 那個 commit 變成一個單獨的補丁檔 (patch),

可以用 git format-patch 指令。

不過要注意參數我給的是 a4f9 也就是前一個 commit,

因為 git format-patch 會把 af49 到最新 commit (af64) 間的改變,

變成一個 patch 檔,

像這次它產生了一個 0001-Fix-cli-showvminfo.patch:

testuser@localhost ~ $ git format-patch a4f91f12af185c2202a6a09b8a8c805eb957790d

0001-Fix-cli-showvminfo.patch

 

當然你也可以用 HEAD~1 取代 a4f9,

表示我要取前一次 commit 到最新 commit 間的改變,效果相同:

git format-patch HEAD~1

 

這個 patch 檔案的內容,前面是給 git 看的資訊,

後面的部分就跟 diff 指令會產生的 patch 檔類似:

testuser@localhost ~ $ cat 0001-Fix-cli-showvminfo.patch

From af64a3dbd21b332551f4dd7b9d7d0d91b1e612fd Mon Sep 17 00:00:00 2001
From: Test User <testuser@test.com>
Date: Wed, 22 Apr 2020 09:56:51 +0800
Subject: [PATCH] Fix cli: showvminfo

---
 src/cli/showvminfo.py | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/src/cli/showvminfo.py b/src/cli/showvminfo.py
index f0ef1f9..1c3e2f9 100644
--- a/src/cli/showvminfo.py
+++ b/src/cli/showvminfo.py
@@ -1,11 +1,12 @@
+import xml.etree.cElementTree as ET
 from cli import Cmd
+from manager.xml import Xml

 

我現在就可以回到 dev 分支,然後開一個 bug/fix-showvminfo 分支,

準備來修 bug:

testuser@localhost ~ $ git checkout -b bug/fix-showvminfo

Switched to a new branch 'bug/fix-showvminfo'

 

接著用 git apply –check 檢查一下這個補丁檔,能不能應用在這個分支上。

如果沒有衝突的話,這個指令不會輸出任何東西:

git apply --check 0001-Fix-cli-showvminfo.patch

 

接著就可以拿掉 –check 參數,讓 git apply 真正的打上補丁:

git apply 0001-Fix-cli-showvminfo.patch

 

這時用 git status 指令,可以看到補丁確實被打上了,

可以再用 git diff 指令檢查一下修改的內容,再 commit 了:

testuser@localhost ~ $ git status

On branch bug/fix-showvminfo
Changes not staged for commit:
  (use "git add ..." to update what will be committed)
  (use "git checkout -- ..." to discard changes in working directory)

	modified:   cli/showvminfo.py

 

git commit 之後,就可以對這 bug 分支送出 PR,

它不會包含之前的 af49 的 commit,

因此 PR 裡就只會有修 bug 的部分,同事審查起來也比較簡單~

 

如果很確定 patch 檔案沒問題的話,也可以直接用 git am 來上補丁,

省掉 git apply 和 git commit 兩個動作,

不過我還是傾向用 git apply 一步步做,比較安心囉~^^

(本頁面已被瀏覽過 13,684 次)

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料