Git的Patch功能
UNIX世界的軟體開發大多都是協作式的,因此,Patch(補丁)是一個相當重要的東西,因為幾乎所有的大型UNIX項目的普通貢獻者,都是通過 Patch來提交代碼的。作為最重要的開源項目之一,Linux,也是這樣的。普通開發者從軟體倉庫clone下代碼,然後寫入代碼,做一個Patch, 最後用E-mail發給Linux Kernel的維護者就好了。Git最初作為Linux的版本控制工具,提供了透明、完整、穩定的Patch功能。
我們先介紹一下Patch是什麼。如果一個軟體有了新版本,我們可以完整地下載新版本的代碼進行編譯安裝。然而,像Linux Kernel這樣的大型項目,代碼即使壓縮,也超過70MB,每次全新下載是有相當大的代價的。然而,每次更新變動的代碼可能不超過1MB,因此,我們只 要能夠有兩個版本代碼的diff的數據,應該就可以以極低的代價更新程序了。因此,Larry Wall開發了一個工具:patch。它可以根據一個diff文件進行版本更新。
不過在git中,我們沒有必要直接使用diff和patch來做補丁,這樣做既危險又麻煩。git提供了兩種簡單的patch方案。一是用git diff生成的標準patch,二是git format-patch生成的Git專用Patch。
1.git diff生成的標準patch
我們可以首先用git diff製作一個patch。本文示例的工作目錄里最初有一個文件a,內容是「This is the file a.」,放置在master分支中。為了修改代碼,我們一般的做法是建立一個新分支:
sweetdum@sweetdum-ASUS:~/GitEx$ git branch Fix sweetdum@sweetdum-ASUS:~/GitEx$ git checkout Fix Switched to branch "Fix"
接下來我們在a文件裡面追加一行,然後執行git diff。 sweetdum@sweetdum-ASUS:~/GitEx$ echo "Fix!!!">>a sweetdum@sweetdum-ASUS:~/GitEx$ git diff diff --git a/a b/a index 4add65f..0d295ac 100644 --- a/a +++ b/a @@ -1 +1,2 @@ This is the file a. +Fix!!!
我們看到了Git diff的輸出,這是一個非常典型的Patch式diff。這樣我們可以直接把這個輸出變為一個Patch: sweetdum@sweetdum-ASUS:~/GitEx$ git commit -a -m "Fix" [Fix b88c46b] Fix 1 files changed, 1 insertions(+), 0 deletions(-) sweetdum@sweetdum-ASUS:~/GitEx$ git diff master > patch sweetdum@sweetdum-ASUS:~/GitEx$ git checkout master Switched to branch "master"
我們現在有一個patch文件,並且簽出了master,接下來我們可以使用git apply來應用這個patch。當然了,實際應用中,我們不會這樣在一個分支建patch,到另一個分支去應用,因為只有merge一下就好了。我們現 在權當沒有這個Fix分支。一般情況下,為了保護master,我們會建立一個專門處理新交來的patch的分支:
sweetdum@sweetdum-ASUS:~/GitEx$ git branch PATCH sweetdum@sweetdum-ASUS:~/GitEx$ git checkout PATCH Switched to branch "PATCH" sweetdum@sweetdum-ASUS:~/GitEx$ git apply patch sweetdum@sweetdum-ASUS:~/GitEx$ git commit -a -m "Patch Apply" [PATCH 9740af8] Patch Apply 1 files changed, 1 insertions(+), 0 deletions(-)
看,現在我們在PATCH分支中應用了這個補丁,我們可以把PATCH分支和Fix比對一下,結果肯定是什麼也沒有,說明PATCH分支和Fix分支完全一樣。patch應用成功。即使有多個文件git diff 也能生成一個patch。
2.git format-patch生成的git專用補丁。我們同樣用上面那個例子的工作目錄,這次,我們在Fix分支中的a添加了新行之後,用git format-patch生成一個patch。 sweetdum@sweetdum-ASUS:~/GitEx$ git checkout Fix Switched to branch "Fix" sweetdum@sweetdum-ASUS:~/GitEx$ echo "Fix!!!">>a sweetdum@sweetdum-ASUS:~/GitEx$ git commit -a -m "Fix1" [Fix 6991743] Fix1 1 files changed, 1 insertions(+), 0 deletions(-) sweetdum@sweetdum-ASUS:~/GitEx$ git format-patch -M master 0001-Fix1.patch
git format-patch的-M選項表示這個patch要和那個分支比對。現在它生成了一個patch文件,我們看看那是什麼:
sweetdum@sweetdum-ASUS:~/GitEx$ cat 0001-Fix1.patch From 6991743354857c9a6909a253e859e886165b0d90 Mon Sep 17 00:00:00 2001 From: Sweetdumplings <linmx0130@163.com> Date: Mon, 29 Aug 2011 14:06:12 +0800 Subject: [PATCH] Fix1
--- a | 1 + 1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/a b/a index 4add65f..0d295ac 100644 --- a/a +++ b/a @@ -1 +1,2 @@ This is the file a. +Fix!!! -- 1.7.4.1
看,這次多了好多東西,不僅有diff的信息,還有提交者,時間等等,仔細一看你會發現,這是個E-mail的文件,你可以直接發送它!這種patch,我們要用git am來應用。
sweetdum@sweetdum-ASUS:~/GitEx$ git checkout master Switched to branch "master" sweetdum@sweetdum-ASUS:~/GitEx$ git branch PATCH sweetdum@sweetdum-ASUS:~/GitEx$ git checkout PATCH sweetdum@sweetdum-ASUS:~/GitEx$ git am 0001-Fix1.patch Applying: Fix1 sweetdum@sweetdum-ASUS:~/GitEx$ git commit -a -m "PATCH apply"
在提交了補丁之後,我們可以再看看目前文件a的情況:
sweetdum@sweetdum-ASUS:~/GitEx$ cat a This is the file a. Fix!!!
果然,多了一個Fix!!!
不過要注意的是,如果master與Fix分支中間有多次提交,它會針對每次提交生成一個patch。
3.兩種patch的比較:
推薦閱讀:
※超聲引導射頻消融治療肝癌的圍術期免疫功能變化及隨訪觀察
※兩種蔬菜預防癌症功能獲證實:不用再懷疑了
※啤酒的保健功能
※中醫中常見的10味中藥,其性味歸經和功能主治,值得收藏
※陽台小改造 ----舒適與功能加倍放大(典藏)
TAG:功能 |