38.2 对非Git版本库中二进制文件变更的支持
不在Git版本库中的文件和目录可以比较生成Git格式的补丁文件吗,以及可以执行应用补丁的操作吗?
是的,Git的diff命令和apply命令支持对非Git版本库/工作区进行的操作。但是1.7.3以前版本的Git的git apply命令有一个Bug,这个Bug导致目前的git apply命令只能应用patch level(补丁文件前缀级别)为1的补丁。我已经将改正这个Bug的补丁文件提交到了Git开发列表中[1],但有其他人先于我修正了这个Bug。不管最终的修正方法如何,在新版本的Git中,这个问题应该已经解决。
下面的示例将演示如何对非Git版本库使用git diff和git patch命令。首先准备两个目录,一个为hello-1.0目录,在其中创建一个文本文件及一个二进制文件。
$mkdir hello-1.0
$echo hello>hello-1.0/readme.txt
$dd if=/bin/ls of=hello-1.0/binary.dat count=1 bs=32
记录了1+0的读入
记录了1+0的写出
32字节(32 B)已复制,0.0001026秒,312 kB/秒
另外一个hello-2.0目录,其中的文本文件和二进制文件都有所更改。
$mkdir hello-2.0
$printf "hello\nworld\n">hello-2.0/readme.txt
$dd if=/bin/ls of=hello-2.0/binary.dat count=1 bs=64
记录了1+0的读入
记录了1+0的写出
64字节(64 B)已复制,0.0001022秒,626 kB/秒
然后执行git diff命令。命令中的—no-index参数对于不在版本库中的目录/文件进行比较时可以省略。其中还用了—no-prefix参数,这样就可以生成前缀级别(patch level)为1的补丁文件。
$git diff—no-index—binary—no-prefix\
hello-1.0 hello-2.0>patch.txt
$cat patch.txt
diff—git hello-1.0/binary.dat hello-2.0/binary.dat
index
dc2e37f81e0fa88308bec48cd5195b6542e61a20..bf948689934caf2d874ff8168cb716fbc2a
127c3 100644
GIT binary patch
delta 37
hcmY#zn4qBGzyJX+<}pH93=9qo77QFfQiegA0RUZd1MdI;
delta 4
LcmZ=zn4kav0;B;E
diff—git hello-1.0/readme.txt hello-2.0/readme.txt
index ce01362..94954ab 100644
—-hello-1.0/readme.txt
+++hello-2.0/readme.txt
@@-1+1,2@@
hello
+world
进入到hello-1.0目录,执行git apply应用补丁,即使hello-1.0不是一个Git库。
$cd hello-1.0
$git apply../patch.txt
会惊喜地发现hello-1.0应用补丁后,已经变得和hello-2.0一样了。
$git diff—stat…/hello-2.0
命令git apply也支持反向应用补丁。反向应用补丁后,hello-1.0中的文件被还原,和hello-2.0比较又可以看到差异了。
$git apply-R../patch.txt
$git diff—stat…/hello-2.0
{.=>../hello-2.0}/binary.dat|Bin 32->64 bytes
{.=>../h e l l o-2.0}/read me.txt|1+
2 files changed,1 insertions(+),0 deletions(-)