【问题标题】:Fixing Git repo after incorrect merging错误合并后修复 Git repo
【发布时间】:2010-08-21 23:42:28
【问题描述】:

我有一堆独立的分支,我想合并它们,因为它们中的每一个都是对程序不同部分的更新。

我想我应该合并它们,但我在检查每个分支后运行了 git commit -a

然后我意识到整个程序可以回到过去,所以我运行了git reset --soft HEAD(我在某处读到了一篇文章,这应该会有所帮助),但这并没有起到任何作用。

我还从 git 收到了这条关于手动删除一些 ./git/index.lock 的消息,因此我将其移至 ./git/backup_of_index.lock,但这似乎也没有任何作用。

如何修复我的存储库并合并所有分支?

【问题讨论】:

  • 恢复到旧备份总是适合我
  • Git 很棒,你真的应该知道如何从命令行使用它。然而,当涉及到除了简单的提交和推送之外的分支/合并/几乎任何事情时,我更喜欢使用良好的 GUI。如果您使用的是 Windows,我强烈建议您使用“Git Extensions”。奇怪的是,在 linux 上没有一个好的多合一解决方案,但是普通的 git-gui 和 giggle 可以为我完成工作。
  • 首先,现在对工作树和.git 文件夹进行完整备份,并将其放在安全的地方,最好是只读的。从你所说的看来,你失去工作的可能性很小(没有reset --hard,听起来你在搞乱提交到分支上的事情)。完成此操作后,请在某个交互式频道上找到一位 git 专家,他可以告诉您如何搜索和恢复您以前的状态。 stackoverflow 几乎肯定不是这个论坛,因为您需要交互式帮助,而不仅仅是问答。
  • 谢谢大家,我会用所有的建议想办法,我还不能真正选择答案。

标签: git merge


【解决方案1】:

这种情况下最重要的 git 命令是git reflog。 reflog 会跟踪对每个特定分支头的所有更改,git reflog 命令会及时列出对分支头的所有更改。

如果您可以使用 reflog 识别出一个“好的”提交 id(并且它会在某个地方),那么您就远远领先于您现在的位置。如果一个好的提交 ID 是 abc123,那么命令:

git checkout -b rescue abc123

在提交 ID abc123 处创建一个名为 rescue 的新分支。

当我学习 git 时,我有类似的“我到底在哪里,我是怎么到这里的?”片刻。我在 different Stack Overflow question 上了解了 reflog,这是了解 Git 最有价值的事情。

【讨论】:

  • 我将此评论作为您应该关注乔纳森的评论。运行 git reflog(或 git log -g 以获取相同的信息和更多数据),找到最后一个好的提交并在此时签出一个分支。
  • 另外,这里有一些关于这种情况的文档:progit.org/book/ch9-7.html#data_recovery
  • 我来这里是为了说“reflog!”仅从问题的标题来看。
  • 不幸的是,我已经听过别人的声音并重置了 head,所以当我运行 git reflog 时,head{0} 已经在混乱之后了
  • @jsd911:没关系。重置头部不会删除 reflog 或任何东西。 reflog 会跟踪对分支头部的每次更改。它会全部记住它们,因此每当分支发生变化时,previous 值都会存储在 reflog 的顶部。查看 reflog 是一种时光倒流,其中包含对您的分支的每一次更改。因此,如果您的分支在过去的某个时间点包含“正确”的提交 ID,那么它将在 reflog 中。
【解决方案2】:

除非您入侵了.git 目录中的数据,否则您不太可能丢失任何东西。您可能需要清理一个可怕的烂摊子,并且可能需要花费大量时间来弄清楚您做了什么以及它在哪里,但您可能没有丢失任何东西。

这是个好消息。

坏消息是,任何人都很难为您提供太多帮助。

您可能需要识别所有分支,并追溯每个分支上的提交。您需要确定所有这些“git commit -a”操作是否是一个好主意。这听起来不太可能——因此您可能需要正确地进行合并,从每个分支的下一个到最后一个提交开始工作。

你还需要决定你真正想要做什么。

听起来您想将一些分支(称为 BranchA、BranchB 和 BranchC)合并到主分支上,master。但目前尚不清楚您是否尝试过。

鉴于事情有些混乱,我建议创建另一个我们可以称之为“Fixup”的分支。从 master 分支的头部创建它。然后,将 BranchA、BranchB 和 BranchC 的相应版本合并到 Fixup 分支中。在每个阶段,检查代码是否确实正常工作 - 通过其测试套件等。在 Fixup 分支上分别检查每个合并。

当你满意Fixup分支正确后,切换回master分支,将Fixup分支合并到master。


Charles Bailey 提出了非常明智的建议(在对问题的评论中):在您做任何其他事情之前,请按照当前的状态备份您所拥有的内容。然后才继续进行任何清理操作。而且他提出的获得互动帮助的建议也很明智。

【讨论】:

    【解决方案3】:

    Git 的一大优点是您可以轻松复制整个工作存储库。这允许您在尝试分支和合并时保留备份副本。

    我建议的解决您当前问题的方法:

    1. 创建整个存储库的备份副本
    2. 使用存储库的一次性副本进行实验
    3. 每次您搞砸了一个废弃的存储库 - 把它扔掉并从您的备份中重新开始一个新副本
    4. 最终,您将开始掌握 repo hacking - 您将恢复您的工作,并且您会对所学的知识感到满意

    另外,我希望您使用 gitk(或类似工具)来查看您的更改的效果——它确实可以帮助您可视化不同的代码行以及它们之间的关系。

    gitk --all ## show me all the branches
    

    【讨论】:

    • 还有(甚至更好?):gitk --reflog -- 我认为这是一个新功能,但非常有用。
    【解决方案4】:

    错误:

    1. “我开始在我的新项目中使用 git”
    2. “我只是想合并它们,因为它们中的每一个都是对程序不同部分的更新”

    当您的代码有意义时,您不应该在不熟悉的领域玩耍。如果你想这样做,至少要有一个后备计划。

    灾难恢复似乎只对最需要它的人很重要,但到那时为时已晚。

    我完全赞成实验,但我讨厌看到这种情况,我为开发人员感到难过,因为我太了解他的鞋子了,但是一旦你知道了这个错误,你就永远不会忘记它。

    在你决定玩之前,把你的代码扔到别的地方,这样当你大吃一惊时,你就可以回到自己的舒适区,继续作为一个快乐的开发者工作,并在完成工作后继续玩完成。

    【讨论】:

    • 虽然我同意你的观点,但这不是问题的答案。它应该作为评论发布(尽管我知道 cmets 无法容纳这么多文本)。
    • 我最初开始输入评论并用完了空间。 :-/
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-06-19
    • 2013-10-23
    • 1970-01-01
    • 2017-08-03
    • 2021-09-19
    • 2021-11-05
    • 2016-02-15
    相关资源
    最近更新 更多