来自 svn,刚刚开始熟悉 git。
当在git中删除分支时,它是否会从历史记录中删除?
在svn中,您可以通过恢复删除操作(反向合并)轻松恢复分支。与 svn 中的所有删除一样,分支从未真正删除,它只是从当前树中删除。
如果该分支实际上从 git 的历史记录中删除,那么从该分支合并的更改会发生什么?他们被保留了吗?
分支只是 git 中提交的指针。在 git 中,每个提交都有一个完整的源代码树,它与 svn 的结构非常不同,其中所有分支和标签(按照惯例)都位于存储库的单独“文件夹”中,旁边是特殊的“主干”。
如果该分支在被删除之前已合并到另一个分支中,那么当第一个分支被删除时,所有提交仍然可以从另一个分支访问。它们保持原样。
如果删除分支而没有合并到另一个分支中,则该分支中的提交(直到从仍可访问的提交中分叉出来的点)将不再可见。
提交仍将保留在存储库中,并且可以在删除后立即恢复它们,但最终它们将被垃圾收集。
在 Git 中,分支只是指向提交的有向无环图 (DAG) 中的提交的指针(引用)。 这意味着删除分支只会删除对提交的引用,这可能会使 DAG 中的某些提交无法访问,从而不可见。 但已删除分支上的所有提交仍将位于存储库中,至少在无法访问的提交被修剪之前(例如使用
git gc
)。
请注意,如果无法确定删除分支不会留下无法访问的提交,则
git branch -d
将拒绝删除分支。 如果分支可能会留下无法访问的提交,您需要使用更强大的 git branch -D
来强制删除分支。
还要注意,无法访问的提交(如果存在)只是已删除分支的最后一个提示与合并到另一个现有分支的提交、任何标记的提交或分支点之间的提交;以较晚者为准。 例如以下情况:
----O----*----*----/M----* <-- master <-- HEAD \ / \--.----.--/--x---y <-- deleted branch
删除分支后,只有提交“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
来查找“unreachable commit git show <sha1>
或 git log <sha1>
)来查找已删除分支的尖端。
无论您如何找到已删除分支的尖端,您都可以撤消删除,或者使用
重新创建刚刚删除的分支git branch <deleted-branch> <found-sha1-id>
但请注意,分支的引用日志将会丢失。
contrib/
中还有
git-resurrect.sh脚本,它有助于查找具有给定名称的分支尖端的痕迹并复活(取消删除)它。
如果您担心意外删除分支并且不再拥有存储库的本地副本,可以使用 Gerrit 等企业 Git 服务器的扩展,它可以检测历史记录重写和分支删除,并将它们备份到特殊的引用下,以便如果需要,它们可以恢复,并且不会被垃圾收集删除。如果出于法律原因需要,Gerrit 管理员仍然可以删除选定的提交。
回应@CB Bailey的回答(https://stackoverflow.com/a/2613954/20422104)。如果标记一个提交,然后删除该分支,该提交会永远保留吗?
PS:为什么我需要更多的声誉来发表评论而不是回答?我想问一个后续问题,但因为我需要更多的声誉来发表评论,而不是提出/回答问题,所以我必须这样做并标记 CB Bailey,或者提出一个新问题...似乎是一个糟糕的系统,因为我们鼓励我提出尽可能多的问题,以提高我的声誉。