我有两个存储库。在一个方面,我对文件./hello.test
进行了更改。我提交更改并使用git format-patch -1 HEAD
从该提交创建补丁。现在,我有一个第二个存储库,其中包含一个与hello.test具有相同内容的文件,但是以不同的名称放在另一个目录中:./blue/red/hi.test
。如何将上述补丁应用于hi.test
文件?我试过git am --directory='blue/red' < patch_file
,但当然抱怨文件名称不一样(我认为Git并不关心?)。我知道我可以编辑差异以应用于该特定文件,但我正在寻找命令解决方案。
答案 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~1
与A
之间的差异应用于文件B
。
打开三向合并工具,例如Beyond Compare,左侧面板的路径为A
,中间面板为共同的祖先,因此路径为A~1
,右侧面板的路径为{ {1}}。然后,下方面板显示将B
与A~1
之间的差异应用于文件A
的结果。
下图说明了这个想法。
答案 5 :(得分:0)
仅供参考:最近,我在尝试从Github下载补丁并将其应用到本地文件时遇到了问题(这是在新位置的“替代”)。
git am
不会应用补丁,因为文件“不在索引中”或“脏”。但是,我发现简单的patch
命令可以应用补丁。它的确提示我要修补的文件的名称。
反正做好了工作...