我已经知道如何在git rebase --continue之前使用git mergetool或git add(基础用法),但有时文件之间的差异并不足够:我想看到刚刚未能应用于工作树的提交日志和差异。
我阅读了其他问题中的答案,其中提到如果我正在使用git merge,则git log --merge将显示父提交。当我遇到冲突时还是尝试了它,但被告知“致命错误:--merge没有MERGE_HEAD?”。
如何确定有问题的提交?
如果显示为
Patch failed at 0001 commit message for F
然后运行
$ head -1 .git/rebase-apply/0001
From ad1c7739c1152502229e3f2ab759ec5323988326 Mon Sep 17 00:00:00 2001
要获取失败提交的SHA ad1c77
,然后使用 git show ad1c77
命令查看它。
让我们从这个树开始:
A---B---C---D
\
E---F---G
$ git checkout G
$ git rebase D
当发生变基冲突时,它是发生在
C--D
)与公共祖先(B
)之间的已经重新基于的更改和已经解决的冲突(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'
以下是错误信息:
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
首先,你可以看到它是F
,因为提交信息出现了。但是,如果你的提交信息都像“foo”、“documentation”或“一些修复”,那么这并没有帮助,你实际上需要查看SHA ID ad1c77
或补丁内容。
F
的真实身份的方法:当它列出变基冲突时,会显示类似于以下内容:
Patch failed at 0001 commit message for F
现在查看 .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
补丁文件包括原始的提交ID。
$ head -1 .git/rebase-apply/0001
From ad1c7739c1152502229e3f2ab759ec5323988326 Mon Sep 17 00:00:00 2001
你可以查看那个。
肯定有更简单的方式,但这个方法也有效。
注意,补丁失败可能是由于不同的提交(如果你正在将其变基到HEAD
和变基目标的公共祖先)。找到该提交要复杂得多,尽管你可以尝试反向进行变基以找到它:
$ git checkout D
$ git rebase G
head -1 .git/rebase-apply/0001 | awk '{ print $2 }'
命令。如果您想立即显示提交,则可以使用git show $(head -1 .git/rebase-apply/0001 | awk '{ print $2 }')
命令。 - Dan在进行 git rebase
时,如果遇到冲突需要停止解决时,以下命令将显示冲突的提交(所有内容,而不仅是冲突的文件),也就是您当前正在重播/重新基于新基础的提交,无论您在何处:
git show $(< .git/rebase-apply/original-commit)
如果您只想查看特定冲突文件(您正在解决的文件)的冲突情况,请使用独立模式:
git show $(< .git/rebase-apply/original-commit) -- /path/to/conflicting/file
在构建这个答案的过程中没有虐待猫咪 :).
这可能是一个新功能,但是REBASE_HEAD
可以给你停留在哪个提交上(例如,如果提交无法应用)。如果您想查看完整的提交信息,可以使用:
git show REBASE_HEAD
git rebase --show-commit-patch
。文档中说它们是等效的。master
重新定位到origin/master
,则可以使用:git diff master..origin/master
如果您想将更改作为单独的提交查看:
git log -p master..origin/master
如果你更喜欢使用哈希值,或者重新创建衍合分支有一段时间了,忘记了正在衍合哪些分支,你可以使用 git status
命令查看这两个分支。例如:
你当前正在将分支“master”衍合到“b5284275”上。
然后,你可以使用以下命令查看发生的变化:
git diff master..b5284275
--show-current-patch
。 - ricab--show-current-patch
。 - undefinedrebase-apply
。--show-current-patch
"选项提供了一种面向最终用户的方法,在"git rebase
"(和"git am
")在冲突时停止时获取正在应用的diff
。
查看 提交 fbd7a23, 提交 6633529, 提交 984913a (2018年2月11日) 由Nguyễn Thái Ngọc Duy (pclouds
)完成。
(由Junio C Hamano -- gitster
--合并于提交 9ca488c, 2018年3月6日)
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".
然后你会得到:
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
git am --short-current-patch
" 是一种展示停止步骤的电子邮件片段的方式,不适合直接输入到 "git apply
"(它被设计为一个良好的 "git am
" 输入)。
随着 Git 2.26(2020年第一季度)的推出,它学习了一个新选项,仅显示补丁部分。
查看 提交 aa416b2, 提交 f3b4822, 提交 e8ef1e8, 提交 bc8620b, 提交 62e7a6f (2020年2月20日) 由Paolo Bonzini (bonzini
)提交。
(由Junio C Hamano -- gitster
--合并于提交0e0d717, 2020年3月9日)
am
: 支持 --show-current-patch=diff 以检索 .git/rebase-apply/patch报告者: J. Bruce Fields
签名作者: Paolo Bonzini
当 commit 984913a210 ("am
: 添加 --show-current-patch", 2018-02-12, Git v2.17.0-rc0 -- 合并 列在 批次 #7 中) 加入 "git am --show-current-patch
" 后,"git am
" 开始推荐它作为 .git/rebase-merge/patch
的替代品。
不幸的是,这个建议有些误导人;例如,"git am --show-current-patch
" 的输出如果编码为 quoted-printable 或 base64,则无法传递给 "git apply
"。
添加一个新模式到 "git am --show-current-patch
" 中,以纠正这个建议。
新模式是diff
:
--show-current-patch[=(diff|raw)]
:显示由于冲突而
git am
已停止的消息。
如果指定了raw
,则显示电子邮件消息的原始内容;如果指定了diff
,则仅显示差异部分。
默认为raw
。
还有:
am
:支持--show-current-patch=raw
作为--show-current-patch
的同义词Signed-off-by: Paolo Bonzini
为了简化工作树操作并避免用户进入.git
,最好让 "git am
" 也提供一种将 .git/rebase-merge/patch
复制到标准输出的模式。
一种可能是完全分开选项,引入例如 --show-current-message
(用于 .git/rebase-apply/NNNN
)和 --show-current-diff
(用于 .git/rebase-apply/patch
),同时可能弃用 --show-current-patch。
这甚至可以删除系列中前两个补丁的需要。但是,长公共前缀会阻止使用缩写选项,例如 "--show
"。
因此,我选择在 --show-current-patch
中添加一个字符串参数。
cat .git/rebase-apply/original-commit
A---B---C---D
\
E---F---G
$ git checkout G
$ git rebase D
鉴于在应用F时存在合并冲突:
A---B---C---D--E'--!
\
E---F---G
如果执行了以上操作,original-commit
文件将显示F的哈希值。这是“theirs”的版本。
此外,在这种情况下,HEAD(.git/HEAD)将为E'。这是“mine”的版本。HEAD^将是“base”版本。
对于至少git 1.7.9版本,这是正确的。
不确定为什么在我的情况下没有 .git/rebase-apply
。 对于处于相同情况的人,这是我的变化。
git show $(cat .git/rebase-merge/stopped-sha)
git config --global alias.sp='!git show $(cat .git/rebase-merge/stopped-sha)'
rebase-apply
文件夹用于非交互式的变基操作,而rebase-merge
则用于交互式的变基操作。 - LoKigit am --show-current-patch
很多时候,在进行变基(rebase)操作时,你会想跳过那些不必要的提交。
不幸的是,尽管 git status
告诉你正在处理提交,并建议使用 git rebase --continue
, git rebase --skip
或 git rebase --abort
命令,但它并不告诉你当前所在的提交。
因此,有时很难知道你应该使用 git rebase --skip
还是不用。
然而,仍有一种方法可以通过运行以下命令来找出你当前所在的提交:
git log -1 $(< .git/rebase-apply/original-commit)
git am --show-current-patch
。请参见下面的答案。 - VonC