在咱們的一個項目中,有3-4我的在同時開發,目前採用的是AoneFlow的變體進行分支管理,簡單來講,分爲四種類型的分支:主幹分支(master)、特性分支(feature)、發佈分支(release)、開發分支(develop/test)。git
每當新功能需求過來後,會從master切出feature分支進行開發,開發完成後合併到test分支中進行測試。多個功能需求測試完成後,將對應的feature分支合併到release分支,再合併到master分支進行發佈。如圖: shell
這種開發模式下的特色:在最近一次項目代碼合併的時候發現了兩個問題:編輯器
在發現問題後, 通過一個小時的排查,終於發如今某次提交過程當中,咱們的一位開發不當心把test分支合併到了本身的featureA分支上。測試
這意味着,許多開發中的功能被合併到了featureA上。爲了解決這個問題,這位同窗經過對比,手動刪除了多餘的代碼,保持了featureA分支只有本身開發的那部分代碼,也通過測試經過了。spa
因而分支變成了這個樣子:code
在上線代碼合併到master的時候,我檢查merge request進行例行的code-review,發現確實featureA 功能的提交,因而將featureA 合併到了master準備上線,上線後也沒有任何問題。後續的功能也一個一個都提交上去了。cdn
幾天後,一個同窗像我反映,在一個新功能的開發中,基於master切出了featureD分支,開發完成後合併到test分支進行測試的時候,出現了不少不是本身開發的代碼,我當時就很納悶,這種模式下test分支永遠是領先於master分支的,基於master的分支開發完成後提交到test應該只會有包含本身開發功能的那部分代碼纔對呀,最可能是產生一些衝突,不會有太多的文件變動。blog
最初懷疑是否是拉錯了分支,一看commit記錄,發現了問題的根本緣由:開發
在上次featureA 合併到master的時候,雖然沒有多餘的文件變動,可是featureA合併過test代碼,即featureA包含了添加featureB/C, 刪除featureB/C的兩次commit記錄工作流
因此在後續基於Master拉出來的feature分支都會帶上這個錯誤的commit記錄,致使:
git checkout featureA
git revert commit_id
複製代碼
提示失敗了
緣由是這個commit是一個merge commit,此次commit包含兩個父節點,須要指定你要revert哪個,即若是A,B合併到C,須要告訴git你要revert的是A提交仍是B提交。 這裏使用—m
參數就能夠了,1和2表明你要revert哪個父提交,大多數狀況是1,即撤銷「剛纔merge進來的那一個提交」
git revert commit_id -m 1
複製代碼
可是這裏有個須要注意的地方,若是revert掉某次修改後,若是須要再次merge該分支, 須要再作一次反向revert。 即Revert 掉以前的Revert,不然該分支以前的修改沒法被提交,由於已是「落後」於主幹分支了。
reset和revert不一樣的是:
這裏要注意的是,若是在出錯的commit版本後還有若干次正確的提交,reset後也會一併消失,須要從新加回來,否則後續正確的代碼也會丟失,按照以下操做進行cherry-pick:
git reset --hard commit_id #退回到出錯前的一個commit
git cherry-pick commit_id_right #將出錯後的commit提交從新加回當前的時間軸
git push -f #強制更新
複製代碼
rebase即變基 使用git rebase -i
命令能夠壓縮合並屢次提交
格式:git rebase -i [startpoint] [endpoint]
其中-i
的意思是interactive,即彈出交互式的界面讓用戶編輯完成合並操做,[startpoint] [endpoint]則指定了一個編輯區間,若是不指定[endpoint],則該區間的終點默認是當前分支HEAD所指向的commit(注:該區間指定的是一個前開後閉的區間)。
操做方式爲:
首先根據git log,找到出錯前的一個commit
執行git rebase -i commit_id
合併以前的提交記錄
會彈出一個vi編輯器以下:
將出錯的那兩次提交,pick
改成drop
,即丟棄。 Esc :wq
保存
若是出現衝突
須要手動解決衝突後,執行git add xxx
git rebase --continue
複製代碼
revert
來進行錯誤回退,並注意後續分支再次合併是否有問題。reset
和rebase
儘可能在私人分支或者未提交到遠程的時候使用,若是過去的分支已經提交到遠程,會對其餘人的本地分支形成影響。