设为首页 收藏本站
查看: 873|回复: 0

[经验分享] Git的Patch功能

[复制链接]

尚未签到

发表于 2018-9-18 09:07:53 | 显示全部楼层 |阅读模式
  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
  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生成补丁。


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-589662-1-1.html 上篇帖子: Git 设置 下篇帖子: git clone eclipse 失败
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表