Git的Patch功能

2023-11-14

本文整理编辑自:
http://www.cnblogs.com/y041039/articles/2411600.html
一、前言
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
二、git diff生成的标准patch
2.1、制作标准补丁
我们可以首先用 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'
2.2、应用标准补丁
我们现在有一个patch文件,并且签出了master,接下来我们可以使用git apply来应用这个patch。当然了,实际应用中,我们不会这样在一个分支建patch,到另一个分支去应用,因为只有merge一下就好了。我们现 在权当没有这个Fix分支。一般情况下,为了保护master,我们会建立一个名叫 PATCH 的分支来专门处理新提交来的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。
三、git format-patch生成的git专用补丁
3.1、制作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的文件,你可以直接发送它!
注意 如果master与Fix分支中间有多次提交,它会针对每次提交生成一个 patch
3.2、应用git专用补丁
git format-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!!!
3.3、应用多个git专用patch
因为在git使用当中,会有很多时候别人(供应商或者其他的开发人员)发过来一系列的patch,这些patch通常的是类似这样的名字:
git-am 可以一次合并一个文件,或者一个目录下所有的patch,或者你的邮箱目录下的patch.
在使用git-am之前, 你要首先 git am –abort 一次,来放弃掉以前的am信息,这样才可以进行一次全新的am。
不然会遇到这样的错误。
.git/rebase-apply still exists but mbox given.
下面举两个例子:
示例1
你现在有一个code base: small-src, 你的patch文件放在~/patch/0001-trival-patch.patch
cd small-src
git am ~/patch/0001-trival-patch.patch
如果成功patch上去, 你就可以去喝杯茶了。
如果失败了, git 会提示错误, 比如:
error: patch failed: android/mediascanner.cpp:452
error: android/mediascanner.cpp: patch does not apply
这样你就需要先看看patch, 然后改改错误的这个文件,让这个patch能够patch上去。
示例2
你有一堆patch, 名字是上面提到的那一堆patch, 你把他们放在~/patch-set/目录下(路径随意)
cd opencore
git am ~/patch-set/*.patch
(这里git就会按照文件名的顺序一次am这些patch)
如果一切顺利, 你所有的patch都OK了, 你又Lucky了。
3.4、应用git专用补丁失败
在使用 git am 打补丁时,如果中间遇到了应用某个patch失败,那么 git am 就会停到打这个 patch的地方, 告诉你是哪个patch打不上去。
比如我现在有一个文件file,有两个patch.
file 的内容是
the text
more text
两个patch分别是:
0001-add-line.patch补丁文件 :
From 48869ccbced494e05738090afa5a54f2a261df0f Mon Sep 17 00:00:00 2001
From: zhangjiejing <zhangjiejing@zhangjiejing-desktop.(none)>
Date: Thu, 22 Apr 2010 13:04:34 +0800
Subject: [PATCH 1/2] add line
---
file | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/file b/file
index 067780e..685f0fa 100644
--- a/file
+++ b/file
@@ -3,3 +3,5 @@ file:
some text
more text
+
+add line
--
1.6.3.3
0002-change-line.patch 补丁文件:
From f756e1b3a87c216b7e0afea9d15badd033171578 Mon Sep 17 00:00:00 2001
From: zhangjiejing <zhangjiejing@zhangjiejing-desktop.(none)>
Date: Thu, 22 Apr 2010 13:05:19 +0800
Subject: [PATCH 2/2] change line
---
file | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/file b/file
index 685f0fa..7af7852 100644
--- a/file
+++ b/file
@@ -1,6 +1,6 @@
file:
-some text
+Change line text
more text
--
1.6.3.3
运行
git am *.patch 来应用这些patch, 报错, Patch failed at 0001 add line
这样我们看0001这 个patch,原来patch需要的是 some text , 而file里面是 the text, 所以我们用编 辑器把这行改成some text,
vi file
git apply 0001-add-line.patch
git add file
git am --resolved
在解决完冲突以后, 比如用git add来让git知道你已经解决完冲突了。
如果你发现这个冲突是无法解决的, 要撤销整个am的东西。 可以运行 git am –abort
如果你想只是忽略这一个 patch ,可以运行 git am –skip 来跳过这个patch.
四、两种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生成补丁。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Git的Patch功能 的相关文章

  • 将 git dcommits 切换到 svn 分支

    I had master dcommit到 和rebase来自 颠覆trunk 我创建了一个中间 Subversion 分支tc 合并来自 2 个不同分支的更改 使用 git branch master git svn branch tc
  • 将各种提交合并为一而不合并

    是否可以加入各种提交 这是我的情况 我的应用程序在 OSX 10 6 和 10 7 中运行 我已经修复了 10 6 的一些内容 然后提交了 更改为 10 7 并再次修复修复程序 以便它们兼容 然后再次提交 然后返回到 10 6 并再次检查并
  • 如何使用 vim 作为“git log”编辑器?

    当我跑步时git log 编辑器到底是什么git log正在使用 Also 无论如何我可以使用吗vim作为我的默认编辑器git log 如果我想搜索 git 日志 最好的方法是什么 现在我正在做类似的事情 git log grep bla
  • git:检查标签,修改某些内容,然后再次标记它

    我觉得我应该知道这一点 但我很困惑 我在 github 上分叉了一个存储库 我需要的是签出一个标签 称为 v1 0 5 修改文件上的语句 使用名为 1 0 5 的新标签 不带 v 重新标记该状态 然后执行对 master 进行同样的更改 让
  • Git 日志历史记录

    对于版本控制来说 重要的一件事是知道谁做了什么更改 如果某些内容发生了变化 而我不知道为什么要进行更改 我会查看历史并询问进行更改的人 当我探索 git 时 让我对这个功能有点紧张的一件事是它似乎很容易伪造 是什么阻止我将同事姓名 电子邮件
  • Git 合并删除文件

    这是第二次发生这种情况 当我进行合并时 我后来意识到正在合并的分支中的一些文件不再位于正在合并的分支中 最新的例子是我们有一个功能分支 我一直在合并主开发分支中的更改 合并后我们丢失了很多文件 并且它们现在不存在于功能分支中 为什么会出现这
  • git apply 不对文件进行任何更改

    我必须对我的存储库应用补丁并正在运行 git apply directory PWD xxxxx patch 由于我不会详细讨论的原因 我无法使用git am在这种情况下 我需要使用目录标志 吉特告诉我 gt git apply direc
  • 中止 `git stash apply` [重复]

    这个问题在这里已经有答案了 我很遗憾应用了存储 错误的分支 我如何撤消此操作并将我的存储返回到我的存储列表 以便稍后将其应用到正确的分支 如果你还没有承诺 你应该能够git stash再次 可能与git reset HEAD first A
  • 在 Xcode 9 上切换分支

    我无法找到使用 Xcode 9 切换分支的菜单项 工作副本菜单似乎已经消失 有任何想法吗 Xcode 9 Xcode 8 Press 2 to open the new Source Control Navigator 右键单击master
  • 使用 Git 处理 subversion:忽略对跟踪文件的修改

    我目前正在使用 subversion 存储库 但我正在使用 git 在我的计算机上本地工作 它使工作变得更加容易 但也使 subversion 存储库中发生的一些不良行为变得非常明显 这给我带来了问题 拉取代码后 有一个有点复杂的本地构建过
  • 如何使用 PyGithub 创建新存储库

    如何使用 PyGithub 在 Github 上创建新的存储库 我特别想知道如何使用create repo http jacquev6 net PyGithub v1 github objects AuthenticatedUser htm
  • git 工作目录中的更改拒绝恢复

    我的 git 工作目录中有五个文件git status显示为已修改 当我git diff他们 整个文件显示为已更改 我有core autocrlf true但似乎没有效果 当我试图从同事那里获取更改时 真正的问题出现了 修改 的文件之一会被
  • 合并多个 git 存储库

    假设我有一个看起来像这样的设置 phd code phd figures phd thesis 由于历史原因 这些都有自己的 git 存储库 但我想将它们合并为一个 以稍微简化事情 例如 现在我可能会进行两组更改 并且必须执行类似的操作 c
  • Git 身份验证 - 以新用户身份拉取

    以下命令集可以正常工作 mkdir carboncake cd carboncake git init git remote add origin email protected cdn cgi l email protection rep
  • Windows 上的 git 忽略文件名大小写更改 [重复]

    这个问题在这里已经有答案了 我有一个reactjs应用程序 我正在将所有文件名标准化为小写以符合Nodejs 最佳实践 https devcenter heroku com articles node best practices stic
  • 运行 flutter doctor 吐出错误:标准错误:致命:坏对象 HEAD

    我已经从官方网站安装了 Flutter 和 Android Studio 我是 Git GitHub 移动开发和 Android 开发的新手 我试图在命令提示符 Windows 10 中运行 flutter doctor 命令 但是 它会以
  • 从 Eclipse 的历史视图中删除 ORIG_HEAD 和 FETCH_HEAD

    我最近开始使用 Eclipse Kepler 和 EGit 插件 这些分支不是我习惯的 有没有办法永久阻止这些分支的创建 我尝试手动删除它们 但它不起作用 并且我不想在下次获取或变基时保留它们 据我从对您问题的评论中了解到 您只希望这些参考
  • 如何与其他用户共享 bitbucket 存储库?

    我正在使用 Bit 存储桶 并且我想与一位朋友分享我的存储库 我用的是免费的个人账户 似乎有一个选项可以在位桶中创建团队 但它说它将把我的帐户从个人帐户转换为团队帐户 我不要那个 我如何授予其他用户访问此存储库的权限 有一个共享链接选项 如
  • 如何将一个文件存储库上传到 Gist,并保留历史记录?

    我的计算机上有一个包含单个文件的 Git 存储库coins py 我如何才能将其作为 Github 上的要点来保存历史 这其实很简单 您可以将现有历史记录移动到 Gist 存储库中 就像将其移动到任何其他存储库中一样 创建要点 只需输入一些
  • Git rebase --继续而不打开编辑器

    调用时git rebase continue在正常的变基冲突之后 编辑器 GIT EDITOR 打开并要求修改提交消息 因为提交消息可能包含前导 所以这可能会失败 export GIT EDITOR true git rebase cont

随机推荐

  • LibEvent中文帮助文档

    http blog csdn net zhouyongku article details 53431597 libevent源码分析 http blog csdn net yusiguyuan article details 182675
  • Rinetd 端口转发

    文章目录 端口转发工具 Rinetd 安装 利用 Rinetd 实现Service 负载均衡 端口转发工具 Rinetd Rinetd 重定向传输协议控制工具 可将源ip端口 数据转发至目标 ip端口 在 k8s 中用于将service服务
  • jwt实现token鉴权(nodejs koa)

    为什么需要token 在后台管理系统中 我们通常使用cookie session的方式用于鉴权 如何通过cookie session鉴权 nodejs koa 但这种方式存在着以下问题 比如cookie的容量太小 浏览器端和app端发送ht
  • 动态代理的两种方式以及区别

    JDK动态代理 利用反射机制生成一个实现代理接口的匿名类 在调用具体方法前调用InvokeHandler来处理 CGlib动态代理 利用ASM 开源的Java字节码编辑库 操作字节码 开源包 将代理对象类的class文件加载进来 通过修改其
  • Java-模板注释

    前言 好的代码规范是一个程序员的基本修炼 好的代码注释更能体现一个程序员的思维逻辑 虽然代码是用来给机器运行的 我们只要能写出能让编译器运行的代码就行了 但是如果没有好的编码规范 到项目后期 加入开发的人员逐渐增多时 每个人的编码风格都不一
  • navicat连接oracle进行数据的迁移到mysql以及遇到的问题总结

    打开navicat客户端连接oracle数据服务需要先配置oci dll文件 配置的过程为 打开navicat界面点击 工具 gt 选择 gt OCI 导入oci dll文件 注意 选择instanceclient需要跟oracle数据库的
  • python用bbp公式求圆周率_Python学习笔记

    本文为中国大学MOOC Python语言程序设计 课程学习笔记 课程主讲 嵩天老师 练习平台 Python123 参考教材 Python语言程序设计基础 一 使用公式的方法求解圆周率的值 pi 0 N 1000 for k in range
  • Ubuntu Kylin 20_10 在VMware Workstation Pro上安装

    Ubuntu Kylin 20 10 在VMware Workstation Pro上安装 文章目录 Ubuntu Kylin 20 10 在VMware Workstation Pro上安装 准备工作 在VMVMware Workstat
  • vue-cropper实战使用

    vue cropper 一个优雅的图片裁剪插件 查看演示 Demo README english 更新日志 一 安装使用 1 安装 npm 安装 npm install vue cropper 2 引入 Vue Cropper Vue2 组
  • C++打印类名+函数名的方法

    C 打印类名 函数名的方法 打log的时候经常需要将输出log时所在的类名 函数名写清楚 但是自己敲函数名和类名比较麻烦 复制粘贴的时候也会忘记修改而出错 下面介绍下如何在G GCC编译器下获得函数名和类名 如果只想获得函数名可以用C99的
  • 使用Git-bash将本地项目传到Github

    近几天复习了JavaWeb的一些基础 做了一个简单的管理系统 想放在Github上留个底 但只会用IDEA直接pull 就想着用本地的Gitbash直接pull 花了些时间能好了 现在总结下流程 1 首先在本地目录创建一个文件夹 作为版本库
  • pinia核心模块----store

    目录 一 概念 二 定义store 1 首先store目录下创建user ts文件 主要用来存放与user相关的store 2 页面中使用 一 概念 store简单来说就是数据仓库的意思 我们数据都放在store里面 当然你也可以把它理解为
  • SQL中Group By的使用

    SQL中Group By的使用 1 概述 2 原始表 3 简单Group By 4 Group By 和 Order By 5 Group By中Select指定的字段限制 6 Group By All 7 Group By与聚合函数 8
  • 操作系统(02)- 四个基本特征

    文章目录 一 操作系统的特征 1 并发 2 共享 3 虚拟 4 异步 一 操作系统的特征 操作系统的特征可以分为四类 并发 共享 虚拟 异步 其中并发和共享是最基本的特征 二者互为存在条件 后面会给出详细解释 下面详细的介绍这四种特征 1
  • 中国智能建筑行业运行状况与十四五应用前景调研报告2022版

    中国智能建筑行业运行状况与十四五应用前景调研报告2022版 修订日期 2021年12月 搜索鸿晟信合研究院查看官网更多内容 第一章 智能建筑发展概述 1 1 智能建筑的相关概念 1 1 1 智能建筑的定义 1 1 2 智能建筑的层次划分 1
  • Ubuntu安装redis5.0.0

    一 下载 sudo wget http download redis io releases redis 5 0 0 tar gz 如果慢 可以传上去 二 解压编译安装 解压后 切换目录 cd app redis 5 0 0 编译 make
  • 【C++】对数组指针的理解,例如 int (*p)[3]

    目录 简介 思考 理解 结语 简介 Hello 非常感谢您阅读海轰的文章 倘若文中有错误的地方 欢迎您指出 昵称 海轰 标签 程序猿 C 选手 学生 简介 因C语言结识编程 随后转入计算机专业 获得过国家奖学金 有幸在竞赛中拿过一些国奖 省
  • 【MYSQL】mysql1130错误与安装重置密码

    1 连接服务器 mysql u root p 2 看当前所有数据库 show databases 3 进入mysql数据库 use mysql 4 查看mysql数据库中所有的表 show tables 5 查看user表中的数据 sele
  • freeswitch编译过程以及添加odbc连接mysql

    freeswitch 编译 参考官网wiki bootstrap sh j configure prefix home make make j install make j cd sounds install make j cd moh i
  • Git的Patch功能

    本文整理编辑自 http www cnblogs com y041039 articles 2411600 html http yuxu9710108 blog 163 com blog static 2375153420101114488