--- title: git 撤銷某commit技巧 --- ###### tags: `infrastructure` # git 撤銷某commit技巧 ## 撤銷方式 1. revert 2. reset 3. rebase -drop ## 特色 與 使用場景 ### revet #### 會增加一個commit 以撤銷目標commit的代碼 ##### 優點: 如果revert發生錯誤,可以退回某個commit達到恢復目的,相當安全。 且可以單獨撤銷commit交錯下的某個commit ##### 缺點: commit會較為雜亂。 例如原要撤銷的commit 3個,revert後還會再增加一個。 其他方式較能維持commit簡潔 ##### 建議場景: 使用在dev、feature等與他人共用的分支上。 可以達到安全撤銷目的; 同時當dev 往ut 等上層分支merge時,透過squesh 合併功能過程的多次commit,可以維持上層commit的簡潔 ### reset #### 會撤銷目標commit 要留意的是reset會一路撤銷目標過程中所有的目標過程中所有的 commit,而不是單一個目標。 例如 A -> B -> C, reset B時,C也會一併被reset ##### 優點: 乾淨、簡潔、方便快速 ##### 缺點: 危險,會直接撤銷commit, 當撤銷後沒有commit、或者使用 --hard 指令,撤銷內容不復見 ##### 建議場景: 在自己獨立的分支上開發時,自己理應相當清楚細節,使用reset撤銷,特別是剛剛commit後發現需要撤銷時,使用起來簡便、簡潔(不像revert增加多餘的commit) ### rebase -drop #### 會單獨撤銷指定的commit ##### 優點: 由於可以單獨撤銷某幾個特定commit,當需要保留、與需要撤銷的commit交錯時,這功能相當好用 ##### 缺點: 危險,像是reset --hard 那樣不可恢復; 且當撤銷交錯的commit之間有關聯時,會出現衝突需要解決,而git 的預設衝突處理,是要嘛全留,要嘛一路全砍直到你指定的分支,當你與別人共同開發時,對方的內容少了什麼你可能沒有感覺,更是危險 ##### 建議場景: 當須撤銷與要保留的commit交錯時使用,可以乾淨、獨立的撤銷掉不需要的commit而不影響其他要保留部分; 特別是有多個commit要撤銷的情況下,rebase -drop的優點比其他兩個更強大。 另外如果有出現衝突需要處理時,建議先abort rebase,將原始的分支備份一份,以防誤刪同事代碼 ## 案例實測 A -> B -> C -> D ![](https://i.imgur.com/XVXCFf4.png) ### revet revert c commit, c commit 還會在,並且要求你填入撤銷c commit的 新增commit comment。 如果要撤回,reset這次revert commit,代碼會停留在revert commit的內容, 但是commit已經退回d commit階段, 此時rollback即可將工作區代碼退回 d commit內容 ``` git revert [c commit] ``` ![](https://i.imgur.com/R73EP9s.png) ### reset 撤銷c commit: HEAD^^,或者指向 b commit, d commit會一併被撤銷 ``` git reset [b commit] or git reset HEAD^^ ``` ps: 沒帶上--hard參數,被撤銷的commit代碼還會留在工作區 ![](https://i.imgur.com/Hc4XKSb.png) ### rebase -drop 單獨撤銷 c ``` git rebase -i ``` 將c commit 改為drop,並退出 ![](https://i.imgur.com/sHld1yR.png)