前提:

生成patch:
git format-patch -M master
生成指定patch,0163bed3bf59ae74c36cc5138b4c24f1556d8304是commit id,-1是指从当前id开始,向下提交次数,包含此次且计数从1开始。
也就是说,我想要打出0163bed3bf59ae74c36cc5138b4c24f1556d8304当前的patch,则:
git format-patch 0163bed3bf59ae74c36cc5138b4c24f1556d8304 -1
想要打出0163bed3bf59ae74c36cc5138b4c24f1556d8304和它之前的一次提交的patch,则:
git format-patch 0163bed3bf59ae74c36cc5138b4c24f1556d8304 -2
生成diff:
git diff (id1) (id2) --binary --(path) > 目标文件路径
比如要生成frameworks/base/下的diff,保存到~/gittest/下的f_b.diff:(注意:旧的id1在前)
git diff 206b47c132a80870c06d87c69a548bbfeebecd2d b5ce3e4ebe9503e370d734cecc12482bca023fdf --binary -- frameworks/base/ > ~/gittest/f_b.diff

打入 patch / diff:
git apply xxx.patch
git apply xxx.diff
检查 patch / diff:
git apply --check xxx.patch
git apply --check xxx.diff
若git和需要打patch的文件不在一个目录:(git在framework下,patch要打入frameworks/base/下)
git apply --check --directory=base/ xxx.patch
git apply --directory=base/ xxx.patch
** git am 后面会说到,以及生产patch和打入patch的一些命令参数**

  1. 我们创建一个文件夹,git init一下,模拟diff / patch源环境
$ mkdir gittest
$ git init
  1. 然后创建一个空文件 test,然后首次提交
$ touch test
$ git add .
$ git commit -m "test init"
  1. 在里面加入11111,add,commit(add 11111)一次;
    在里面加入22222,add,commit(add 22222)一次;
    ...
    在里面加入55555,add,commit(add 55555)一次;
    一共提交5次,可以看到提交了5次。

gitk

生成patch / diff 文件(我们单独建一个文件夹来存patch和diff --> ~/patch/patch/):

在工作中,二者选一个就可以,看自己的需求。
patch相对于diff,多了提交记录,也就是说可以原封不动的把他人commit内容写上去,但是操作比diff麻烦一些

  • 生成patch:
    我们记录一下最新的commit id : 21ebfb1ef6a0a9b56d46036c036e8377b56b2da5,有5次提交。
$ git format-patch 21ebfb1ef6a0a9b56d46036c036e8377b56b2da5 -5

git patch

生成了包含当前id和之前的4个id的patch,一共5个,命名也有规律000X+commit的内容.patch
我们把这5个移到~/patch/patch/中。

  • 生成diff:
    我们记录要生成diff的区间,!!包上不包下!!

就是说我要生成 11111~55555的diff
id1 是 test init的id;1cf68afcf3e089a349c8ee534dc3ff44d11a6624
id2是add 55555的id。21ebfb1ef6a0a9b56d46036c036e8377b56b2da5

$ git diff 1cf68afcf3e089a349c8ee534dc3ff44d11a6624 21ebfb1ef6a0a9b56d46036c036e8377b56b2da5 --binary -- . > ~/patch/patch/test.diff

diff 多次提交可以是一个文件,但是patch不行,因为它里面有commit记录!

打 patch / diff 补丁(无冲突):

我们在当前目录创建一个需要打补丁的文件夹(gittest1),里面也有一个空的test文件。
然后我们把patch/diff打入gittest1/test。
执行最开始的1、2即可,改一下文件夹名称就ok

