【问题标题】:Does deleting a branch in git remove it from the history?删除 git 中的分支是否会将其从历史记录中删除?
【发布时间】:2010-04-10 15:43:14
【问题描述】:

来自svn,刚开始熟悉git。

当一个分支在 git 中被删除时,它会从历史记录中删除吗?

在 svn 中,您可以通过还原删除操作(反向合并)轻松恢复分支。像 svn 中的所有删除一样,分支从未真正删除,它只是从当前树中删除。

如果分支实际上从 git 的历史记录中删除,从该分支合并的更改会发生什么?是否保留?

【问题讨论】:

    标签: git version-control branch revision-history


    【解决方案1】:

    分支只是 git 中提交的指针。在 git 中,每个提交都有一个完整的源代码树,它与 svn 的结构非常不同,在 svn 中,所有分支和标签(按照惯例)都位于存储库的单独“文件夹”中,旁边是特殊的“主干”。

    如果分支在被删除之前被合并到另一个分支,那么当第一个分支被删除时,所有提交仍然可以从另一个分支访问。它们保持原样。

    如果分支在没有合并到另一个分支的情况下被删除,那么该分支中的提交(直到仍然可以访问的提交的分叉点)将不再可见。

    提交仍将保留在存储库中,并且可以在删除后立即恢复它们,但最终它们将被垃圾回收。

    【讨论】:

    • 感谢您的回答。您能否澄清“每个提交都有一个完整的源代码树”的意思?据我了解,git 中的每个提交都是一组增量,它们引用父提交,而不是整个树。
    • @Ken Liu:提交包含指向零个或多个父提交的指针、一个树对象和一些关于提交的元数据。因此,提交唯一地标识了一对源树,并且在查看其父级时,它引入了更改。
    • @Ken Liu:这完全取决于您的“包含”,但是是的,基本上每个提交都包含一个完整的树。在对象数据库中,对象由 id 索引,因此对象在引用它们的所有对象(树和提交)之间共享,因此隐含的存储开销并不像最初听起来的那么糟糕。 git 还具有高效的存储优化(打包文件),可以更有效地使用磁盘空间。
    • “最终它们将被垃圾回收” - 最终何时?
    • @BadHorsie, it depends.
    【解决方案2】:

    在 Git 中,分支只是指向提交的有向无环图 (DAG) 中的提交的指针(引用)。这意味着删除分支只会删除对提交的引用,这可能会使 DAG 中的某些提交无法访问,从而不可见。但是,在已删除分支上的所有提交仍将保留在存储库中,至少在无法访问的提交被修剪之前(例如,使用 git gc)。

    注意git branch -d 会拒绝删除一个分支,如果它不能确定删除它不会留下无法访问的提交。如果分支可能留下无法访问的提交,您需要使用更强的git branch -D 来强制删除它。

    还要注意,如果存在无法访问的提交,则它们只是已删除分支的最后一个提示与合并到另一个现有分支的提交、任何标记的提交或分支点之间的提交;以较晚者为准。例如以下情况:

    ----O----*----*----/M----*

    只有提交 'x' 和 'y' 会在删除分支后变得无法访问。

    如果您在 gc.reflogExpire 期间(默认 90 天)内对已删除分支进行操作,您将在 HEAD reflog 中记录已删除分支的最后提示(请参阅 git reflog show HEADgit log --oneline --walk-reflogs HEAD)。您应该能够使用 HEAD reflog 来恢复已删除的指针。另请注意,在这种情况下,仅在已删除分支中无法访问的提交将在 gc.reflogExpireUnreachable 期间(默认为 30 天)内受到保护,不会被修剪(删除)。

    如果在 HEAD 的 reflog 中找不到刚刚删除的分支的提示,可以尝试使用 git fsck 查找“无法访问的提交 ”,并检查这些(通过 git show <sha1> 或 @987654331 @) 找到被删除分支的尖端。

    根据您如何找到已删除分支的尖端,您可以撤消删除,或者使用重新创建刚刚删除的分支

    git branch <deleted-branch> <found-sha1-id>
    

    但请注意,分支的 reflog 会丢失。


    contrib/ 中还有一个 git-resurrect.sh 脚本,它可以帮助找到具有给定名称的分支提示的痕迹并恢复(取消删除)它。

    【讨论】:

    • 太棒了! git reflog show HEAD 列出了提交,就像你说的那样,我创建了一个新分支,完美。
    【解决方案3】:

    如果您担心意外删除的分支并且不再拥有您的 repo 的本地副本,可以使用 Gerrit 等企业 Git 服务器的扩展来检测历史记录重写和分支删除,并将它们备份到一个特殊的 ref以便它们可以在需要时恢复,并且不会被垃圾收集修剪。如果出于法律原因需要,Gerrit 管理员仍然可以删除选定的提交。

    【讨论】:

      猜你喜欢
      • 2016-03-13
      • 1970-01-01
      • 1970-01-01
      • 2023-02-09
      • 1970-01-01
      • 2014-06-19
      • 2020-03-20
      • 1970-01-01
      • 2023-01-30
      相关资源
      最近更新 更多