Azure DevOps 服務 |Azure DevOps Server |Azure DevOps Server 2022
Git 是一個受歡迎的分散式原始碼倉庫(repo),讓使用者在斷線狀態下也能使用完整原始碼庫。 Git 的優點已經有充分的紀錄,但如果你需要在主要儲存庫上「回溯」怎麼辦? 這樣做並不直覺,需要提升權限。 這個要求是預期中影響所有儲存庫使用者的狀況。
如何安全地回滾中央資料庫?
問題情境
想像你將一個大型檔案(例如影片)提交到你的 Git 伺服器。 在傳統的原始程式碼系統中,將所有內容儲存在一個地方,然後下載所需的內容,是很方便的。 使用 Git 時,整個倉庫會複製到每位使用者的本地電腦。 對於大型檔案,專案中的每位使用者都必須下載這些大型檔案。
隨著每一個大型檔案被提交到伺服器,問題只會越來越嚴重。 資源庫變得過於龐大,對使用者來說運作效率不佳。 即使你從本地倉庫移除大檔案並重新提交,該檔案仍然存在於倉庫的歷史紀錄中。 因此,該檔案仍會被下載到每個人的本地電腦,作為歷史紀錄的一部分。
把一個大檔案加入本地倉庫。
當你從本地倉庫提交後,伺服器也會保留那個大型檔案。
凍結存放庫
為了解決大型儲存庫的問題,必須從源代碼著手。 在這種情況下,來源是伺服器儲存庫。 請團隊停止推送到儲存庫。 在此過程中,如果發生更多推送,您必須將其納入考量,以防止資料遺失。
這很重要
以下步驟會將影片從你的分支歷史紀錄中移除,但當你從 Azure Repo 複製倉庫時,該檔案仍會保留在你的倉庫歷史中。 從分支歷史中移除檔案會阻止檔案更新,導致檔案庫中產生另一個版本的大檔案。
了解更多關於 如何在 Git 中管理大型檔案。 關於使用 Azure Repos Git 倉庫時這種行為的解釋與變通方法,請參見「為什麼從 Visual Studio Team Services 複製會回傳舊的未被參考物件?」。
重設基底並強制推送
如果團隊中沒有人對資源庫做任何更改,這些更改通常是透過推送進行的,因此你可以選擇比較簡單的方式。 基本上你讓你的本地倉庫看起來符合你想要的樣子(也就是說,沒有那個大檔案)。 然後你強制將變更推送到伺服器。
你可能需要先複製或修復本地倉庫,才能開始這項工作。 此過程可能導致工作遺失或變更,請謹慎進行。
預設情況下,你可以修改本地專案檔案並將變更推送到伺服器,但無法執行伺服器層級的操作,例如刪除或重新建立基底。 要繼續,您需要擁有強制推送的權限(建議)或存取管理員權限。 聯絡你的專案管理員申請這些權限,或請已有權限的人協助。 如需詳細資訊,請參閱 設定 Git 存放庫許可權。
接著,你需要重新建立倉庫的基礎。
用
git log來查找最近提交的安全雜湊演算法(SHA)雜湊值。 你現在需要這些資訊,因為你需要知道最近的好承諾。 你可以透過開啟 Git 指令字元輸入以下資訊來取得這些資訊:git log或者,你也可以從 Visual Studio 團隊檔案總管的分支歷史中取得 SHA 雜湊值。
打開 Git 命令提示字元。
找出感興趣的 SHA 雜湊號。
你需要一個開始
25b4的 SHA 。請記得 Git 會用指標來判斷 head 或目前分支在倉庫中的位置。 你感興趣的儲存庫狀態存在於過去的某個時刻。
要回到過去,將先前的狀態設為新的當前狀態,請使用指令:
git rebasegit rebase -i <SHA hash of desired new current branch>
這個
-i開關能在編輯器中調出歷史記錄,提供額外的安全保障。 (本文使用了一個 Git 實作,能在 Windows 命令列中啟動經典的 vi 編輯器。如果你使用過基於 Unix 的系統,可能會記得它。)在這個例子中,你輸入:
git rebase -i 25b4編輯器出現後,移除所有
pick行,只保留你想作為新主幹的分支。 當一切看起來都正確時,在 vi 裡輸入:w\<enter\>儲存,或者輸入!q\<enter\>退出不儲存。
改變你不再想要的線條。
請更改
pick為drop如圖所示。 接著在 vi 中輸入:w以儲存,輸入:q!開始變基。現在再次輸入
git log。 違規的分支應該不在日誌中。 如果是,那你就準備好進入最後一步了,這需要專案管理員權限:git log
大影片的提交現在已經從本地儲存庫消失了。
輸入下列命令:
git push --force
這個指令會強制你的儲存庫覆寫伺服器上的儲存庫。
使用此指令時要小心,因為你很容易在伺服器上遺失資料。
你必須向伺服器驗證,這個動作才會生效。
如果你用的是 Azure Repos,可能需要設定一個不使用特殊字元的替代憑證。 例如電子郵件地址中的 at 符號(@)。 要完成此任務,請依照 Azure Repos 認證中的指示操作。
現在該分支已永久從伺服器消失。 專案團隊成員後續的複製和同步不會下載你想移除的大檔案。 使用者需要從伺服器下載更新,確保與新的伺服器儲存庫狀態同步。
如果使用者有較新的提交記錄
如果其他使用者將提交推送到伺服器儲存庫,你還有需要考慮的因素。 你想移除包含大型檔案的分支,但又不想失去團隊所做的變更。 為了解決這種情況,當你在執行 rebase 時打開編輯器,仔細查看提交記錄。 請確保你想保留的提交在 pick 行上列出。 刪除你想移除的部分,例如新增大型檔案的位置。
重新建立資料庫後,團隊中的其他使用者也需要重新建立,確保每個人都有一致的伺服器儲存庫副本。 這項工作對每個人來說都很繁瑣,你最好避免。 如果你需要移除一個推送,就必須和團隊協調。 欲了解更多關於重新基底的資訊,請參見 Git 分支 - 重新基底。
關鍵是要確保你清楚哪些提交是你需要的,哪些提交是你不需要的。 研究 git log 或你整合開發環境中的歷史(例如 Visual Studio)。 仔細記錄要保留和刪除的 SHA 雜湊值。
如果大檔案很舊,且後來有分支和合併,你可能可以透過切換器移除檔案 git filter-branch 。 欲了解更多資訊,請參閱 「從儲存庫移除敏感資料」。
最佳實務考量
確保大型檔案不要進入主倉庫,這樣可以省下團隊成員的額外工作。 以下是團隊應該記住的一些常識性最佳實務。
活動
- 經常提交變更。 你之後可以用南瓜或重新定基來修補。
- 使用分支來進行變更的隔離。 分支機構便宜,私人,合併很簡單。 您也可以將變更推送至伺服器,以備份分支上的變更。
- 發佈主題分支時,請使用命名規則。 請說出分行
users/<alias>/<branchname>名稱。 這個名稱有助於分行分類,也方便其他人辨識擁有者。 - 記得要推動你的改變。 使用
Commit != Checkin和(Commit + Push) == Checkin。 - 考慮使用
.gitignore對於大型二進位檔,以避免將它們加入版本庫。 更多資訊請參見 「忽略檔案」。 - 考慮使用 NuGet 或 Team Foundation Server 版本控制來儲存大型二進位檔。
要避免的事項
- 推送之後不要重新設定基底。 在 Git 中重新基底已推送的提交可能會造成不好的影響,因為它會迫使儲存庫中的其他人需要重新整理他們的本地變更。 團隊成員若必須執行這項任務,可能不會感到高興。 在你自己的分支上重新設定推送提交,即使推送了,也沒什麼問題,除非其他人拉取這些提交。
- 請勿將二進位檔提交至倉庫。 Git 不像 Team Foundation 版本控制那樣壓縮二進位檔案。 因為所有 repo 都有完整的歷史紀錄,提交二進位檔案會導致永久的臃腫。
總結
有時會加入不受歡迎的元素,例如大型檔案,必須移除以保持儲存庫的乾淨和輕量。 你可以透過整理本地的代碼庫來完成這項工作。 使用 git rebase 指令,然後使用 git push --force 指令將伺服器倉庫覆蓋為本地倉庫。