gittest1

  • 打patch(不包含commit内容)

    1. 检查patch是否可用,没显示文字,就说明可用,且无冲突;
      git apply --check ~/patch/patch/0001-add-11111.patch
      一般检查一个就可以。
    2. 打入patch,可以批量,也可以单个。
      git apply ~/patch/patch/*.patch
    3. 肯定会成功,因为没有冲突。我们查看一下
      git diff

git diff

5个patch都打上去了,接着就可以 git add / commit提交了。但是这样没有commit记录。

  • 打patch(包含commit内容 git am git checkout . 撤销一下

    1. 检查patch是否可用,没显示文字,就说明可用,且无冲突;
      git apply --check ~/patch/patch/0001-add-11111.patch
    2. 打入patch,可以批量,也可以单个。
      ** git am ~/patch/patch/*.patch **
    3. 肯定会成功,因为没有冲突。我们查看一下

      gitk

gitk

我们发现已经自动commit,不用add、commit,可以直接push。

  • **打diff ** git reset --hard 4c6eb312e94214a5f34fa3f119382ace647b1b3c 撤销一下

    1. 检查diff是否可用,没显示文字,就说明可用,且无冲突;
      git apply --check ~/patch/patch/test.diff
    2. 打入diff;
      git apply ~/patch/patch/test.diff
    3. 肯定会成功,因为没有冲突。我们查看一下
      git diff

git diff

接着就可以 git add / commit提交了。但是这样没有commit记录。

打 patch / diff 补丁(有冲突):

我们还原gittest1/test的初始状态,然后修改一下test文件,写入00000,,然后add、commit。

add 00000

  • 打patch

    1. 检查patch是否可用,没显示文字,就说明可用,且无冲突;
      git apply --check ~/patch/patch/0001-add-11111.patch
error: 打补丁失败:test:0
error: test:补丁未应用

说明是可以用,但是有冲突。

  1. 打入patch,可以批量,也可以单个。

因为在check的时候知道已经有冲突了,就不好用apply来打patch,如果一定要用的话,建议一个一个apply,所以很麻烦,不如用diff。
在这里要用到 git am

git am ~/patch/patch/*.patch

正应用:add 11111
error: 打补丁失败:test:0
error: test:补丁未应用
补丁失败于 0001 add 11111
失败的补丁文件副本位于:/home/deshui/****/log/gittest1/.git/rebase-apply/patch
当您解决了此问题后,执行 "git am --continue"。
如果您想跳过此补丁,则执行 "git am --skip"。
要恢复原分支并停止打补丁,执行 "git am --abort"。

这行话告诉你,patch冲突了,但是有三个选项 git am --continuegit am --skipgit am --abort
这时候不要动!不要动!不要动!
1. 解决冲突。
> 我们 gedit test,在里面手动加入11111,因为我们加入了00000,导致错行,所以接下来的4个patch都会有冲突。
2. 提交记录。
git add test
git am --continue

正应用:add 11111
正应用:add 22222
error: 打补丁失败:test:1
error: test:补丁未应用
补丁失败于 0002 add 22222
失败的补丁文件副本位于:~/gittest1/.git/rebase-apply/patch
当您解决了此问题后,执行 "git am --continue"。
如果您想跳过此补丁,则执行 "git am --skip"。
要恢复原分支并停止打补丁,执行 "git am --abort"。

我们gitk一下,发现已经commit已经有add 11111的记录了!
** 同上操作,一直修改到44444 **
git add test
git am --continue

正应用:add 44444
正应用:add 55555

这样就完整的解决冲突,保留commit了。

git am finish

  • **打diff ** git reset --hard 0050cda7f22df985d79b9b98da9bfc282ea10ef1 撤销到add 00000

    1. 检查diff是否可用,肯定有冲突。
      git apply --check ~/patch/patch/test.diff
error: 打补丁失败:test:0
error: test:补丁未应用
  1. 打入diff;
    git apply --reject --ignore-whitespace ~/patch/patch/test.diff 2>&1 | tee ~/patch/patch/testdiff.log
这里reject是生成一个.rej的文件,是一个差异文件。
ignore-whitespace是忽略多余的空格。
2>&1是值错误信息tee 错误信息输出到控制台
~/patch/patch/testdiff.log 错误信息保存在这个文件里
*********输出log**********
检查补丁 test...
error: 当查询:
error: 打补丁失败:test:0
应用 test 个补丁,其中 1 个被拒绝...
拒绝第 #1 个片段。
*********输出log**********
  1. 这时候我们发现,文件夹多了一个test.rej的文件,打开它。
diff a/test b/test  (rejected hunks)
@@ -0,0 +1,5 @@
+11111
+22222
+33333
+44444
+55555

这个告诉我们,要在test中加入的信息,我们打开test补上就可以了。手动!
然后add / commit 就可以了。

END

作者:yotods
链接:https://www.jianshu.com/p/e5d801b936b6
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

