在 git 变基冲突中找不到 `HEAD`?
Can't find `HEAD` in git rebase conflict?
我正在尝试变基以压缩提交,但我遇到了冲突:
<username>:~/path/to/director$git rebase -i HEAD~6
error: could not apply 0111a7a... <commit message>
When you have resolved this problem, run "git rebase --continue".
If you prefer to skip this patch, run "git rebase --skip" instead.
To check out the original branch and stop rebasing, run "git rebase --abort".
Could not apply 0111a7acsadd9a9d98a9003a560a390a50a22afa3af546f42101... <full commit message>
然后,我执行以下操作来查找冲突:
find . -name "*.py" -exec egrep ".*HEAD.*" {} \;
因为我知道我只更改了 python 个文件,所以我使用 *.py
通配符。然而,没有结果显示!有没有办法准确找到问题所在?
git status
和 git diff
都是干净的。
通常 git status
应该向您显示一个冲突的文件。您不应该搜索 HEAD,而应该搜索 <<<<<<、====== 或 >>>>>>.
既然你说 git status
是干净的,那么你的提交可能已经变空了。您可以使用
检查提交中的内容
git show 0111a7a
如果你的提交已经变成空的,你应该跳过它,使用
git rebase --skip
在回答下面的问题之前,我想说明一件事:如果您只想将一系列提交压缩成一个提交,最简单的方法通常就是将 git reset --soft
与单个所需的提交结合起来.请参阅 this answer by Chris Johnsen and this answer by VonC,并注意 VonC 的最后一段要点。
我们无法确定发生了什么,因为您没有向我们展示足够的信息,但这是一个常见的场景,其中 git rebase
告诉您它无法应用某些提交,但也有git status
未显示任何修改。这与您的情况不一样(您将自己的提交变基到自己的 HEAD~6
,这使得这种可能性降低),但我们还是看得不够多来自您的信息,所以我将此作为示例。
假设您正在对一系列两个或多个提交进行变基。第一个修复文本文件第 3 行单词 word
的拼写。第二次和任何后续提交对其他文件进行其他操作。这些更改是在分支 bran
上进行的,但从那时起您 运行 git fetch
and/or 决定将它们移动到分支 master
或其他任何地方。
与此同时,有人 也 修复了该文本文件第 3 行 word
一词的拼写,以及 word
一词的拼写 spelling
在第 12 行。因此,您的修复是他们修复的一个子集。这不是 完全相同的 修正——你只修正了一个词,他们修正了两个——但是你的修正不能应用,因为词 word
已经在文本文件。
Git 不能1 明白这个就OK了。由您决定是否不再需要您的修复,虽然它与您正在重新定位的 "upstream" 修复不同。 在这种情况下(但在其他情况下则不然)您应该跳过提交。
这是发生这种情况的示例会话:
$ * abda13a (master) fix two words
| * 9e7ed64 (HEAD, bran) add a file
| * 144d5a6 fix one word
|/
* ac7be27 initial
让我们看一下提交 144d5a6
:
$ git show bran^
commit 144d5a66949cdd40fd92b0846d5b0ce00ebcdd8c
Author: [redacted]
Date: [redacted]
fix one word
diff --git a/README.txt b/README.txt
index c37e4c4..983e649 100644
--- a/README.txt
+++ b/README.txt
@@ -1,6 +1,6 @@
This readme file
has at least one
-wurd
+word
that is
misspelled.
There may be
现在让我们看一下 master
的最高提交:
$ git show master
commit abda13a47f5b5d968a09eedaf5cc573ba35a3dee
Author: [redacted]
Date: [redacted]
fix two words
diff --git a/README.txt b/README.txt
index c37e4c4..867d98f 100644
--- a/README.txt
+++ b/README.txt
@@ -1,6 +1,6 @@
This readme file
has at least one
-wurd
+word
that is
misspelled.
There may be
@@ -9,7 +9,7 @@ words, since
the point of
this file
is to allow someone
-to fix the speeling
+to fix the spelling
of any
of the misspelled
words.
现在让我们将当前分支(即 bran
)变基到 master
,但以交互方式:
$ git rebase -i master
[the editor comes up with both commits selected as `pick`]
[I exit the editor with the same `pick`s]
The previous cherry-pick is now empty, possibly due to conflict resolution.
If you wish to commit it anyway, use:
git commit --allow-empty
Otherwise, please use 'git reset'
rebase in progress; onto abda13a
You are currently rebasing branch 'bran' on 'abda13a'.
nothing to commit, working directory clean
Could not apply 144d5a66949cdd40fd92b0846d5b0ce00ebcdd8c... fix one word
(这是 git 2.3.7,顺便说一句;旧版本甚至没有注意到 cherry-pick 已经变空了,只是抱怨无法应用提交。这不是我很清楚为什么它也建议 git reset
;目前没有必要。但是,git 2.3.7 现在已经过时了;我应该升级。)
1这个其实还要看其他的。在 git 2.3.7 中,它现在已经足够智能,可以检测 非交互式 变基的这种情况。使用上面的初始设置:
$ git rebase master
First, rewinding head to replay your work on top of it...
Applying: fix one word
Using index info to reconstruct a base tree...
M README.txt
Falling back to patching base and 3-way merge...
No changes -- Patch already applied.
Applying: add a file
$ git log --oneline --graph --decorate --all
* c8f1815 (HEAD, bran) add a file
* abda13a (master) fix two words
* ac7be27 initial
在这种情况下,非交互式 rebase 发现我的 "fix one word" 与 "fix two words" 是多余的并简单地跳过它,因此 bran
上的最终提交顺序是实际上只是剩下的一个提交, "fix two words" 在 master
上作为其父项。
我正在尝试变基以压缩提交,但我遇到了冲突:
<username>:~/path/to/director$git rebase -i HEAD~6
error: could not apply 0111a7a... <commit message>
When you have resolved this problem, run "git rebase --continue".
If you prefer to skip this patch, run "git rebase --skip" instead.
To check out the original branch and stop rebasing, run "git rebase --abort".
Could not apply 0111a7acsadd9a9d98a9003a560a390a50a22afa3af546f42101... <full commit message>
然后,我执行以下操作来查找冲突:
find . -name "*.py" -exec egrep ".*HEAD.*" {} \;
因为我知道我只更改了 python 个文件,所以我使用 *.py
通配符。然而,没有结果显示!有没有办法准确找到问题所在?
git status
和 git diff
都是干净的。
通常 git status
应该向您显示一个冲突的文件。您不应该搜索 HEAD,而应该搜索 <<<<<<、====== 或 >>>>>>.
既然你说 git status
是干净的,那么你的提交可能已经变空了。您可以使用
git show 0111a7a
如果你的提交已经变成空的,你应该跳过它,使用
git rebase --skip
在回答下面的问题之前,我想说明一件事:如果您只想将一系列提交压缩成一个提交,最简单的方法通常就是将 git reset --soft
与单个所需的提交结合起来.请参阅 this answer by Chris Johnsen and this answer by VonC,并注意 VonC 的最后一段要点。
我们无法确定发生了什么,因为您没有向我们展示足够的信息,但这是一个常见的场景,其中 git rebase
告诉您它无法应用某些提交,但也有git status
未显示任何修改。这与您的情况不一样(您将自己的提交变基到自己的 HEAD~6
,这使得这种可能性降低),但我们还是看得不够多来自您的信息,所以我将此作为示例。
假设您正在对一系列两个或多个提交进行变基。第一个修复文本文件第 3 行单词 word
的拼写。第二次和任何后续提交对其他文件进行其他操作。这些更改是在分支 bran
上进行的,但从那时起您 运行 git fetch
and/or 决定将它们移动到分支 master
或其他任何地方。
与此同时,有人 也 修复了该文本文件第 3 行 word
一词的拼写,以及 word
一词的拼写 spelling
在第 12 行。因此,您的修复是他们修复的一个子集。这不是 完全相同的 修正——你只修正了一个词,他们修正了两个——但是你的修正不能应用,因为词 word
已经在文本文件。
Git 不能1 明白这个就OK了。由您决定是否不再需要您的修复,虽然它与您正在重新定位的 "upstream" 修复不同。 在这种情况下(但在其他情况下则不然)您应该跳过提交。
这是发生这种情况的示例会话:
$ * abda13a (master) fix two words
| * 9e7ed64 (HEAD, bran) add a file
| * 144d5a6 fix one word
|/
* ac7be27 initial
让我们看一下提交 144d5a6
:
$ git show bran^
commit 144d5a66949cdd40fd92b0846d5b0ce00ebcdd8c
Author: [redacted]
Date: [redacted]
fix one word
diff --git a/README.txt b/README.txt
index c37e4c4..983e649 100644
--- a/README.txt
+++ b/README.txt
@@ -1,6 +1,6 @@
This readme file
has at least one
-wurd
+word
that is
misspelled.
There may be
现在让我们看一下 master
的最高提交:
$ git show master
commit abda13a47f5b5d968a09eedaf5cc573ba35a3dee
Author: [redacted]
Date: [redacted]
fix two words
diff --git a/README.txt b/README.txt
index c37e4c4..867d98f 100644
--- a/README.txt
+++ b/README.txt
@@ -1,6 +1,6 @@
This readme file
has at least one
-wurd
+word
that is
misspelled.
There may be
@@ -9,7 +9,7 @@ words, since
the point of
this file
is to allow someone
-to fix the speeling
+to fix the spelling
of any
of the misspelled
words.
现在让我们将当前分支(即 bran
)变基到 master
,但以交互方式:
$ git rebase -i master
[the editor comes up with both commits selected as `pick`]
[I exit the editor with the same `pick`s]
The previous cherry-pick is now empty, possibly due to conflict resolution.
If you wish to commit it anyway, use:
git commit --allow-empty
Otherwise, please use 'git reset'
rebase in progress; onto abda13a
You are currently rebasing branch 'bran' on 'abda13a'.
nothing to commit, working directory clean
Could not apply 144d5a66949cdd40fd92b0846d5b0ce00ebcdd8c... fix one word
(这是 git 2.3.7,顺便说一句;旧版本甚至没有注意到 cherry-pick 已经变空了,只是抱怨无法应用提交。这不是我很清楚为什么它也建议 git reset
;目前没有必要。但是,git 2.3.7 现在已经过时了;我应该升级。)
1这个其实还要看其他的。在 git 2.3.7 中,它现在已经足够智能,可以检测 非交互式 变基的这种情况。使用上面的初始设置:
$ git rebase master
First, rewinding head to replay your work on top of it...
Applying: fix one word
Using index info to reconstruct a base tree...
M README.txt
Falling back to patching base and 3-way merge...
No changes -- Patch already applied.
Applying: add a file
$ git log --oneline --graph --decorate --all
* c8f1815 (HEAD, bran) add a file
* abda13a (master) fix two words
* ac7be27 initial
在这种情况下,非交互式 rebase 发现我的 "fix one word" 与 "fix two words" 是多余的并简单地跳过它,因此 bran
上的最终提交顺序是实际上只是剩下的一个提交, "fix two words" 在 master
上作为其父项。