来自svn,刚开始熟悉git。
当在 git 中删除一个分支时,它会从历史记录中删除吗?
在 svn 中,您可以通过还原删除操作(反向合并)轻松恢复分支。像 svn 中的所有删除一样,分支从未真正删除,它只是从当前树中删除。
如果分支实际上是从 git 的历史记录中删除的,那么从该分支合并的更改会发生什么?他们被保留了吗?
来自svn,刚开始熟悉git。
当在 git 中删除一个分支时,它会从历史记录中删除吗?
在 svn 中,您可以通过还原删除操作(反向合并)轻松恢复分支。像 svn 中的所有删除一样,分支从未真正删除,它只是从当前树中删除。
如果分支实际上是从 git 的历史记录中删除的,那么从该分支合并的更改会发生什么?他们被保留了吗?
分支只是 git 中提交的指针。在 git 中,每个提交都有一个完整的源代码树,它与 svn 的结构非常不同,在 svn 中,所有分支和标签(按照惯例)都位于存储库的单独“文件夹”中,旁边是特殊的“主干”。
如果分支在被删除之前被合并到另一个分支,那么当第一个分支被删除时,所有提交仍然可以从另一个分支访问。它们保持原样。
如果分支在没有被合并到另一个分支的情况下被删除,那么该分支中的提交(直到仍然可以访问的提交的分叉点)将不再可见。
提交仍将保留在存储库中,并且可以在删除后立即恢复它们,但最终它们将被垃圾收集。
在 Git 中,分支只是提交的有向无环图 (DAG) 中提交的指针(引用)。这意味着删除分支只会删除对提交的引用,这可能会使 DAG 中的某些提交无法访问,从而不可见。但是,在已删除分支上的所有提交仍将在存储库中,至少在无法访问的提交被修剪之前(例如使用git gc
)。
请注意,git branch -d
如果无法确定删除分支不会留下无法访问的提交,它将拒绝删除分支。如果分支可能留下无法访问的提交,您需要使用 stronggit branch -D
强制删除分支。
另请注意,如果存在无法访问的提交,则它们只是已删除分支的最后一个提示与合并到另一个现有分支的提交、任何标记的提交或分支点之间的提交;以较晚者为准。例如在以下情况下:
----O----*----*----/M----* <-- master <-- HEAD \ / \--.----.--/--x---y <-- 删除的分支
只有提交 'x' 和 'y' 会在删除分支后变得无法访问。
如果您在此gc.reflogExpire
期间(默认 90 天)内对已删除的分支进行操作,您将在 HEAD reflog 中记录已删除分支的最后一个提示(请参阅git reflog show HEAD
、 或git log --oneline --walk-reflogs HEAD
)。您应该能够使用 HEAD reflog 来恢复已删除的指针。gc.reflogExpireUnreachable
另请注意,在这种情况下,仅在已删除分支中无法访问的提交将在此期间(默认为 30 天)内免受修剪(删除) 。
如果在 HEAD 的 reflog 中找不到刚刚删除的分支的尖端,您可以尝试使用git fsck
查找“无法访问的提交 <sha1>”,并检查那些(通过git show <sha1>
或git log <sha1>
)以找到已删除分支的尖端。
独立于您如何找到已删除分支的尖端,您可以撤消删除,或者使用重新创建刚刚删除的分支
git branch <deleted-branch> <found-sha1-id>
但是请注意,分支的 reflog 会丢失。
还有一个git-resurrect.sh脚本,contrib/
它可以帮助找到具有给定名称的分支提示的痕迹并复活(取消删除)它。
如果您担心意外删除的分支并且不再拥有您的 repo 的本地副本,可以使用 Gerrit 等企业 Git 服务器的扩展来检测历史记录重写和分支删除,并将它们备份到一个特殊的 ref 下,以便它们如果需要可以恢复,并且不会被垃圾收集修剪。如果出于法律原因需要,Gerrit 管理员仍然可以删除选定的提交。