開發(fā)過程中,我們經(jīng)常會遇到代碼回滾的情況。正常人都知道,git 回滾有兩大寶:
當(dāng)我們在本地開發(fā),還未 git push
到遠(yuǎn)端時,可以毫無顧忌的使用 git reset
進(jìn)行回滾。更多的情況中,我們不僅 push 了,而且由于開發(fā)周期長,在開發(fā)過程中不斷的 merge master
和 merge other-branch
以發(fā)布到預(yù)發(fā)環(huán)境測試或者多需求合并測試。
突然
上線后用戶投訴,需要馬上下線本次需求中的 A、B、C,只保留 D、E、F,迅速回滾,不要影響更多用戶。
撕逼?那肯定是來不及了。一群人在你背后眼巴巴地盯著你,就問你慌不慌...
接下來,我們來說說,如何在緊急回滾面前,鎮(zhèn)定(假)自若(裝)地進(jìn)行 git 操作
簡單場景
本地操作使用 git reset
隨便玩玩就行了,我們主要講講 git revert
回滾“單一提交”
回滾“連續(xù)提交”
回滾一次“合并”
回滾合并時,如果直接使用 git revert mergeCommit
實際上是遞歸回滾里面的每一個節(jié)點,指定 -m
是指定以哪一個分支為主線,當(dāng)前所在分支為 1,依次類推(一次合并多個分支時會 > 2,正常只有 1 和 2)
高級場景
如果我們遇到的問題都像上面一樣,那怎么能體現(xiàn)一個程序員的價值?
回滾“混合場景”
如以下場景中,我們期望回歸的節(jié)點之間含有一次合并導(dǎo)致我們無法一次回滾到位。有兩種方式:
1. 按順序見招拆招回滾(三次操作)
2. 先回滾 D + F,再回滾合并(兩次操作)
【推薦】使用方案1,按順序回滾會處理更少的 conflict,否則假設(shè) D、F 是一系列提交合集,那么回滾成本很高
回滾有點復(fù)雜“混合場景”
如下的場景中,特殊的地方在于,我有一個 feature,搭車了一個 bugfix,我需要回滾需求但不回滾 bug
這種情況下,有兩種選擇:
回滾 G,通過 git 引一步一步回滾 F-F'-E‘-D'-C‘-E'‘(不滾)-D'‘(不滾)-C'‘(不滾) ,回滾 E+D 【推薦】回滾 G,回滾 F 丟棄 F',回滾 D+E,復(fù)原 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``
回滾復(fù)雜的”混合場景“
標(biāo)注解釋
- 藍(lán)色代表已經(jīng)合并到遠(yuǎn)程分支 Master 生成了 tag
- 紅色代表需要回滾的 commit
- 綠色代表正常 commit
場景解釋 一開始你所在的團隊接到一個需求,這個需求中可以分拆出一個自需求,最終可以實現(xiàn)兩人并行開發(fā)
- 兩個人 Pa 和 Pb 分別在 Master 基礎(chǔ)上創(chuàng)建了新分支
- 在開發(fā)過程中 Master 上發(fā)布了兩次 bugfix(v2、v3)
- 由于需要在預(yù)發(fā)上持續(xù)測試,所以 Pa 主動合并了 Master
- Pb 在自己分支 B‘ C' D‘ 中廢棄了之前的舊邏輯和一些代碼的小幅重構(gòu)(穩(wěn)定性更新),之后 一直在本地開發(fā)新功能 驗證
- 最后即將上線時需要合并自需求一起驗證,驗證后 Pb 發(fā)布了 v3
- 后續(xù)又經(jīng)過了一次 bugfix 發(fā)布了 v4
- 結(jié)果,產(chǎn)品反悔了 WTF ???
- 最后,要廢棄新功能,需要重新設(shè)計產(chǎn)品,但是舊有邏輯仍然按原計劃廢棄 >> F(v2) + B'-D'
回滾方式
遇到這樣的場景,一般有如下幾種方案回滾:
- 回到最新的遠(yuǎn)端 Master (v4) 手動識別需求代碼進(jìn)行人工刪除 刪除自己的代碼還好,刪除別人的代碼就有點難度了,而且當(dāng)提交量很大時很耗時耗力
- 復(fù)制 F(v2) 替換 Master(v4),手動或應(yīng)用 B'-D‘ commit 圖示情況,直接復(fù)制粘貼是個便捷的方法,再次回復(fù) B'-D' 也費不了多大事,只是手動操作難免失誤,尤其是增加/刪除文件的情況,復(fù)制粘貼容易出錯
- 【推薦】按時序回滾(O'-T‘、L'‘、F'‘-K'‘^、B'‘-C'‘、E'-N‘) 版本控制本來就是為了代碼管理更便捷,使用 git 操作后面的人不僅能看懂回滾了哪些 / 如何回滾的 / 怎么處理回滾中的 conflict 的,如果回滾錯了還可以回滾“回滾了的”操作
git revert N`..S`
// 僅回滾非 merge Master 節(jié)點,保留 Master 代碼
git log B``^..L`` --first-parent --no-merges --pretty=format:%H | xargs | xargs git cherry-pick -n
git revert E`..F`
最后多說一點
想要回滾不頭痛,提前就要做好功課并且保持清晰的提交記錄,否則幾百個 commit 回滾起來就變成了一場災(zāi)難。提幾個好方法
保持 Commit 清晰
- 一次 commit 的做一件完整的事,不要摻雜別的需求和 bugfix,未完成需求前不要輕易提交編譯代碼;
- commit 有清晰的描述
善用 rebase
- 如果有幾次 commit 干的是一件事,可以通過 rebase 合并,不要出現(xiàn)很多 init、update 之類的無效 log
- 剛剛提交代碼后,又想起來某個配置需要改個版本,可以先 commit,最后使用 rebase 清理一下版本樹
多人并行開發(fā),創(chuàng)建獨立的分支進(jìn)行合并測試 不要合并到某一個分支中,防止上線時間變化導(dǎo)致代碼再次清洗
到此這篇關(guān)于如何使用Git優(yōu)雅的回滾實現(xiàn)的文章就介紹到這了,更多相關(guān)Git 回滾內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
您可能感興趣的文章:- IDEA通過git回滾到某個提交節(jié)點或某個版本的操作方法
- 利用PyCharm操作Github(倉庫新建、更新,代碼回滾)
- Git使用小技巧之回滾與撤銷詳解
- git 刪除分支和回滾的實例詳解
- 簡單談?wù)凣it中的回滾操作