活用 git apply 合入 patch 补丁
前言
在还是 git 新手时,经常会遇到一个比较尴尬的处境,git 仓库经常会被自己给玩坏了,虽然没到山穷水尽的地步,但也恨不得反手给自己一巴掌
冲动是魔鬼,我们还是要解决问题是吧~ 当然重置方法有很多了,而本文也将为你提供一个新的解题思路。
使用方法
认识 GIT DIFF
git diff
命令我们用得太多了,默认返回工作区和暂存区的文件详细差异。
什么叫详细差异?
工作区与暂存区的每一行数据变更都能够在这个命令中看到,多用于提交代码前的再次审阅,避免出错。
当然,git diff
不仅能提供工作区和暂存区的文件对比,可以说能提供任意文件差异,如下:
- git diff filepath 工作区与暂存区某文件对比
- git diff HEAD filepath 工作区与 HEAD(当前工作分支) 比较,HEAD 也可替换为任意一次 commitID
- git diff --staged 或 --cached filepath 暂存区与 HEAD 比较
- git diff branchName filepath 当前分支的文件与 branchName 分支的文件进行比较
- git diff commitId filepath 与某一次提交进行比较
- git diff commitID1 commitID2 两次 commit 提交间文件对比
然后就在想,若能根据这些信息恢复文件,岂不妙哉? 当然,我肯定不是第一个这么聪明的人,git 早就提供了相应的命令,且向下看。
生成 PATCH 补丁
patch 补丁即为根据 git diff
生成的文本内容文件,最简单的生成方法为 git diff > test.patch
。
其中 test。patch 文件记录了你本次的所有修改,若由于你忘记 git stash
,或者强行 git reset --hard HEAD
,这个文件将是最后的救命稻草。
GIT APPLY
基本使用方法为 git apply patch
,根据 patch 文件内的信息,在现有文件中添加或删除内容。
这里添加或删除的操作,和手动修改并无多大区别,即修改内容还是在工作区,不会提交到暂存区。之后的操作,就任君发挥了。
示例
我们预先生成一个文本文件 text,其内容如下并提交 commit,工作区,暂存区皆无内容:
origin context line1 origin context line2
将其修改为:
origin context line1 origin context add line
使用 git diff > test.patch
生成 patch 补丁,当然你可以把这个文件放至任何目录下,打开其内容如下:
diff --git a/test b/test index ce2f4b3..ae27ef5 100644 --- a/test +++ b/test @@ -1,2 +1,3 @@ origin context line1 -origin context line2 +origin context +add line
然后我们使用 git checkout .
将文件重置为最初状态,text 文件恢复为
origin context line1 origin context line2
使用 git apply test.patch
,将变更内容再次写入,查看 text 文件,又变回了
origin context line1 origin context add line
示例为求简洁特别简单,也可以使用上文 git diff
保存各种对比内容,从而恢复不同的文件内容。
另外需要多说一句的是,git apply 是一个事务性操作的命令,若有冲突修改会被全部放弃,加参数 --reject 即可。
应用
前面说了那么多,会有人反驳了,这里我用其它命令诸如 git stash
,git rebase
比你这个强大多了,这条命令很鸡肋没什么用啊~
下面,用两个鲜明的实例,证明这一命令的方便之处
使用 patch 补丁下载 MR 内容
这个方法来源于部门同事,这是个有趣的人,经常会给我带来各种奇思妙想,这里我也就借花献佛了。(为了获取这个 idea 能够撰文,偷偷塞给他 10 块钱获取了授权)
经常使用 gitlab 的同学大家都知道,当他人提交 MR 到主库时,你只能做代码审阅,无法在 MR 未合并前直接下载更改后的文件内容验证代码是否正确。
当文件更改内容过多,或者是前端项目你特别想看看代码运行起来的页面效果时,备感无力。
当然,若是仅凭代码就能脑补其在浏览器中的显示效果的人,当我没说……
这里关键的地方在于,如何获取这个 MR 与主库现有文件的对比 patch 补丁,然而 gitlab 早已看透了你的一切小心思~
点击 Email Patches,就可以直接下载 patch 文件,然后通过上文的 git apply
直接将修改内容下载至本地,然后愉快的 yarn start
或者其它命令跑起你的项目查看效果啦,so good!
多人协作
程序员的工作大家都是知道的,周末也会偶尔加个班修个紧急 bug 啥的,若你正放假坐着火车上,吃着火锅唱着歌,一个电话打过来,紧急 bug,速度修复,真是要了个命呐~
而这时候屋漏偏逢连阴雨,VPN 也连不上公司内网,啥倒霉事全让你占尽了,这可咋整?!
要么打电话请同事帮你改,二十八个文件都需要改两三句代码,一个一个说吧…… 半天过去了
或者整个修改的文件全发过去,信号差传得又慢,还不如打电话说,可急死我了……
这时候,废什么话,git diff 打个 patch 补丁传过去呗,一个 bug 修改的内容通常极少,不到 1KB……
到这里也看出来了,patch 补丁最大的优势在于内容小,能够只记录你的修改内容而非全文件,通过 git apply
简直不能更好用~
补充
这里还有两个类似命令:git format-patch commitA commitB
和 git am
。
前者会将一次 commit 的所有信息也带上,如作者,时间,节点描述等,再配合后者将 patch 内容应用到当前分支。与 git apply
的不同点是,这里补丁不再只在工作区,你会发现当前分支多 commitA 和 commitB 之间的提交记录。具体细节,就还请大家自行去探索吧~