假设我有两个存储库A和B相似,但是提交历史不同。
示例可能是两个Python Flask应用程序,或者两个共享相似文件的 lot 但并不完全相同的Ruby on Rails应用程序。
我对存储库A进行了更改,我想也将其应用于存储库B。将其应用于B可能会有一些冲突,但是没关系,我想看看它们是什么并通过他们。
我尝试了以下操作,从存储库A生成补丁
> cd ~/git/repoA/
> git format-patch HEAD~
0001-My-Example-Commit.patch
> mv 0001-My-Example-Commit.patch ~/git/repoB
然后我尝试将补丁应用于回购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".
如图所示,它导致多个错误/冲突。很好,我将尝试看看冲突是什么并解决它们,就像我在常规合并中所做的一样:
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"
....
答案 0 :(得分:1)
没有任何冲突。 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 此处不能有冲突,因为补丁本身并不表示对同一行的两组不同更改。当您有两个
补丁仅提供一个更改。它要么适用,要么不适用。
这里有两个替代选项。从效果不佳的订单到效果更好的订单:
确保来自存储库A的补丁程序是由git format-patch --full-index
生成的。使用git am
时,请使用git am -3
(或将am.threeWay
配置为true
)。这样,A
上的差异将包含文件父版本的完整Blob哈希。如果该Blob(文件的父级版本)在存储库B中可用,则Git将能够使用blob-hash-and-patch重构实际合并所需的三个输入:通用基本版本和已修改的两个版本,从基础版本开始。
或者,在存储库B中使用git remote add
来添加对存储库A的直接访问。选择一个远程名称,该名称将提醒您以后要使用的名称(或之后立即删除该远程对象)。然后使用此远程名称运行git fetch
,将来自仓库A的提交引入仓库B,以便所有提交都可以在B中本地使用。现在,代替git format-patch
和git am
,您可以运行:
git cherry-pick <hash>
用于相关提交。 Git现在将使用回购A的两次提交作为合并基础及其更改来进行完整的三向合并:
git diff <parent of hash> <hash> # what they changed
和您当前所做的更改:
git diff <parent of hash> HEAD # what we changed
并结合它们,并酌情存在冲突。这里的第二个diff命令是“我们所做的更改”或合并的--ours
部分;这里的第一个diff命令是“它们更改了什么”,因此是合并的--theirs
部分。
请注意,git am -3
或设置am.threeWay
只是通过以下方式尝试尝试完全合并的一种方法:
index a1539a7ce682f10a5aff3d1fee4e86530e058c89..98f88a28d3227c436ecf1765f75b7f4e8e336834 100755
给出显示在您的存储库中的哈希ID。如果您还没有git fetch
,实际上会用该哈希ID来获得 这个斑点,因此您只需要希望和愿望即可。
答案 1 :(得分:0)
注意,您会看到:
hint: Use 'git am --show-current-patch' to see the failed patch
但是,正如Git 2.25(第1季度2020)中所述,情况并非如此。
请参见commit 80736d7的Junio C Hamano (gitster
)(2019年10月23日)。
(由Junio C Hamano -- gitster
--在commit f1e2666中合并,2019年11月10日)
doc
:am --show-current-patch
提供了完整的电子邮件消息现有措辞给人的印象是,它仅提供
$GIT_DIR/rebase-apply/patch
文件的内容,即补丁正确,,但该选项实际上发出了正在处理的整个电子邮件(现在,其中一个来自“ git mailsplit”的输出文件)。
因此,您可能必须从该电子邮件中提取出导致冲突的确切部分。