【问题标题】:Is it safe to delete merged branch in git在git中删除合并的分支是否安全
【发布时间】:2016-08-12 10:33:13
【问题描述】:

假设我们在分支中开发了一个特性,认为它已经完成,将其合并到 master 并删除分支。后来在此特定功能中发现了错误,并且有人去重置全局存储库上的 HEAD(您不应该这样做)。现在,我们本可以修复该错误,但不再拥有分支,并且整个功能都丢失了。有没有办法恢复这些更改,合并后保留功能分支一段时间总体上是个好主意吗?

【问题讨论】:

  • 没有人的克隆仍然包含合并提交?

标签: git github merge


【解决方案1】:

假设在合并之前提交历史是这样的。

feature合并到master后,变成了这个。

现在分支feature已经被删除了,一直是这个样子。

正如我们所见,feature 的提交历史仍然存在,尽管 ref feature 已经消失。分支 ref 只是一个变量,它存储从那时到现在它指向的提交的 sha1 哈希值。

M 是在将feature 合并到master 时创建的合并提交(仅当它是真正的合并,非快进合并时)。它有两个父级,D 第一个父级,master 指向,F 第二个父级,feature 指向。如果我们将master 合并到feature 并创建M,那么F 是第一个父级,D 是第二个父级。

M^ 可以引用第一个父级,M^2 可以引用第二个父级。

现在如果你想重新创建分支引用feature,假设M 的值为af2343242,你可以运行git branch feature af2343242^2。它会再次像这样。

合并一段时间后保留特征分支总体上是个好主意

这取决于。有些人认为保留曾经存在的所有更改是件好事,包括所有提交和所有分支、标签等。毕竟,这些都是项目的宝贵遗产。

【讨论】:

    【解决方案2】:

    示例

    使用发布分支。比如说,当你在项目开发中达到一个重要的里程碑(完成并合并一个新功能)到生产等中时。

    创建标签

    git tag -a v1.0.0 -m "v1.0.0"
    

    现在,假设您继续工作并开始了一项新功能,一段时间后您意识到存在一个错误,该错误已与您之前合并的该功能一起引入。合并删除后如何恢复?

    让我们回到我们在合并新功能时创建的标签

    git checkout v1.0.0
    

    我们不能直接提交到 tag,但我们可以从中创建一个新分支(release 分支)。

    git checkout -b rb1.0.0
    

    现在我们可以应用 hot fix 然后添加并提交我们的更改到分支

    git add <file> <file> 
    git commit -m "<hot fix message>"
    

    此时剩下的就是合并热修复。所以,我们回到master分支,合并release分支

    git checkout master
    git merge rb1.0.0 -m "Merged <hot fix message>"
    

    为了保持整洁,此时我们还将删除 release 分支

    git branch -d rb1.0.0
    

    【讨论】:

      【解决方案3】:

      是的,保留特性分支一段时间通常是个好主意,至少在你 100% 确定你永远不会回去之前。

      它不会伤害任何东西或占用任何资源。分支只是指向提交的小便签。它在git 内部的唯一作用是防止垃圾收集器不可恢复地删除它指向(及其祖先)的提交。

      对于您当前的情况,我将简单地创建一个分支(或标记)指向 master 的错误版本,然后将 master 重置回合并点后面。然后你就准备好了 - git 不会自动删除你否则“丢失”的分支,你可以在准备好后回到它。

      当然,如果你想从中创建一个“真正的”分支,你需要在合并之前在分支端找到提交,然后执行git branch mybranch &lt;hash&gt;,这可能是最佳选择。

      【讨论】:

      • 它不会伤害任何东西或占用任何资源它会占用认知资源,当你注意到你的 repo 有 79 个分支时,会以那种旧的“WTF”感觉的形式出现,有些可以追溯到六个月前。
      • 为什么你的 repo 中的分支数量会占用认知资源?
      • “通常切断一个分支只会释放一个非常小的、不可预测的空间。”在stackoverflow.com/questions/13722076/git-disk-usage-per-branch 得到这个,我同意@Anoe,它不会伤害任何东西或占用任何资源。
      • 有用的答案,但强烈不同意 70 多个合并的、陈旧的分支不占用“认知”资源,如果我在 Github 上查看我的分支列表,我希望看到的分支是积极工作,我不想筛选 70 个分支(无论排序如何),只是为了找到我正在寻找的一个分支。
      【解决方案4】:

      您可以使用 reflog 恢复所有提交。请参阅以下链接。

      http://gitready.com/advanced/2009/01/17/restoring-lost-commits.html

      链接摘录:

      例如,考虑以下回购:

      $ git show-ref -h HEAD
        7c61179cbe51c050c5520b4399f7b14eec943754 HEAD
      
      $ git reset --hard HEAD^
        HEAD is now at 39ba87b Fixing about and submit pages so they don't look stupid
      
      $ git show-ref -h HEAD
        39ba87bf28b5bb223feffafb59638f6f46908cac HEAD
      

      现在 HEAD 被移回 1 个提交。让我们看看 git 是否知道被删除的提交。

      $ git reflog
        39ba87b... HEAD@{0}: HEAD~1: updating HEAD
        7c61179... HEAD@{1}: pull origin master: Fast forward
        [... lots of other refs ...]
      

      所以,我们现在有了 SHA1:7c61179。如果我们想立即将它应用回我们当前的分支,执行 git merge 将恢复提交:

      $ git merge 7c61179
        Updating 39ba87b..7c61179
        Fast forward
          css/screen.css |    4 ++++
          submit.html    |    4 ++--
          2 files changed, 6 insertions(+), 2 deletions(-)
      

      此命令将恢复丢失的更改并确保 HEAD 指向提交。从这里您可以继续正常工作!

      【讨论】:

      • 更新了答案。谢谢你的指导。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-08-23
      • 1970-01-01
      • 2017-01-24
      • 2012-06-01
      • 2012-02-24
      • 2013-12-13
      相关资源
      最近更新 更多