1. 程式人生 > 程式設計 >如何使用Git優雅的回滾實現

如何使用Git優雅的回滾實現

開發過程中,我們經常會遇到程式碼回滾的情況。正常人都知道,git 回滾有兩大寶:

  • git revert
  • git reset

當我們在本地開發,還未 git push 到遠端時,可以毫無顧忌的使用 git reset 進行回滾。更多的情況中,我們不僅 push 了,而且由於開發週期長,在開發過程中不斷的 merge mastermerge other-branch 以釋出到預發環境測試或者多需求合併測試。

突然

上線後用戶投訴,需要馬上下線本次需求中的 A、B、C,只保留 D、E、F,迅速回滾,不要影響更多使用者。

撕逼?那肯定是來不及了。一群人在你背後眼巴巴地盯著你,就問你慌不慌...

接下來,我們來說說,如何在緊急回滾面前,鎮定(假)自若(裝)地進行 git 操作

簡單場景

本地操作使用 git reset 隨便玩玩就行了,我們主要講講 git revert

回滾“單一提交”

如何使用Git優雅的回滾實現

回滾“連續提交”

如何使用Git優雅的回滾實現

回滾一次“合併”

回滾合併時,如果直接使用 git revert mergeCommit 實際上是遞歸回滾裡面的每一個節點,指定 -m 是指定以哪一個分支為主線,當前所在分支為 1,依次類推(一次合併多個分支時會 > 2,正常只有 1 和 2)

如何使用Git優雅的回滾實現

高階場景

如果我們遇到的問題都像上面一樣,那怎麼能體現一個程式設計師的價值?

回滾“混合場景”

如以下場景中,我們期望迴歸的節點之間含有一次合併導致我們無法一次回滾到位。有兩種方式:

1. 按順序見招拆招回滾(三次操作)

2. 先回滾 D + F,再回滾合併(兩次操作)

如何使用Git優雅的回滾實現

【推薦】使用方案1,按順序回滾會處理更少的 conflict,否則假設 D、F 是一系列提交合集,那麼回滾成本很高

回滾有點複雜“混合場景”

如下的場景中,特殊的地方在於,我有一個 feature,搭車了一個 bugfix,我需要回滾需求但不回滾 bug

如何使用Git優雅的回滾實現

這種情況下,有兩種選擇:

回滾 G,通過 git 引一步一步回滾 F-F'-E‘-D'-C‘-E'‘(不滾)-D'‘(不滾)-C'‘(不滾) ,回滾 E+D 【推薦】回滾 G,回滾 F 丟棄 F',回滾 D+E,復原 C‘'..E‘' 比第一種方案更快更簡單,不用處理第一種方案中的 conflict

git revert G
git revert F -m 1
git revert D..E
git cherry-pick C``
git cherry-pick D``
git cherry-pick E``

回滾複雜的”混合場景“

如何使用Git優雅的回滾實現

標註解釋

  • 藍色代表已經合併到遠端分支 Master 生成了 tag
  • 紅色代表需要回滾的 commit
  • 綠色代表正常 commit

場景解釋 一開始你所在的團隊接到一個需求,這個需求中可以分拆出一個自需求,最終可以實現兩人並行開發

  • 兩個人 Pa 和 Pb 分別在 Master 基礎上建立了新分支
  • 在開發過程中 Master 上釋出了兩次 bugfix(v2、v3)
  • 由於需要在預發上持續測試,所以 Pa 主動合併了 Master
  • Pb 在自己分支 B‘ C' D‘ 中廢棄了之前的舊邏輯和一些程式碼的小幅重構(穩定性更新),之後 一直在本地開發新功能 & 驗證
  • 最後即將上線時需要合併自需求一起驗證,驗證後 Pb 釋出了 v3
  • 後續又經過了一次 bugfix 釋出了 v4
  • 結果,產品反悔了 WTF ???
  • 最後,要廢棄新功能,需要重新設計產品,但是舊有邏輯仍然按原計劃廢棄 >> F(v2) + B'-D'

回滾方式

遇到這樣的場景,一般有如下幾種方案回滾:

  • 回到最新的遠端 Master (v4) 手動識別需求程式碼進行人工刪除 刪除自己的程式碼還好,刪除別人的程式碼就有點難度了,而且當提交量很大時很耗時耗力
  • 複製 F(v2) 替換 Master(v4),手動或應用 B'-D‘ commit 圖示情況,直接複製貼上是個便捷的方法,再次回覆 B'-D' 也費不了多大事,只是手動操作難免失誤,尤其是增加/刪除檔案的情況,複製貼上容易出錯
  • 【推薦】按時序回滾(O'-T‘、L'‘、F'‘-K'‘^、B'‘-C'‘、E'-N‘) 版本控制本來就是為了程式碼管理更便捷,使用 git 操作後面的人不僅能看懂回滾了哪些 / 如何回滾的 / 怎麼處理回滾中的 conflict 的,如果回滾錯了還可以回滾“回滾了的”操作
git revert N`..S`
// 僅回滾非 merge Master 節點,保留 Master 程式碼
git log B``^..L`` --first-parent --no-merges --pretty=format:%H | xargs | xargs git cherry-pick -n 
git revert E`..F`

最後多說一點

想要回滾不頭痛,提前就要做好功課並且保持清晰的提交記錄,否則幾百個 commit 回滾起來就變成了一場災難。提幾個好方法

保持 Commit 清晰

  • 一次 commit 的做一件完整的事,不要摻雜別的需求和 bugfix,未完成需求前不要輕易提交編譯程式碼;
  • commit 有清晰的描述

善用 rebase

  • 如果有幾次 commit 乾的是一件事,可以通過 rebase 合併,不要出現很多 init、update 之類的無效 log
  • 剛剛提交程式碼後,又想起來某個配置需要改個版本,可以先 commit,最後使用 rebase 清理一下版本樹

多人並行開發,建立獨立的分支進行合併測試 不要合併到某一個分支中,防止上線時間變化導致程式碼再次清洗

到此這篇關於如何使用Git優雅的回滾實現的文章就介紹到這了,更多相關Git 回滾內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!