Rob*_*obM 40 git merge git-rebase
当我遇到使用合并冲突时git rebase
,如何根据提交识别冲突的来源,而不仅仅是文件差异?
我已经知道如何使用(git mergetool
或基本)使用或git add
之前git rebase --continue
,但有时文件之间的差异是不够的:我想看到提交的提交日志和差异,但未能应用于工作树.
我已经读过其他问题,git log --merge
如果我使用的话会显示父提交git merge
.当我遇到冲突并被告知时,我还是尝试过fatal: --merge without MERGE_HEAD?
.
如何识别有问题的提交?
Ale*_*own 39
如果它说
Patch failed at 0001 commit message for F
Run Code Online (Sandbox Code Playgroud)
然后跑
$ head -1 .git/rebase-apply/0001
From ad1c7739c1152502229e3f2ab759ec5323988326 Mon Sep 17 00:00:00 2001
Run Code Online (Sandbox Code Playgroud)
获取ad1c77
失败提交的SHA ,然后使用它git show ad1c77
来查看它.
让我们从这棵树开始:
A---B---C---D
\
E---F---G
$ git checkout G
$ git rebase D
Run Code Online (Sandbox Code Playgroud)
当发生rebase冲突时,它之间会发生冲突
C--D
从共同的祖先() B
)PLUS已经重订的变化和已经解决冲突(E'
)对F
)的补丁让我们看看发生了什么:
1) A---B---C---D---E' <- E patched and committed successfully as E'
2) A---B---C---D---E'--- <- failed to patch F onto E'
Run Code Online (Sandbox Code Playgroud)
这是错误消息:
First, rewinding head to replay your work on top of it...
Applying: commit message for F
Using index info to reconstruct a base tree...
Falling back to patching base and 3-way merge...
Auto-merging 1.txt
CONFLICT (content): Merge conflict in 1.txt
Failed to merge in the changes.
Patch failed at 0001 commit message for F
Run Code Online (Sandbox Code Playgroud)
首先,您可以看到它F
,因为提交消息出现.但是,如果您的提交消息都看起来像"foo","documentation"或"some fixes",那么这将无济于事,您确实需要SHA ID ad1c77
或补丁内容.
F
:当它列出rebase冲突时,它会说:
Patch failed at 0001 commit message for F
Run Code Online (Sandbox Code Playgroud)
现在看看.git/rebase-apply/
,你会在哪里找到补丁文件0001
:
$ ls .git/rebase-apply
0001 head-name msg orig-head sign
0002 info msg-clean patch threeway
apply-opt keep next quiet utf8
final-commit last onto rebasing
Run Code Online (Sandbox Code Playgroud)
补丁文件包含原始commit-id
$ head -1 .git/rebase-apply/0001
From ad1c7739c1152502229e3f2ab759ec5323988326 Mon Sep 17 00:00:00 2001
Run Code Online (Sandbox Code Playgroud)
然后你可以看一下.
必须有一个更简单的方法,但这是有效的.
请注意,修补程序失败的事实可能是由于不同的提交(如果您要重新定位到共同的祖先HEAD
和rebase目标).发现提交相当复杂,尽管你可以尝试反向修改它来找到它:
$ git checkout D
$ git rebase G
Run Code Online (Sandbox Code Playgroud)
jav*_*ett 10
在git rebase
停止解决冲突的过程中,以下命令将显示冲突的提交(所有这些,而不仅仅是冲突的文件),即,您的提交当前正在重播/重新定位到新基础上,无论您在哪里 -至:
git show $(< .git/rebase-apply/original-commit)
Run Code Online (Sandbox Code Playgroud)
如果您只想查看特定冲突文件(您正在解析的文件)的冲突,请隔离:
git show $(< .git/rebase-apply/original-commit) -- /path/to/conflicting/file
Run Code Online (Sandbox Code Playgroud)
没有猫在这个答案的构建中被滥用:).
这可能是一个新功能,但REBASE_HEAD
会为您提供当前停止的提交(例如,如果提交未能应用)。如果您想完整查看提交,可以使用
git show REBASE_HEAD
Run Code Online (Sandbox Code Playgroud)
作为更详细的替代方法,您可以使用git rebase --show-commit-patch
. 文档说它们是等效的。
如果您想查看重新定位的位置和重新定位的位置之间发生了什么变化,您可以获取两个分支之间的差异。例如,如果你从基础重建master
到origin/master
你可以使用:
git diff master..origin/master
Run Code Online (Sandbox Code Playgroud)
或者,如果您想将更改视为单独的提交:
git log -p master..origin/master
Run Code Online (Sandbox Code Playgroud)
如果您更喜欢使用散列,或者可能在一段时间后回到变基并且不记得要变基的分支,您可以使用git status
查看两个分支。例如:
您目前正在将分支 'master' 重新设置为 'b5284275'
然后,要查看发生了什么变化,您可以使用:
git diff master..b5284275
Run Code Online (Sandbox Code Playgroud)
从 Git 2.17(2018 年 3 月)开始,您不需要使用rebase-apply
.
新的“ --show-current-patch
”选项提供了一种面向最终用户的方式,可以diff
在“ git rebase
”(和“ git am
”)因冲突而停止时应用。
请参阅Nguy?n Thái Ng?c Duy ( ) 的commit fbd7a23、commit 6633529、commit 984913a(2018 年 2 月 11 日)。(由Junio C Hamano合并-- --在提交 9ca488c 中,2018 年 3 月 6 日)pclouds
gitster
am
: 添加 --show-current-patch签字人:Nguy?n Thái Ng?c Duy
指向用户
$GIT_DIR/rebase-apply
可能会鼓励他们在那里乱搞,这不是一件好事。这样,当用户需要查看补丁时,用户不必将路径保留在某处(因为在执行几个命令后,路径可能会超出回滚缓冲区)。
在“显示当前的 git 交互式 rebase 操作”中查看更多信息
例子:
C:\Users\VonC\repo\src>git rebase origin/master
First, rewinding head to replay your work on top of it...
Applying: change code
Using index info to reconstruct a base tree...
M a/src/file
Falling back to patching base and 3-way merge...
Auto-merging a/src/file
CONFLICT (content): Merge conflict in a/src/file
error: Failed to merge in the changes.
hint: Use 'git am --show-current-patch' to see the failed patch <======
Patch failed at 0001 change code
Resolve all conflicts manually, mark them as resolved with
"git add/rm <conflicted_files>", then run "git rebase --continue".
You can instead skip this commit: run "git rebase --skip".
To abort and get back to the state before "git rebase", run "git rebase --abort".
Run Code Online (Sandbox Code Playgroud)
然后你会得到:
C:\Users\VonC\rep\src>git am --show-current-patch
commit xxx (master)
Author: VonC <vonc@vonc.com>
Date: Mon Nov 4 13:59:18 2019 +0100
change code
diff --git a/a/src/file b/a/src/file
index yyy..zzz 100644
--- a/a/src/file
+++ b/a/src/file
@@ -13,5 +13,5 @@ file: /a/src
content line 1
content line 2
content line 3
content line 4
-content line 5
-content line 6
+content bis line 5
+content bis line 6
Run Code Online (Sandbox Code Playgroud)
“ git am --short-current-patch
”是显示停止步骤的邮件的一种方式,不适合直接输入“ git apply
”(它被设计为一个很好的“ git am
”输入)。
在 Git 2.26(2020 年第一季度)中,它学习了一个仅显示补丁部分的新选项。
请参阅Paolo Bonzini ( ) 的commit aa416b2、commit f3b4822、commit e8ef1e8、commit bc8620b、commit 62e7a6f(2020 年 2 月 20 日)。(由Junio C Hamano合并-- --在0e0d717 提交中,2020 年 3 月 9 日)bonzini
gitster
am
: 支持 --show-current-patch=diff 检索 .git/rebase-apply/patch报告人:J. Bruce Fields
签字人:Paolo Bonzini当
git am --show-current-patch
在提交 984913a210中添加“ ” (“am
:add --show-current-patch”,2018 年 2 月 12 日,Git v2.17.0-rc0 --合并在第 7 批中列出)时,“git am
”开始推荐它作为的替代品.git/rebase-merge/patch
。不幸的是,这个建议有些误导;例如,如果“
git am --show-current-patch
”的输出git apply
被编码为quoted-printable 或base64,则不能将其传递给“ ”。为“
git am --show-current-patch
”添加一个新模式以纠正建议。
在新的模式是diff
:
--show-current-patch[=(diff|raw)]
:显示
git am
因冲突而停止的消息。
如果raw
指定,则显示电子邮件消息的原始内容;如果diff
,仅显示差异部分。
默认为raw
.
和:
am
: support--show-current-patch=raw
作为同义词--show-current-patch
签字人:Paolo Bonzini
为了简化工作树操作并避免用户进入
.git
,如果“git am
”还提供一种复制.git/rebase-merge/patch
到标准输出的模式会更好。一种可能性是拥有完全独立的选项,例如引入
--show-current-message
(for.git/rebase-apply/NNNN
) 和--show-current-diff
(for.git/rebase-apply/patch
),同时可能弃用 --show-current-patch。这甚至可以消除对系列中前两个补丁的需求。但是,较长的公共前缀会阻止使用诸如“
--show
”之类的缩写选项。因此,我选择将字符串参数添加到
--show-current-patch
.