【问题标题】:How did my git branch forget its parent?我的 git 分支是如何忘记它的父级的?
【发布时间】:2012-11-30 18:46:34
【问题描述】:

我以通常的方式创建了一个 git 功能分支:

git checkout develop
git checkout -b new_feature_branch

当将功能合并回主开发分支时,合并产生了大量冲突(由于主线没有太大变化,因此超出预期)。

经过调查,我的功能分支似乎以某种方式成为其父级的孤儿。历史记录中缺少该分支的前 24 次提交,主线的初始分叉也是如此。

我知道这恰好是 24 次提交,因为它们在 git reflog --all | grep new_feature_branch 中列出。

由于缺少这些早期提交,分支现在似乎从整个存储库的副本开始,当我尝试将其合并回开发时会产生很多冲突。

这是怎么发生的?

如何恢复丢失的提交?

【问题讨论】:

  • 你是git branch -b 还是git checkout -b
  • 糟糕。不,是git checkout -b。谢谢!

标签: git


【解决方案1】:

这是怎么发生的?

  • 您从 develop 分支 - 您确定您的本地副本(而不是 origin/develop)在您分支时是最新的吗?
  • develop 绝对是您想要的父分支(不是master 或其他)?
  • 你在分支后是否对develop 进行了rebase?这可能会重写 develop 中的父提交,而不是 new_feature_branch 的历史记录。
  • 您是否曾在某个时间点变基 new_feature_branch,并以这种方式在您的分支点之前不小心重写了父提交?

如何恢复丢失的提交?

只需将您的分支重新设置为所需的分支点(请参阅this questionthis book 等)

【讨论】:

  • 感谢您的参考。 rebase --onto 是解决方案的一部分(发布了完整的步骤)。这仍然是一个谜。我通常不使用 rebase,并且当我创建它时,repo 肯定是最新的。
【解决方案2】:

要恢复,只需使用graft or a replace,它允许您重新指定孤立分支的基(根)的父级。

如果您不需要在合并后保留功能分支,那么简单的一次性移植就足以让您看到正确的分支结构。

但是,合并时的父链接仍将保留孤立分支,并且您的 repo 将有两个根提交 [可能不是您想要的]。

简单的改进是在移植后做一个rebase(你的孤儿到其正确的分支点)或filter-branch

听起来您不小心检查了原始分支点的特定提交而不是创建分支(提示),因此您遇到了detached HEAD 的情况,并且在一些错误消息后以不适当的顺序进行了修复- 很容易做到。

【讨论】:

    【解决方案3】:

    好的,这就是我修复它的方法:

    1. 运行 git reflog --all | grep <new_feature_branch> 以获取功能分支上的完整提交列表,包括历史中丢失的早期提交。
    2. 打开 .git/logs/HEAD 并搜索最旧的可见提交以找到其原始父级 (hat tip) 的完整 SHA。
    3. 签出父提交(现在从分支的历史记录中丢失的那个),然后从该提交中签出一个新的“恢复”分支以创建一个新的基础。完成此操作后,“丢失”的提交作为恢复分支的一部分重新出现在树中,并从开发分支正确分叉。
    4. 使用来自“孤立”分支的最旧提交运行git cherry-pick <SHA>,以将该分支的基础复制到恢复分支的顶端。解决合并冲突。
    5. 检查孤立的分支。
    6. 运行git rebase --onto <new-parent> <old-parent>,其中new-parent 是我刚刚复制到恢复分支的提交,old-parent 是我从中复制该提交的孤立分支上最旧的提交。完整的分支历史已成功移植,冲突最小。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-03-10
      • 2017-10-21
      • 1970-01-01
      • 1970-01-01
      • 2020-11-09
      • 2012-03-21
      • 2010-10-12
      相关资源
      最近更新 更多