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

mar*_*t1n 84 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并不关心?).我知道我可以编辑差异以应用于该特定文件,但我正在寻找一个命令解决方案.

geo*_*ock 82

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

例如:

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

cd ../second-repo
patch -p1 blue/red/hi.test ~/patch_file
Run Code Online (Sandbox Code Playgroud)

  • 啊,很好,没想到。但是,有什么方法可以使用Git命令执行此操作,以使提交数据(日期和时间,提交作者,提交消息)保持不变? (4认同)
  • 可能你可以用 `am` 或 `apply` 做一些事情,但我找不到。如果您发现自己重复了很多更改,那么使用子模块或您选择的任何语言提供的共享代码可能有更好的解决方案(例如,在 Ruby 中,您可以将重复的代码提取为 gem)。 (2认同)
  • 在 Windows 上,可以使用“git-bash”,它包含在 Windows 版 Git 中。`git-bash` 包含多个 Unix 命令,包括 `patch`。 (2认同)

小智 42

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

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

git format-patch --relative <committish> --stdout > ~/patch
Run Code Online (Sandbox Code Playgroud)

在第二个存储库中:

git am --directory blue/red/ ~/patch
Run Code Online (Sandbox Code Playgroud)

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

它也可以在git format-patch --relative <committish>没有的情况下运行--stdout,它将生成一组.patch文件.这些文件可以被直接输送到git amgit am --directory blue/red/ path/to/*.patch.

  • 这仍然依赖于文件名相同的事实,对吧? (7认同)
  • 应该注意,`--directory`选项似乎要求您指定相对于repo根目录的完整路径; 像`--directory =./`这样的东西,而chdir进入repo中的子目录是行不通的. (3认同)
  • 使用 `--3way` 有助于解决 `does not exist in index`:`git am --3way --directory (relative-path) (patch)` (2认同)

mar*_*t1n 9

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

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


oli*_*ver 5

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

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

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

cd second-repo
git am ~/00*.patch
Run Code Online (Sandbox Code Playgroud)

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

patch --directory blue/red < ~/0001-*.patch
git add -a
git am --continue
Run Code Online (Sandbox Code Playgroud)

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

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