gpt4 book ai didi

git - 跨具有不同提交历史的存储库应用补丁

转载 作者:行者123 更新时间:2023-12-04 17:33:14 26 4
gpt4 key购买 nike

假设我有两个相似但提交历史不同的存储库 A 和 B。

一个例子可能是两个 Python Flask 应用程序,或者两个 Ruby on Rails 应用程序,它们共享很多相似的文件但并不完全相同。

我对存储库 A 进行了更改,我也想将其应用于存储库 B。将其应用于存储库 B 时可能会出现一些冲突,但没关系,我想看看它们是什么并完成他们。

我尝试了以下从 repo A 生成补丁

> cd ~/git/repoA/
> git format-patch HEAD~
0001-My-Example-Commit.patch
> mv 0001-My-Example-Commit.patch ~/git/repoB

然后我尝试将补丁应用到 repo B

> cd ~/git/repoB
> git am 0001-My-Example-Commit.patch
Applying: My Example Commit
error: patch failed: Gemfile:20
error: Gemfile: patch does not apply
error: patch failed: Gemfile.lock:125
error: Gemfile.lock: patch does not apply
error: patch failed: app/assets/stylesheets/application.scss:29
error: app/assets/stylesheets/application.scss: patch does not apply
....
....
error: patch failed: spec/views/application/_mobile_navigation.html.erb_spec.rb:44
error: spec/views/application/_mobile_navigation.html.erb_spec.rb: patch does not apply
Patch failed at 0001 Using Devise for authentication
hint: Use 'git am --show-current-patch' to see the failed patch
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".

如图所示,它会导致一些错误/冲突。没关系,我将尝试查看冲突是什么并修复它们,就像我在常规 merge 中所做的那样:

git status
On branch test-git-apply
You are in the middle of an am session.
(fix conflicts and then run "git am --continue")
(use "git am --skip" to skip this patch)
(use "git am --abort" to restore the original branch)

nothing to commit, working tree clean

Git 甚至不将更改应用为差异,因此没有差异/修改的文件,我什至看不到冲突是什么或尝试修复它们

有没有办法强制 git 显示冲突?

谢谢!

编辑:

我知道 --directory 选项存在,但我认为它不适用于此处,因为我的补丁文件已经相对于同一根目录生成。例如

diff --git a/Gemfile b/Gemfile
index c970c34..ffc812d 100644
--- a/Gemfile
+++ b/Gemfile
@@ -20,12 +20,17 @@ gem "webpacker", "~> 3.5", ">= 3.5.5"
#
gem "bcrypt", "~> 3.1", ">= 3.1.10"
gem "cancancan", "~> 3.0"
....

最佳答案

没有冲突1 补丁根本无法应用。例如,补丁可能会说:第 87 行显示为“foo”。在随后的第 88 行,将“bar”更改为“baz”。第 89 行显示为“quux”。 但是您的第 87 行到第 89 行没有显示为“foo”、“bar”和“quux”,并且附近也没有包含该序列的行。由程序员决定如何处理补丁。

hint: Use 'git am --show-current-patch' to see the failed patch

所以,使用它。阅读补丁。检查您的文件并决定如何处理此补丁。


1这里不能有冲突,因为补丁本身并不代表对同一行的两组不同更改。当你有两个 diff 时就会发生冲突:一个说在第 88 行将 bar 更改为 baz(这是可能的),另一个说在第 88 行将 bar 更改为 rab(这也是可能的) .这两个变化是冲突的。

一个补丁只提供一个改变。它要么适用,要么不适用。


修补的替代方法

这里有两个备选方案。从低效到高效的顺序:

  • 确保 repo A 中的补丁是由 git format-patch --full-index 生成的。使用git am时,使用git am -3(或将am.threeWay配置为true)。这样,A 上的差异将包含文件父版本的完整 blob 哈希。如果那个 blob——文件的父版本——在 repo B 中可用,Git 将能够使用 blob-hash-and-patch 来重建真正 merge 所需的三个输入:一个公共(public)基础版本和两个修改过的版本来自基础版本。

  • 或者,在存储库 B 中使用 git remote add 来添加对存储库 A 的直接访问。选择一个远程名称,它会在以后提醒你这是干什么的(或者立即删除远程之后)。然后使用此远程名称运行 git fetch 将 repo A 中的提交带到 repo B,以便所有提交都在 B 中本地可用。现在,而不是 git format-patch git am,你可以运行:

    git cherry-pick <hash>

    对于有问题的提交。 Git 现在将进行完整的三向 merge ,使用来自 repo A 的两个提交作为 merge 基础和他们的更改:

    git diff <parent of hash> <hash>   # what they changed

    和您当前的提交作为您的更改:

    git diff <parent of hash> HEAD     # what we changed

    并将它们结合起来,并适本地进行冲突。这里的第二个 diff 命令是“what we changed”或者 merge 的 --ours 部分;这里的第一个 diff 命令是“他们改变了什么”,因此是 merge 的 --theirs 部分。

请注意,git am -3 或设置 am.threeWay 只是一种尝试完全 merge 的方法,希望:

index a1539a7ce682f10a5aff3d1fee4e86530e058c89..98f88a28d3227c436ecf1765f75b7f4e8e336834 100755

提供出现在您的存储库中的哈希 ID。执行 git fetch 实际上 获取 具有该哈希 ID 的 blob,如果您还没有它的话,那么就不需要单纯的希望和愿望。

关于git - 跨具有不同提交历史的存储库应用补丁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57795704/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com