在两个目录之间创建 git 差异并将补丁应用到目录

Create git diff between two directories and apply patch to directory

我的目标是在两个文件夹之间创建差异,以便可以轻松应用文件更改。

我当前的命令:

git diff --no-index --binary 20140902/ 20141227/ > 01.diff

每个文件的差异如下所示:

diff --git a/20140902/Documents/sheet.xlsx b/20141227/Documents/sheet.xlsx
index 3d0d2c8acd53eb068ac5d390048e7f624dd012b9..fe5a87dd3b99874746e137d752fa6b151544c0ca 100644
GIT binary patch
delta 11480
...

如何将此差异应用到与 20140902 具有相同内容的文件夹 current(或者如果需要,应用到名为 20140902 的文件夹)?

当我尝试时

cd current/
git apply ../01.diff

我明白了

error: git diff header lacks filename information when removing 1 leading pathname component (line 3)

第 3 行是“GIT 二进制补丁”行。也许 diff 文件中的行应该看起来像

diff --git a/Documents/sheet.xlsx b/Documents/sheet.xlsx

?

TL;DR: 尝试 git apply -p2 ....

描述

正确的设置对我来说从你的帖子中不是很清楚,所以我会展示我的设置:

$ mkdir tpatch
$ cd tpatch
$ mkdir -p 20140902/Documents 20141227/Documents
$ printf 'binary[=10=]stuff' > 20140902/Documents/foo
$ printf 'different[=10=]binary' > 20141227/Documents/foo
$ git diff --no-index --binary 20140902/ 20141227/ > 01.diff

(由于上面 printf 输出中的 NUL,生成的补丁确实是 GIT binary patch,尽管我有两个 literal 而不是 delta。 )

接下来,我在目录 current 中创建了一个存储库。如果您的存储库处于不同级别,您可能需要不同的 -p 值:

$ mkdir current; cd current; git init
Initialized empty Git repository in .../tmp/tpatch/current/.git/
$ cp -r ../20140902/Documents .
$ ls
Documents
$ git add . && git commit -m initial
[master (root-commit) ee60bbe] initial
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 Documents/foo

请注意,在这一点上我得到了与普通 git apply 相同的错误,因为从 diff 中剥离 a/ 留下 Git 与 20140902/Documents/foo,而不是 Documents/foo:

$ git apply ../01.diff 
error: git diff header lacks filename information when removing 1 leading pathname component (line 3)

但是,通过使用 -p2,我们告诉 Git 从路径中删除 两个 组件 (a/20140902/),之后文件名 Documents/foo 与存储库和工作树中的文件名匹配:

$ git apply -p2 ../01.diff
$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   Documents/foo

no changes added to commit (use "git add" and/or "git commit -a")

如果你有更复杂的情况,你可能需要首先使用 git diff 命令中的 --src-prefix and/or --dst-prefix 选项,但可能-p2 就可以了。