UNIX世界的軟件開發大多都是協做式的,所以,Patch(補丁)是一個至關重要的東西,由於幾乎全部的大型UNIX項目的普通貢獻者,都是經過 Patch來提交代碼的。做爲最重要的開源項目之一,Linux,也是這樣的。普通開發者從軟件倉庫clone下代碼,而後寫入代碼,作一個Patch, 最後用E-mail發給Linux Kernel的維護者就行了。Git最初做爲Linux的版本控制工具,提供了透明、完整、穩定的Patch功能。git
咱們先介紹一下Patch是什麼。若是一個軟件有了新版本,咱們能夠完整地下載新版本的代碼進行編譯安裝。然而,像Linux Kernel這樣的大型項目,代碼即便壓縮,也超過70MB,每次全新下載是有至關大的代價的。然而,每次更新變更的代碼可能不超過1MB,所以,咱們只 要可以有兩個版本代碼的diff的數據,應該就能夠以極低的代價更新程序了。所以,Larry Wall開發了一個工具:patch。它能夠根據一個diff文件進行版本更新。app
不過在git中,咱們沒有必要直接使用diff和patch來作補丁,這樣作既危險又麻煩。git提供了兩種簡單的patch方案。一是用git diff生成的標準patch,二是git format-patch生成的Git專用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'orm
接下來咱們在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'it
咱們如今有一個patch文件,而且簽出了master,接下來咱們可使用git apply來應用這個patch。固然了,實際應用中,咱們不會這樣在一個分支建patch,到另外一個分支去應用,由於只有merge一下就行了。咱們現 在權當沒有這個Fix分支。通常狀況下,爲了保護master,咱們會創建一個專門處理新交來的patch的分支:io
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。社區
咱們一樣用上面那個例子的工做目錄,此次,咱們在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。