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的比较:

兼容性:很明显,git diff生成的Patch兼容性强。如果你在修改的代码的官方版本库不是Git管理的版本库,那么你必须使用git diff生成的patch才能让你的代码被项目的维护人接受。

除错功能:对于git diff生成的patch,你可以用git apply --check 查看补丁是否能够干净顺利地应用到当前分支中;如果git format-patch 生成的补丁不能打到当前分支,git am会给出提示,并协助你完成打补丁工作,你也可以使用git am -3进行三方合并,详细的做法可以参考git手册或者《Progit》。从这一点上看,两者除错功能都很强。

版本库信息:由于git format-patch生成的补丁中含有这个补丁开发者的名字,因此在应用补丁时,这个名字会被记录进版本库,显然,这样做是恰当的。因此,目前使用Git的开源社区往往建议大家使用format-patch生成补丁。

git diff patch方法的更多相关文章

  1. git diff patch

    如何生成patch:修改一个地方,然后git diff > xxx.patch 就会生成一个patch文件,这里的关键似乎是, 源文件的某个模块的版本要和线上发布的最新版本要一致,这样patch ...

  2. Git diff 常见用法

      Git diff 用于比较两次修改的差异 1.1 比较工作区与暂存区 git diff  比较的是单个仓库的工作区与暂存区的差别,repo diff是对git diff的封装,用来分别显示各个项目 ...

  3. git diff 生成patch, git apply patch 打补丁方法说明,以及分支管理的简单操作。

    git diff 简易操作说明 先git log 查看commit ID, 记录你想要打的补丁的ID 比如说: git log commit 4ff35d800fa62123a28b7bda2a04e ...

  4. linux git patch 和patch以及git diff 命令

    1.git log 查看commit id,修改前为id1,修改后id2 2.根据id1到id2有几次提交来生成几个patch,否则的话会根据所有节点生成很多patch 比如: commit id2 ...

  5. Git以及github的使用方法(三),git status查看工作区的状态,git diff查看具体修改内容

    我们已经成功地添加并提交了一个readme.txt文件,现在,是时候继续工作了,于是,我们继续修改readme.txt文件,改成如下内容: Git is a distributed version c ...

  6. GIT的使用方法

    GIT的使用方法 1.电脑首先安装GIT, 2.在官网注册GitHub账号. 一,使用git在控制台进行本地操作 1.打开GitBash 2.填写用户名和邮箱作为标识分别执行以下命令: git/ co ...

  7. git diff的文字说明

    -U<n>--unified=<n> Generate diffs with <n> lines of context instead of the usual t ...

  8. git diff ^M的消除

    这是由于换行符在不同的操作系统上定义的区别造成的. Windows用CR LF来定义换行,Linux用LF. CR全称是Carriage Return ,或者表示为\r, 意思是回车. LF全称是Li ...

  9. Git的Patch功能

    转自:http://www.cnblogs.com/y041039/articles/2411600.html UNIX世界的软件开发大多都是协作式的,因此,Patch(补丁)是一个相当重要的东西,因 ...

随机推荐

  1. jquery-ui实现拖拽功能

    https://www.runoob.com/jqueryui/jqueryui-tutorial.html

  2. asyncio 自动跳出长时间堵塞的 task

    https://www.cnblogs.com/ywhyme/p/10660411.html 的升级版 可以知道当前是卡在哪一个 task 甚至是多少行 import asyncio import o ...

  3. Tab 切换效果

    今天写的两个小效果都是为了测试我写的单参函数,结果还是有点成功的~~此处是不是想发表情包! Tab效果很简单,这里我就不赘述了,直接上代码: html代码: <div class="c ...

  4. PHP 闭包之变量作用域

      在项目中,难免会遇到闭包的形式,那么在闭包中,变量的作用域到底是怎么样的呢.下面有几个简单的例子. e1 function test_1() { $a = 'php'; $func = funct ...

  5. PHP学习总结(10)——PHP入门篇之自定义网站根目录

  6. BA-siemens-insight时间表设置

    时间表问题汇总: 如果遇到这种问题,显示"unable to locate databse object",就使用database transfer上传一边所有的模块信息,然后在操 ...

  7. Scrapy系列教程(6)------怎样避免被禁

    避免被禁止(ban) 有些网站实现了特定的机制,以一定规则来避免被爬虫爬取. 与这些规则打交道并不easy,须要技巧,有时候也须要些特别的基础. 假设有疑问请考虑联系 商业支持 . 以下是些处理这些网 ...

  8. Java向上转型和向下转型(附具体样例)

                                                Java向上转型和向下转型(附具体样例) 熬夜整理的关于Java向上和向下转型的样例,很的通俗易懂哦~~~~ 一 ...

  9. tcMalloc 配置和优化 nginx 高性能

    tcMalloc优化nginx  记住:nginx一定要先启动 1>下载安装libunwind: #wget  http://download.savannah.gnu.org/releases ...

  10. C语言的长处和缺点

     C语言的长处和缺点 C语言的长处: 1.面向过程的语言C语言是面向过程的语言,在这里用户创建过程或函数来运行他们的任务. 面向过程的语言是非常easy学.因为它遵循的算法来运行你的语句.要使用面 ...