工作專案採用 Git 版控接 TFS 伺服器。我遇到一個狀況:TFS 主機早期曾建了一些實驗性質的分支(例如:feature/test),在本機端已刪除,在 TFS 上也用網頁介面刪掉了。但是,在我開發機 Visual Studio 的 remotes/origin 下 feature/test 分支始終存在,試著在 feature/test 分支按右鍵選單刪除遇到錯誤(猜想是因為伺服器端已刪除),這下可好,一個遠端不存在而我砍不掉的鬼分支。

於是我想到一招,那就把 origin 移掉 (Remove),再重加 (Add) 一次吧!

YA,feature/test 分支終於砍掉了。等等,不對! 整個 remotes/origin 都不見了。

這下跟伺服器形同失聯,而且我本機 master 所有同步過的 Commit 都變回等待 Push 的狀態。


(示意圖)

改用 Cmder 下指令 git remote add ... 也無效,甚至找了一些偏門技巧 - 手動修改 /refs/remotes/origin/HEAD 也沒救不回來,開始有點心慌。雖然這一年多下來,我對 Git 讓時光倒轉的能力很有信心,大部分的操作失誤,只要 .git 資料夾沒毁都有辦法救回來,但第一次遇到這種狀況,要怎麼恢復心裡沒譜。冷靜想了一下,最壞最壞我還有大絕招,本機工作都已 Commit 且 Push,大不了重新 Clone 回來,有王牌在手心裡篤定許多,平靜找答案。

答案出奇簡單,重新 Fetch 一次就好了:

就醬,remotes/origin 回來惹:

【2020-7-13 補充】記得要下指令 git branch -u origin/master master 將 orgin/master 設為本機 master 的上游,才能在 Visual Studio Team Explorer 直接按 Pull 拉回最新內容。

【後記】

後來我又做了實驗,對照 Fetch 後唯一的改變是 .git/refs/remotes/origin 資料夾下多了 master 這個 41 Bytes 的分支貼紙(借用龍哥的比喻):

手動將這個 master 檔案複製到新建的 .git/refs/remotes/origin/feature 資料夾,再更名成「人工移植分支」,我成功讓它出現在 Visual Studio 的 Team Explorer / Branches remotes/origin 下:

換言之,這回害我亂搞一波的 remotes/origin 分支砍不掉問題,其實刪除 .git/refs/remotes/origin/feature/test 分支貼紙檔就可以解決。但歷經這段經驗,我對 Git 的運作再多幾分了解,也不是沒有收獲。

【2020-07-28補充】感謝讀者 Danny Lin 分享更簡單的做法 - git fetch <remote> --prune--prune 會在 fetch 前移除所有遠端不存在的遠端追蹤參照(Remote-Tracking Reference)。

Case of how to recover the remotes/oring branches in VS after re-adding remote Git source.


Comments

# by 小糊塗

詢問「後記」下面那張圖,是甚麼工具阿,好酷歐?比對軟體?

# by Jeffrey

to 小糊塗,是 BeyondCompare,大推! 能為人生帶來光明的好工具,值得投資。

# by Danny Lin

要把 remote 端已砍掉但仍存在於 local 端的 remote tracking branches,用 git fetch <remote> --prune 應該就可以了。

# by Jeffrey

to Danny Lin,感謝分享,已加入本文。

Post a comment