0%

使用diff和git apply跨仓库合并代码

需要在两个拥有相同代码,但是不是同一个仓库之间合并代码,直接使用 git diffgit apply 不能成功。
发现可以使用 diff 来生成 UNIX Patch,然后使用 git apply进行合并,记录如下:

diff生成patch

可以使用 diff 来生成标准 unix patch

diff [OPTION]... from-files to-files

from-files + patch = to-files

用到的相关选型:

  • -r 递归
  • -u 以统一格式创建补丁文件
  • -N 确保补丁文件将正确地处理已经创建或删除文件的情况
diff -ruN SOURCE-DIR PATCH-DIR > 00.patch

patch应用patch

patch [options] [originalfile [patchfile]]
patch -pnum <patchfile>

简单的说,patch就是利用diff制作的补丁来实现源文件(夹)和目的文件(夹)的转换。
这样说就意味着你可以有源文件(夹)――>目的文件(夹),也可以目的文件(夹)――>源文件(夹)。下面介绍几个最常用选项:

  • -p0 选项要从当前目录查找目的文件(夹)
  • -p1 选项要忽略掉第一层目录,从当前目录开始查找

在这里以实例说明:

--- old/modules/pcitable       Mon Sep 27 11:03:56 1999
+++ new/modules/pcitable       Tue Dec 19 20:05:41 2000

如果使用参数-p0,那就表示从当前目录找一个叫做old的文件夹,在它下面寻找modules下的pcitable文件来执行patch操作。
如果使用参数-p1, 那就表示忽略第一层目录(即不管old),从当前目录寻找modules的文件夹,在它下面找pcitable。这样的前提是当前目 录必须为modules所在的目录。而diff补丁文件则可以在任意位置,只要指明了diff补丁文件的路径就可以了。当然,可以用相对路径,也可以用绝 对路径。不过我一般习惯用相对路径。

  • -E 选项说明如果发现了空文件,那么就删除它
  • -R 选项说明在补丁文件中的“新”文件和“旧”文件现在要调换过来了(实际上就是给新版本打补丁,让它变成老版本)

diff 和 patch 使用流程

单个文件

diff –uN from-file to-file > to-file.patch
patch –p0 < to-file.patch
patch –RE –p0 < to-file.patch

目录

diff –uNr from-docu to-docu >to-docu.patch
patch –p1 < to-docu.patch
patch –R –p1 <to-docu.patch

git相关补丁

git用来生成patch的命令:

git format-patch -M v1.0/v1.0

git用来使用补丁的命令

git am --whitespace=fix 00.patch
git apply --stat 00.patch
git apply --check 00.patch
git apply 00.patch

其中 git apply 可以使用 diff 生成的patch,需要注意的是:
git apply --check 会对 patch 路径进行检查,如果路径不对就会导致找不到相应的文件,patch失败。

git apply对目标文件的查找是从 .git 文件夹所有位置开始计算的。
目标文件使用从 .git开始的相对路径。

脚本如下:

#!/bin/bash
# $1 原始基线版本
# $2 打过patch之后的版本
# $3 patch名字

SOURCE=$1
PATCH=$2
NAME=$3

echo $SOURCE
echo $PATCH
diff -ru $SOURCE $PATCH > $NAME

sed -i 's/+++ /+++ platform\//g' $NAME