如何仅为更改特定文件的提交生成/应用git补丁

时间:2013-04-11 21:33:12

标签: git git-diff git-patch

我有两个git repos,它们是彼此的分叉,我需要偶尔将提交从一个提交到另一个。

例如:

git-repo1具有以下目录结构:

repo1/project1/src

repo1/project2/src

git-repo2具有以下目录结构:

repo2/src/

我想要做的是进行一系列提交并仅为在特定子目录中更改文件的提交生成补丁(比如说repo1/project1/src),并忽略所有只在其他地方修改文件的提交。

或者,为所有提交生成补丁,但只应用补丁,如果它改变了特定目录中的文件。

我需要保留有关提交的元数据,因此使用git diff似乎不太可行。

forked git repos之间的目录结构不同。

有没有直接的方法来做到这一点?

UPDATE1

我在处理不同的目录结构方面看到了这个问题(How to apply a git patch from one repository to another?)。

但是,如果补丁说修改那些根本不存在的文件呢?我想忽略这些变化。

2 个答案:

答案 0 :(得分:9)

  

git rev-list --reverse series -- repo1/project1/src/ \
  | xargs -I@ git format-patch --stdout @^! >mystuff.patch

会将影响该子目录的系列中的提交吐出到mystuff.patch

然后,

cat >mystuff.sed <<\EOD
/^(From [0-9a-f]{40}|diff --git )/!{H;$!d}
x
/^From /b
${h;s,.*--,--,;x}
\,^diff[^\n]* [ab]/repo1/project1/src/,!{$!d;x;b}
${p;x}
EOD

sed -Ef mystuff.sed mystuff.patch >justmystuff.patch

将剥离该目录之外的所有人。您可以申请

git am justmystuff.patch

根据需要-p n --directory=new/path/to

(编辑:EOD - &gt; \ EOD,因此上面的猫不会尝试替换)

答案 1 :(得分:1)

如果两个存储库具有共同的历史记录(它们都是从同一个存储库分叉,但进化方式不同),则可以使用cherry-picking从一个分支选择性地将提交导入到另一个分支。

使用两个遥控器(两个不同的存储库)创建一个本地存储库

在repositoryA中查找触及某些文件的提交

 $ git checkout repoA/master
 $ git log sub/dir/ectory
 a34256f ...

樱桃挑选那些提交到repositoryB的分支

 git checkout repoB/master
 git cherry-pick a34256f