git - 如何将 git diff 应用于略有不同的存储库

标签 git

我使用两个 git 存储库,其中一个包含另一个的一些代码,但位于不同的路径下。

例如仓库 A 有一个目录 src/packages/my-pkg ,并且 Repo B 有一个目录 different-path/my-pkg ,并且两个目录具有(大部分)相同的内容。

我想自动化将功能/错误修复从一个复制到另一个的过程。所以如果一个文件 src/packages/my-pkg/some-component/index.js已修改,可将更改复制到different-path/my-pkg/some-component/index.js在另一个仓库中。然而,index.js存储库之间可能略有不同,因此需要容忍这一点并尽可能多地应用差异。

这是我迄今为止提出的流程:

# Get a diff containing the changes in a feature branch
cd repoA
git diff master new-feature-branch > ../feature.diff

# Convert the file paths in the diff to the other repo's structure
sed -i "" 's+src/packages/my-pkg+different-path/my-pkg+g' ../feature.diff

# Apply to the other repo
cd ../repoB
git apply --reject ../feature.diff  # --reject option tells git to apply the changes it can, and put the rest in .rej files

这在一定程度上有效,但对存储库之间的差异非常敏感。例如,当尝试将此更改从存储库 A 应用于存储库 B 时:

--- a/different-path/my-pkg/title-bar/view.js
+++ b/different-path/my-pkg/title-bar/view.js
@@ -95,6 +95,7 @@ export default class TitleBar extends Component<Props> {
                         </span>
                     </div>
                 );
+                // A new comment
             case READONLY:
                 return (
                     <Title>

如果 Repo B 中的任何上下文行已更改(例如,将 prop 添加到 <Title> ),git 将无法匹配该位置,并且差异将不适用。

我认为,如果 git 可以在 Repo A 中的文件的旧/新版本和 Repo B 中的文件之间进行 3 路 merge ,它可以更好地确定在哪里插入更改。但我不知道如何实现这一点。

有人知道如何解决这个问题吗?

(显然,理想的解决方案是将共享代码提取到可重用的模块中。但它很大,并且存在许多细小的差异,因此所涉及的工作量使其无法启动。)

最佳答案

有两种方法可以增加仍然应用不太合适的补丁的机会:

第一种形式

git apply -3 that.diff

使用 merge 机制来应用补丁并可能产生冲突,但在其他方面非常擅长应用上下文行不匹配的补丁。 git apply使用补丁中记录的 blob ID;为此,需要将生成补丁的仓库添加为远程仓库。

第二种形式

git apply -C2 that.diff

减少必须匹配的上下文行数。如果上下文不明确,这也增加了补丁应用在错误位置的危险。可以将上下文减少到零行,但如果补丁仅添加文本,则这是非常危险的,因为补丁应用程序剩下的唯一提示是行号,并且它们通常是不精确的提示。如果补丁包含已删除的行,零上下文行问题就不那么大了,因为它们确实保留为上下文。

编辑:为了解释路径名的更改,-p<n>可用于从补丁中记录的路径中剥离多个目录,以及 --directory=foo/bar可以用来替代不同的路径。这假设至少文件名保持不变。

关于git - 如何将 git diff 应用于略有不同的存储库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64798656/

相关文章:

git - 如何将未推送的提交代码移动到另一个分支?

git - 执行 ls-remote 命令期间捕获的 EGit SSH 异常

git - 禁用/更改 Visual Studio Team Services 自动解释散列号提交消息

linux - 关于设置游戏的问题! linux服务器上的应用程序

git - Git 中如何产生交叉 merge ?

Git说本地分支在远程分支后面,但事实并非如此

git - 如何使用别名访问 Jenkins 中的远程 Git 存储库?

git - git 的 merge 冲突解决是否比其他 SCM 和 merge 工具更高效?

git - 平均堆栈,Win 7,git push heroku master 结果在 sh : bower: not found error

Git 删除 git 日志中的原点/分支