122

我有两个存储库。一方面,我对文件进行了更改./hello.test。我提交更改并使用git format-patch -1 HEAD. 现在,我有第二个存储库,其中包含一个与 hello.test 内容相同但以不同名称放置在不同目录中的文件:./blue/red/hi.test. 如何将上述补丁应用于hi.test文件?我试过git am --directory='blue/red' < patch_file了,但这当然抱怨文件的名称不同(我认为 Git 不在乎?)。我知道我可能可以编辑差异以应用于该特定文件,但我正在寻找命令解决方案。

4

6 回答 6

123

您可以使用该实用程序创建补丁git diff,然后使用该patch实用程序应用它,该实用程序允许您指定要将差异应用到的文件。

例如:

cd first-repo
git diff HEAD^ -- hello.test > ~/patch_file

cd ../second-repo
patch -p1 blue/red/hi.test ~/patch_file
于 2013-05-13T16:38:33.317 回答
68

有一个简单的解决方案,不涉及手动补丁编辑或外部脚本。

在第一个存储库中(这也可能导出一系列提交,-1如果您只想选择一个提交,请使用):

git format-patch --relative <committish> --stdout > ~/patch

在第二个存储库中:

git am --directory blue/red/ ~/patch

另一个解决方案不是使用--relativein ,而是使用option in从补丁路径中删除目录,如对类似问题的回答中所述git format-patch-p<n>git amn

也可以在git format-patch --relative <committish>没有 的情况下运行--stdout,它会生成一组.patch文件。然后可以将这些文件直接提供给git amwith git am --directory blue/red/ path/to/*.patch

于 2015-04-27T06:36:07.690 回答
12

使用执行此操作的脚本回答我自己的问题:https ://github.com/mprpic/apply-patch-to-file

它不是手动修改补丁文件,而是提示用户输入目标文件,修改补丁,并将其应用于您当前所在的存储库。

于 2013-05-17T11:52:07.640 回答
5

基于@georgebrock 的答案,这是我使用的解决方案:

首先,像往常一样创建补丁文件(例如。git format-patch commitA..commitB)。

然后确保您的目标存储库是干净的(应该没有更改或未跟踪的文件)并应用如下补丁:

cd second-repo
git am ~/00*.patch

对于每个补丁文件,您都会收到类似“错误:索引中不存在 XYZ”的错误。您现在可以手动应用此补丁文件:

patch --directory blue/red < ~/0001-*.patch
git add -a
git am --continue

您必须为每个补丁文件执行这三个步骤。

这将保留原始提交消息等,而无需任何特殊git format-patch命令或编辑补丁文件。

于 2018-10-02T11:52:01.510 回答
2

我了解这两个文件在您的情况下完全相同,因此补丁很可能会成功。

但是,如果您想将补丁应用于相似但不完全相同的文件,或者您想要进行交互式补丁,您将使用三向合并。

假设您修改了 File A,我们将其表示A~1为以前的版本,并且您希望将 to 之间的差异A~1应用于AFile B

打开一个三向合并工具,比如Beyond Compare,左边面板的路径是A,中间面板是共同祖先所以路径是A~1,右边面板的路径是B。然后,下方面板显示了将 to 之间的差异A~1应用于AFile的结果B

下图说明了这个想法。

在此处输入图像描述

于 2018-03-12T22:02:25.840 回答
0

仅供参考:我最近在尝试从 Github 下载补丁并将其应用到本地文件时遇到问题(这是在新位置的“覆盖”)。

git am也不会应用补丁,因为文件“不在索引中”或“脏”。但是,我发现简单的patch命令可以应用补丁。它确实提示我输入要修补的文件的名称。

反正任务完成了...

于 2020-03-17T21:03:22.883 回答