git apply、git am打补丁.diff 和 .patch相关推荐

  1. Git补丁简单用法介绍(打补丁.diff 和 .patch 和 git apply、git am应用)

    打补丁.diff 和 .patch 和 git apply.git am应用 生成patch git format-patch -M master 生成指定patch,afc425592dc7dde9 ...

  2. git am, git apply, git format-patch,git diff 用法

    传统的patch可能会丢失一些信息,git 提供两种打patch方法, git diff , git format-patch,两种的区别在于前者打出来的patch中不带有提交信息, 后者打出来的pa ...

  3. Git 补丁— diff 和 patch 使用详解

    Git 补丁- diff 和 patch 使用详解 1. diff 和 patch 的区别 2. 生成patch 2.1 git diff 3. git format-patch 3. 应用patch ...

  4. Linux的diff和git diff生成patch/打patch

    一.Linux的diff生成patch和打patch 1.单个文件生成patch #  diff -up xxx/a.txt yyy/b.txt  > mypatch_1 参数解释: -u:显示 ...

  5. git apply 打补丁

    一:生成patch 和打patch 有这样的 目录层次 x/xx/xxx/xxx/test.c 我的当前位置是在 x/  下 ,执行   git diff> test.patch 在test.p ...

  6. Git diff 生成patch文件

    通过git diff 命令生成patch文件 1.还未提交的修改 命令 :git diff > commit.patch 2.已提交的修改 先用git log命令查看commit id soft ...

  7. git diff生成patch用法

    # git diff ./ > test.patch //生成patch # patch -p1 < test.patch //打patch # git apply test.patch ...

  8. Git 常用操作(5)- git clone/git checkout -b/git diff/git push/git pull

    1. git clone--获取远程仓库 当 git fetch 命令从服务器上抓取本地没有的数据时,它并不会修改工作目录中的内容.它只会获取数据然后 让你自己合并. 然而,有一个命令叫作 git p ...

  9. 【Git】Git 基础命令 ( 添加暂存文件 git add | 提交文件至版本库 git commit | 查看版本库状态 git status | 查询文件修改 git diff )

    文章目录 一.添加暂存文件 git add 二.提交文件至版本库 git commit 三.查看版本库状态 git status 四.查询文件修改 git diff 一.添加暂存文件 git add ...

最新文章

  1. 独家 | 一文读懂如何用深度学习实现网络安全
  2. Linux 部署ftp报530 错误解决方案
  3. python---pandas.merge使用
  4. android 中的组合控件的设计
  5. 求两个点的欧氏距离_数据智能系列(五)| 距离的秘密
  6. 软路由VS高性能路由,该怎么选择?
  7. 9 万条弹幕告诉你,《乘风破浪的姐姐》里谁才是真正的C位?
  8. Linux 内核版本命名
  9. struts2入门操作
  10. 【如何制作电子书】云展网教程 | 编辑纯文本阅读页面功能(有利于SEO收录)
  11. python异步请求aiohttp_利用aiohttp制作异步爬虫
  12. 关于FAST迅捷FWR310无线路由器桥接移动光猫吉比特网关的问题
  13. NBA球队实力聚类分析
  14. 怎么在计算机上面掉出CMD,电脑没有cmd怎么办
  15. (Neighbourhood Components Analysis) NCA 近邻成分分析的学习
  16. docker学习(十三)docker安装dejavu
  17. IP地址和物理地址的区别和联系
  18. outlook使用笔记
  19. Vue.config.silent = true
  20. 应用回归分析之岭回归(Ridge Regression,RR)

热门文章

  1. android 中edittext控件 输入错误后焦点不变_常用基本控件测试用例(二)
  2. 使用 Servlet 读取表单数据
  3. jdk1.8hashmap为什么对hash进行了一次扰动处理
  4. 012_union操作符
  5. php写一个轻量级的容器,PHP写的一个轻量级的DI容器类
  6. JavaWeb:上传下载文件
  7. linux 控制台输入命令无效_在控制台输入什么命令都提示commandnotfound原因是什么?suselinux...
  8. python多列填充缺点_在Python中比较多列中的值并在另一列中添加新值
  9. 实时流处理系统容错机制(一):综述
  10. 怎么实现事务_你可能知道事务的四大特性,但是不一定知道“事务的实现原理”...