第20章 补丁文件交互

之前各个章节的版本库间的交互都是通过git push和/或git pull命令来实现的,这是Git最主要的交互模式,但并不是全部。使用补丁文件是另外一种交互方式,适用于参与者众多的大型项目进行的分布式开发。例如Git项目本身的代码提交就主要由贡献者通过邮件传递补丁文件来实现的。作者在写书过程中发现了Git的两个Bug,就是以补丁形式通过邮件贡献给Git项目的,下面两个链接就是相关邮件的存档。

关于Git文档错误的Bugfix:

http://marc.info/?l=git&m=129248415230151

关于git-apply的一个Bugfix:

http://article.gmane.org/gmane.comp.version-control.git/162100

这种使用补丁文件进行提交的方式可以提高项目的参与度。因为任何人都可以参与项目的开发,只要会将提交转化为补丁,会发邮件即可。

20.1 创建补丁

Git提供了将提交批量转换为补丁文件的命令:git format-patch。该命令后面的参数是一个版本范围列表,会将包含在此列表中的提交一一转换为补丁文件,每个补丁文件包含一个序号并从提交说明中提取字符串作为文件名。

下面演示一下在user1工作区中,如何将master分支的最近3个提交转换为补丁文件。(1)进入user1工作区,切换到master分支。


$cd/path/to/user1/workspace/hello-world/

$git checkout master

$git pull


(2)执行下面的命令将最近3个提交转换为补丁文件。


$git format-patch-s HEAD~3..HEAD

0001-Fix-typo-help-to-help.patch

0002-Add-I18N-support.patch

0003-Translate-for-Chinese.patch


在上面的git format-patch命令中使用了-s参数,会在导出的补丁文件中添加当前用户的签名。这个签名并非GnuPG式的数字签名,不过是将作者姓名添加到提交说明中而已,和在本书第2篇开头介绍的git commit-s命令的效果相同。虽然签名很不起眼,但是对于以补丁的方式提交数据却非常重要,因为以补丁方式的提交可能因为合并冲突或其他原因使得最终提交的作者ID显示为代为提交的项目管理员的ID,在提交说明中加入原始作者的署名信息大概是作者唯一露脸的机会。如果在提交时忘了使用-s参数添加签名,可以在用git format-path命令创建补丁文件的时候补救。

看一下补丁文件的文件头,在下面代码中的第7行可以看到新增的签名。


1 From d81896e60673771ef1873b27a33f52df75f70515 Mon Sep 17 00:00:00 2001

2 From:user1<user1@sun.ossxp.com>

3 Date:Mon,3 Jan 2011 23:48:56+0800

4 Subject:[PATCH 1/3]Fix typo:-help to—help.

5

6

7 Signed-off-by:user1<user1@sun.ossxp.com>

8 —-

9 src/main.c|2+-

10 1 files changed,1 insertions(+),1 deletions(-)


补丁文件有一个类似邮件一样的文件头(第1~4行),提交日志的第一行作为邮件标题(Subject),其余的提交说明作为邮件内容(如果有的话),文件补丁用三个横线和提交说明分开。

实际上这些补丁文件可以直接拿来作为邮件发送给项目的负责人。Git提供了一个辅助邮件发送的命令git send-email。下面用该命令将这三个补丁文件以邮件的形式发送出去。


$git send-email*.patch

0001-Fix-typo-help-to-help.patch

0002-Add-I18N-support.patch

0003-Translate-for-Chinese.patch

The following files are 8bit,but do not declare a Content-Transfer-Encoding.

0002-Add-I18N-support.patch

0003-Translate-for-Chinese.patch

Which 8bit encoding should I declare[UTF-8]?

Who should the emails appear to be from?[user1<user1@sun.ossxp.com>]

Emails will be sent from:user1<user1@sun.ossxp.com>

Who should the emails be sent to?jiangxin

Message-ID to be used as In-Reply-To for the first email?

Send this email?([y]es|[n]o|[q]uit|[a]ll):a


命令git send-email提供交互式字符界面,输入正确的收件人地址,邮件就批量地发送出去了。