在 Git 中使用reset 可以讓當前分支回滾(reset)到任何一個歷史版本, 直接移除那以後的所有提交。但這更改了 Git 的歷史,Git 服務通常會禁止這樣做。 這便需要一個更安全的方式將代碼狀態回到歷史版本,同時不更改 Git 歷史。
所謂 保護分支 ,就是指不允許改寫 Git 歷史的分支。在 Github 中對應的選項是 Force Pushes,該選項默認處於 Disallow 狀態。
找到歷史版本
首先,通過git log 確認你要回滾到的版本的 commit hash。 例如,我們有 4 個版本其中後兩個是壞的,要回滾到 version 2,它對應的 commit hash 就是 4a50c9f :
簽出歷史版本
為了便於操作,我們給這個版本一個分支名,比如 v2 :
現在就已經位於 v2 分支啦,當前的 Git 記錄如下,比上一步只是多了一個分支名:
假合併 master
為了不更改 Git 記錄,我們只能生成一個新的 Commit 讓代碼狀態回到 v2。 這意味着必須在 version 4 的基礎上進行,思路和手動操作無異。 但我們可以通過一個神奇的合併操作自動完成:
-s <strategy> 用來指定合併策略,ours 是遞歸合併策略的一種,即直接使用當前分支的代碼。 -s ours 合併的結果是產生了一個基於 master 的 Commit,但 HEAD 中的代碼與合併前完全相同 。 從 Git 記錄可以看到 version 2 和 version 4 進行了合併:
但合併中完全採用了 version 2 的代碼,即合併前後 diff 為空:
至此我們已經產生了一個 代碼狀態與歷史版本完全一致,但基於 master 的一個 Commit 。
push 到遠程
在產生可用的 Commit 後,可以從當前分支 v2 直接發往 origin/master:
更詳細的遠程倉庫操作可以參考遠程倉庫 一文。