Git分支因错误合并而处于不一致状态

3
我有一个git分支,开始表现出无法进行甚至是微不足道的rebase回到某个时间点之前,声称许多提交已经消失了 - 在调试这个问题时,我发现了一个更简单的异常。 git log给我一个完全一致的提交列表,我期望看到。如果我使用git reset --hard HEAD^逐个向后移动提交,一切都按预期工作 - 直到突然间我只是回退了十几个提交,没有任何警告。
我从ID为367df61041c380b3e769177779cb7c8ab21630b4的提交开始,并且git日志看起来像:
367df61 fixing flake8/syntax errors
14210b8 Merge remote-tracking branch 'origin/dev' into dev
a6818d5 Merge pull request #55 from rec/fast-gamma
e8ffdf2 Tweak exit manager code (fix #56).  Please enter the commit message for your changes. Lines starting
d1c464c Tweak masterBrightness.
975de68 Re-enable timedata end-to-end.
bf7e918 Add optional timedata.Renderer to driver_base.py.
b4daff6 Simplify _render slightly.
a306798 Stop slicing colors and add an offset instead.
b379f21 Move generate_header into util.
e50ec8c Simplify frame rendering slightly.
12cfc2d Extract data and functions into return_codes.py
764e4b9 Convert LDP8806.py from DOS line endings to Unix.
d3dc333 Remove old gamma tables.
5ae2934 Simplify gamma.py; prove backward compatibility.
bae1cf4 Temporarily disable timedata and simplify rendering.
c436f19 showing timedata usage
5228261 updating colors.py for py3

如果我执行git reset --hard HEAD^一次,我会移动到14210b8 Merge remote-tracking branch 'origin/dev' into dev,正如我所期望的那样,而且git log与上述内容一致。
但是现在,如果我第二次执行git reset --hard HEAD^,我会移动到c436f19 showing timedata usage,接近上面列表的底部!a6818d5bae1cf4之间的所有提交都消失了。
我的怀疑之眼被引向提交a6818d5a2,它似乎包含了所有这些消失的更改。
这是怎么发生的?也许是从错误的基础分支或提交ID合并...但我们到底做错了什么?
让我自己处理,我会恢复到某个已知的好提交,然后逐个挑选提交,完全跳过合并。这不会很费力,但我觉得肯定有更好的方法。
以下是需要回答的问题:
1. 发生了什么?这是一个分支处于合理状态吗?我在使用git时犯了错误,还是有什么“损坏”? 2. 如果它被损坏了,我该如何修复它?我们如何改变我们的工作流程以避免再次破坏分支? 3. 如果没有损坏,我们该如何更改我们的git工作流程来处理这种情况?
我的答案是-禁止合并提交。
所有这些问题归结为一个问题——假设我有这些合并,如何在它们上面进行变基?

@matt:帽子/插入符后缀特指第一个父提交,除非您添加一个数字。HEAD^HEAD^1都是父提交#1,而HEAD^2是父提交#2。如果您有一个章鱼合并(超过2个父提交),则继续使用HEAD^3等。大多数工具很难观察到父提交的实际顺序(尽管一些图形查看器使用线条颜色:当通过合并时,相同的颜色表示“父提交#1”),但已经指定:第一个父提交是您进行合并时所在的分支(如git status中所示,“在分支master上”)。 - torek
2个回答

0
这是怎么回事?这个分支处于这种状态是否合理,我在使用git时犯了错误,还是有什么“损坏”了?
请记住,默认情况下git log显示一条线性的提交列表。对于合并来说可能会有点困惑,因为合并提交有多个父节点。您可以使用git log --oneline --graph查看提交图。它将包括额外的可视化内容,以帮助您查看每个提交的所有父节点。
如果没有损坏,我们如何更改我们的git工作流程来处理这种情况?
我对git的行为还不太了解,特别是当一个提交有多个父节点时,我不确定HEAD^的行为。这实际上是你重置你的提交历史的根源。此外,我不知道当提交范围包含合并时git rebase的行为。您需要对这两个问题进行一些研究。

所以你实际上不知道答案。这只是一个(长)注释。 - matt
@matt 我认为这是一个答案,虽然不完整。也许我的编辑使我正在尝试回答的OP的哪个部分更清楚。 - Code-Apprentice
git log --oneline --graph 至少可以在图形上清晰地显示问题所在。 - Tom Swirly

-1

首先,使用 git status 确定您的工作副本处于什么状态。如果您忘记了合并、变基、二分或其他冲突情况,可能会得到非常出乎意料的结果。

然后,在当前 HEAD 仍然重要时,请不要使用 git reset --hard。使用 git checkout <hash> 将其移动到所需位置,并在那里标记提交或使用 git checkout -b <branchname> <hash> 打开一个分支。所有这些更安全的命令都将防止您意外丢失 HEAD

我还没有看到 HEAD^ 指向除(第一个)父提交之外的其他内容。您可以在 此处 找到有关这些导航方法的详细说明。但是,如果您不确定,请使用 git log HEAD^ 查找 HEAD^ 是什么。

以防万一您丢失了 HEAD,如果垃圾收集器尚未完成工作,则可能仍然可以使用 git reflog 找回旧的提交。


什么!?我还没有失去我的HEAD - 我还没有失去任何工作。一切都很好;我只是在尝试调试这个分支有什么问题,防止我重新设置它。 - Tom Swirly
你没有解释工作副本处于什么状态,也没有回答其他人关于合并图的问题。你写道你的提交已经消失了。我只是想帮忙。 - Martin Sugioarto
仅仅因为在变基时发生了一些意外,并不意味着我真的丢失了工作!我试图调试一个无法通过变基的分支。虽然没有人实际要求查看合并图,但是问题在于合并提交有两个父级。尽管如此,我仍然不知道如何在保留它们的情况下进行变基... - Tom Swirly
没有太多信息可以帮助你。我无法说出为什么你称之为“不好”的合并是如此。那里是否有不该在那儿的提交?或者你只是想要一个线性历史记录? - Martin Sugioarto
或许你无法恢复合并之前的状态(将分支回滚到仅包含你提交的上一个点)? - Martin Sugioarto

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接