簡體   English   中英

永久刪除 git 分支 bitbucket

[英]Permanently deleting a git branch bitbucket

有沒有辦法永久刪除遠程 git 分支,無法通過任何方式恢復。 我正在開發一個存儲庫並想刪除其中的分支,但我希望以不應該恢復的方式刪除它。 它不是master分支。 我只想永久刪除它,沒有機會恢復。

這取決於。

分支是一個邏輯實體,一個指向歷史中提交的指針,為方便起見而標記。 然后每個提交都指向它的父級,按照這個層次結構,我們得到了我們大多數人所說的“分支”的意思。

您可以通過以下方式在遙控器上刪除它:

git 推送遠程名稱:分支名稱

如果您分支上的任何提交已合並到其他分支(通過快進或合並提交),則這些提交不會被刪除,除非您也想刪除其他分支,否則無法刪除。 如果您刪除的分支上有任何提交對它們有其他“引用”(即標簽),那么這些提交將不會被刪除。 沒有引用的提交最終會被垃圾收集器刪除。

但是,如果其他人已將您要刪除的分支提取到他們的本地存儲庫,即使您從遠程刪除它,他們也可以自由地檢查它,然后再次推送它。 如果他們在檢查之前完成了git remote prune remote_name ,則情況並非如此。

這是分布式源代碼控制系統的雙刃劍。

刪除分支名稱很容易(至少在您控制存儲庫的情況下)。 但是 Git 本身並不是關於分支的。 Git 都是關於提交的。 要了解刪除分支名稱意味着什么,您必須了解 Git 如何找到提交,以及 Git 對無法訪問的提交做了什么。 無法訪問的提交最終會被收集和丟棄。 Reachable commits 仍然存在,如果一個已經變得不可達的 commit 沒有被立即丟棄,任何人都可以添加一個名稱使其再次可訪問,之后它不會被丟棄。 而且,當然,提交可以復制到其他存儲庫,只要他們願意,它們可以保留這些提交。

要刪除您自己的 Git 中的分支名稱,請使用git branch -dgit branch -D 這些之間的區別在於-D強制刪除:即使您的 Git 說“這會使提交無法訪問”,也可以刪除。 (在這兩種情況下,您都不能簽出該特定分支。Git 不會讓您看到您所在的分支。)

要將刪除請求發送到其他 Git,請使用git push

git push <url-or-remote> :<name>

或者:

git push --delete <url-or-remote> <name>

他們可能會也可能不會遵守刪除該名稱的請求。

長(ish)

請記住,每個提交都有自己的、獨特的、又大又丑的 hash ID。 That hash ID is universal across every Git: if you've created a new commit whose hash ID is a123456... , and I obtain that commit from your Git, I now have the commit whose hash ID is a123456... . 但是 hash ID看起來完全隨機。 1我要如何記住這個ID?

Git 記住提交 hash ID 的主要“地方”有兩個:

  • 首先,每個提交都存儲其直接前任的原始 hash ID。 Git 將這些稱為提交的父母 大多數提交只有一個父級。 我們說提交指向其父級,但實際上,提交只是將其前身的實際 hash ID 作為其自身的一部分。

  • 然后(對您的問題至關重要)分支名稱僅存儲提交鏈中最后一次提交的 hash ID。 從最后一次提交中,Git 可以找到父 hash ID。 Git 可以使用該父 hash ID 來查找一個較早的提交。 That earlier commit has a parent hash ID, which lets Git step back again, which provides another hash ID, which lets Git step back again, and so on, all the way back to the very first commit.

我們可以畫這個。 如果我們使用真正的 hash ID,那會很亂,所以我們根本可以不使用名稱:

... ←●  ←●  ←●  ←●  ←branch

或替換為單個字母:

... <-F <-G <-H   <--branch

刪除分支名稱時得到的是:

... <-F <-G <-H

由於沒有名稱可以找到 hash 為H的提交,我們也無法找到提交G或提交F或任何早期提交。

但也許branch不是唯一可以找到提交的分支名稱。 例如:

...--F--G--H   <-- branch
            \
             I--J   <-- branch2

刪除名稱branch很好,但我們仍然可以從名稱branch2開始並找到提交J ,這讓我們找到I ,這讓我們找到H 所以H畢竟什么都沒有發生,除了name branch不再直接指向提交H

除此之外,標簽還指向(單個)提交,還有其他方法可以命名或查找提交,例如通過git stash遠程跟蹤名稱(一個 Git 的其他 Git 分支名稱的副本)等等。

刪除一個名字所做的就是去掉那個名字 如果這是找到提交的唯一方法,那么提交仍然存在,但 Git 稱它為unreachable

如果有 hash ID 隱藏在某處——寫在紙上,或者在屏幕上的 window 中,或者其他任何地方——你仍然可以通過它的 Z0800FC577294C34E0B28AD283943594 直接找到提交。 假設branch2指向一個指向H的提交,並且H沒有其他名稱:

          H   <-- branch
         /
...--F--G
         \
          I--J   <-- branch2

如果您刪除名稱branch ,則提交H變得無法訪問,而通過G的提交,加上IJ ,仍然可以通過名稱branch2訪問。 但是你的屏幕上仍然有 hash ID H ,所以現在你用鼠標抓住它並將其粘貼到命令中:

git branch resurrect <hash-of-H>

你現在有了這個:

          H   <-- resurrect
         /
...--F--G
         \
          I--J   <-- branch2

您的分支已以新名稱復活!

如果你這樣做——如果你刪除了 name branch並且不拯救被放棄的提交H ,並且在 Grim Collector git gc出現並收獲它之前沒有其他人保存H —— H消失了完全來自這個 Git 存儲庫。 同時,提交H是找不到的,除非您使用其原始 hash ID(或返回到提交H稍后提交的原始hash ID),否則您將看不到它。

但是 Git 是分布式的。 如果我您刪除所有可以找到H的名稱之前出現,並在的存儲庫中為自己獲取H的副本,並給自己一個可以找到H的名稱,您的 Git 可能會從您的存儲庫中刪除H - 最終——但仍然會擁有它。 我可以把它交給另一個 Git,或者寄回給你的 Git。

GCed 提交的速度取決於很多因素。 如果你從服務器 Git 中刪除一個分支,它往往會很快 GC 新無法訪問的提交。 如果你從你自己的命令行操作的 Git 中刪除名稱,它往往會更慢地對它們進行 GC。 3

如果您擺脫分支名稱所發現的某些提交的原因是它們泄露了重要的安全細節,那么您應該認為安全性受到了損害。 但是,如果只是它是垃圾,那么,刪除,並希望沒有人抓住垃圾的副本,然后將垃圾推回給你。


1 Hash ID 實際上根本不是隨機的:每個 ID 都是底層提交 object 全部內容的加密校驗和。 就是它們在每個 Git 中通用的方式。 如果我有你的提交,我會通過其內容的相同校驗和來獲得它。 如果你有我的,你有它校驗和。

2 git gc ,垃圾收集器,作為提交的死神,但實際上由運行一系列仔細排序的低級命令組成。 這些才是真正擺脫無法訪問的提交。

3您的 Git 使用reflogs來包含額外的、隱藏的、對提交 hash ID 的引用。 當前刪除分支名稱也會刪除該分支的 reflog,但不會刪除 HEAD reflog,因此 HEAD reflog 可以使提交保持活動至少 30 天。 服務器 Git 存儲庫通常根本沒有 reflog,這避免了至少 30 天的保存。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM