Git使用進階:git rebase拆分過去的某次提交

情景

你正在作一個項目,然而在過去的某個時候,你把兩個重大的改動提交到了一個版本A中。
直到又進行了幾回提交以後,你才發現有必要將以前那兩個重大改動拆分紅版本A和版本B。git

當前的提交日誌以下所示:shell

commit 4a6a4088ecbe26d7f85db703e9c0a493aaac9675
Author: Wray Zheng 
  
  
  

 
  
  Date: Thu March 25 17:06:19 2017 +0800 add new functions commit 1c6a58f2c80b276b24495558cffedd13998a766a Author: Wray Zheng 
 
  
    Date: Thu March 25 17:04:23 2017 +0800 Two Big Changes commit 3157d5c2c16938d2ba1d68eae8fb5a26f87365ea Author: Wray Zheng 
   
     Date: Thu March 25 17:03:06 2017 +0800 first commit 
    
   

 複製代碼

下面,咱們就要將"Two Big Changes"對應的提交拆成兩個提交。this

1. 進入 rebase 交互模式

git rebase -i 
  
  
  

 複製代碼

此處 SHA-1 爲版本A的上一個提交的校驗和。spa

以上面的提交日誌爲例,能夠輸入如下命令來進入交互模式:rest

git rebase -i 3157d5c複製代碼

若是版本A不是上述狀況,而是第一個提交,則可使用 --root 選項:日誌

git rebase -i --root複製代碼

以後 git 會打開一個文件,給出指定提交以後的全部提交讓你進行修改。code

pick 1c6a58f Two Big Changes
pick 4a6a408 add new functions

# Rebase 3157d5c..4a6a408 onto 3157d5c
#
# Commands:
#  p, pick = use commit
#  r, reword = use commit, but edit the commit message
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit
#  f, fixup = like "squash", but discard this commit's log message
#  x, exec = run command (the rest of the line) using shell
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out複製代碼

2. 將版本A對應的命令改成 edit

咱們找到版本A,即"Two Big Changes"所對應的提交。
將版本A前面的 pick 改成 edit,這會讓 git 在 rebase 過程當中停留在版本A,讓咱們進行修改,而後再繼續 rebase 過程。
改完以後以下所示:ci

edit 1c6a58f Two Big Changes
pick 4a6a408 add new functions
......複製代碼

保存並關閉該文件,git 就開始了 rebase 過程。rem

3. 撤銷版本A的提交

咱們能夠看到 git 在 rebase 過程當中停留在了版本A,讓咱們進行相應操做。
此時,咱們至關於處在剛提交完版本A的環境中。接下來,先撤銷版本A的提交行爲,也就是恢復到版本A的前一個版本:get

git reset HEAD~複製代碼

而後能夠進入到第 4 步。

若是版本A爲首次提交的話,請使用如下的方式解決。

先使用如下命令將第二個改動從暫存區中刪除:

git rm --cached change2.cpp複製代碼

此時暫存區中只剩下第一個改動了,咱們能夠將其提交爲版本A:

git commit --amend -m "Version A"複製代碼

而後再提交第二個改動:

git add change2.cpp
git commit -m "Version B"複製代碼

至此,就完成了改動的分開提交,接下來能夠跳到第5步。

4. 分別提交兩個重大改動

撤銷完版本A的提交後,咱們就能夠把兩個重大改動分開提交了。

git add change1.cpp
git commit -m "Version A"

git add change2.cpp
git commit -m "Version B"複製代碼

5. 完成 rebase 過程

最後,只要輸入如下命令就完成 rebase 過程啦:

git rebase --continue複製代碼

大功告成!讓咱們來看看這時的提交日誌是否是和咱們預期一致。

commit 27aedab1a2a3ae4abb1f194971ae773e9a8017c5
Author: Wray Zheng 
  
  
  

 
  
  Date: Thu March 25 17:06:19 2017 +0800 add new functions commit a5f065f4736c676cca27c0c716ce732f401c913e Author: Wray Zheng 
 
  
    Date: Thu March 25 17:51:53 2017 +0800 Version B commit 56f506b500c1119c3736501e30c0a901a378ae03 Author: Wray Zheng 
   
     Date: Thu March 25 17:51:42 2017 +0800 Version A commit 3157d5c2c16938d2ba1d68eae8fb5a26f87365ea Author: Wray Zheng 
    
      Date: Thu March 25 17:03:06 2017 +0800 first commit 
     
    
   

 複製代碼

咱們按照預期將版本A拆分紅了兩個提交:版本A和版本B。

總結

在這裏,咱們使用了交互模式的 rebase 操做。
當咱們對版本A進行修改時,git爲咱們恢復到了當時的狀態,包括工做區、暫存區、倉庫,都變成剛提交完版本A的狀態。
此時,HEAD就是版本A。

咱們使用 git reset HEAD~ 將倉庫恢復到上一個版本,此時工做區依然保留了版本A的改動。

而後,咱們分開提交這兩個變更。最後,經過 git rebase --continue 來完成這次 rebase 操做。

版權

做者: Wray Zheng
原文連接: www.codebelief.com/article/201…

相關文章
相關標籤/搜索