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…

相关文章
相关标签/搜索