如何将Git补丁应用于具有不同名称和路径的文件?

时间:2013-05-13 15:58:23

标签: git filenames patch git-patch git-am

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

6 个答案:

答案 0 :(得分:74)

您可以使用git diff创建补丁,然后使用patch实用程序应用它,这样您就可以指定要应用差异的文件。

例如:

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

cd ../second-repo
patch -p1 blue/red/hi.test ~/patch_file

答案 1 :(得分:35)

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

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

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

在第二个存储库中:

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

不是在--relative中使用git format-patch,而是在-p<n>中使用git am选项从补丁路径中删除n目录,如answer to a similar question中所述。

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

答案 2 :(得分:8)

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

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

答案 3 :(得分:2)

以@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命令或编辑补丁文件。

答案 4 :(得分:0)

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

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

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

打开三向合并工具,例如Beyond Compare,左侧面板的路径为A,中间面板为共同的祖先,因此路径为A~1,右侧面板的路径为{ {1}}。然后,下方面板显示将BA~1之间的差异应用于文件A的结果。

下图说明了这个想法。

enter image description here

答案 5 :(得分:0)

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

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

反正做好了工作...