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(-)


[1]http://marc.info/?l=git&m=129058163119515&w=2