通常,rebase是基于一个分支,例如,当执行git rebase master
时,当前分支的基点就变为master
分支的头部。
实际上,rebase可以基于任意特定提交,执行时指定提交哈希值:git rebase <commit>
。
另外,git rebase
命令与其他许多git命令一样,支持交互方式:git rebase -i
。交互方式下,可以修改涉及到的,每个提交的内容。
所以,如果想修改当前分支的历史,可以通过交互方式的rebase来进行,指定要修改记录的起点即可。命令格式:
git rebase -i <start commit>
例如,我们当前分支的历史如下:
Kevin@qikegu MINGW64 /g/project/git-demo (master)
$ git log --oneline
d574d8e (HEAD -> master) add 'uvwxy' to test1.txt
ca0ad8e (origin/master, origin/HEAD) modified: test1.txt
454d25c add 'klmno' to test1.txt
c9f926d change 1st line of test1.txt: 'file name is test1.txt'
ad729df change 1st line of test1.txt: 'file type is txt'
724b9f7 add test2.txt
34c2089 add 'fghij' to test1.txt
3aa4060 add 'abcde' to test1.txt
要修改c9f926d
之后的提交(最后3个),只需执行git rebase -i c9f926d
。
交互式rebase操作示例
下面通过实际例子,逐步演示交互式rebase的操作:
- 启动交互式rebase
执行git rebase -i c9f926d
,c9f926d
是第4个提交,也可以使用HEAD~4
指定。Kevin@qikegu MINGW64 /g/project/git-demo (master) $ git rebase -i c9f926d hint: Waiting for your editor to close the file...
- 编辑git-rebase-to文件
git rebase -i
命令执行后,会打开一个git-rebase-to
文件,表示对于各个提交要执行的命令,下面是该文件的内容,其中列出了各个支持的命令。
pick 454d25c add 'klmno' to test1.txt pick ca0ad8e modified: test1.txt pick d574d8e add 'uvwxy' to test1.txt # Rebase c9f926d..d574d8e onto c9f926d (3 commands) # # Commands: # p, pick <commit> = use commit # r, reword <commit> = use commit, but edit the commit message # e, edit <commit> = use commit, but stop for amending # s, squash <commit> = use commit, but meld into previous commit # f, fixup <commit> = like "squash", but discard this commit's log message # x, exec <command> = run command (the rest of the line) using shell # b, break = stop here (continue rebase later with 'git rebase --continue') # d, drop <commit> = remove commit # l, label <label> = label current HEAD with a name # t, reset <label> = reset HEAD to a label # m, merge [-C <commit> | -c <commit>] <label> [# <oneline>] # . create a merge commit using the original merge commit's # . message (or the oneline, if no original merge commit was # . specified). Use -c <commit> to reword the commit message. # # 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可以看到,文件中列出的3个提交(顺序与
git log
列出的相反),正是我们想要修改的提交。默认情况下,对提交执行pick
命令,表示不作修改使用该提交。常用的命令如下:pick
使用该提交reword
使用该提交,但修改描述信息squash
使用该提交,但与前面的提交融合drop
不使用该提交
执行顺序从上到下,可以调整这些行的顺序,提交的顺序也随之调整。请仔细阅读
git-rebase-to
文件的注释,里面有详细说明。git-rebase-to
文件修改如下:pick 454d25c add 'klmno' to test1.txt reword ca0ad8e drop d574d8e add 'uvwxy' to test1.txt ...
- 继续执行rebase
关闭编辑器,命令继续。
执行reword时,会弹出一个编辑器让你输入对应提交的描述信息。完成后,关闭编辑器,命令继续。
Kevin@qikegu MINGW64 /g/project/git-demo (master) $ git rebase -i c9f926d hint: Waiting for your editor to close the file... hint: Waiting for your editor to close the file... [detached HEAD ddfa3c8] add some numbers to test1.txt Date: Wed Aug 21 14:54:51 2019 +0800 1 file changed, 4 insertions(+), 3 deletions(-) Successfully rebased and updated refs/heads/master.
- 查看执行结果
使用
git log
查看修改后的历史:Kevin@qikegu MINGW64 /g/project/git-demo (master) $ git log --oneline ddfa3c8 (HEAD -> master) add some numbers to test1.txt 454d25c add 'klmno' to test1.txt c9f926d change 1st line of test1.txt: 'file name is test1.txt' ad729df change 1st line of test1.txt: 'file type is txt' 724b9f7 add test2.txt 34c2089 add 'fghij' to test1.txt 3aa4060 add 'abcde' to test1.txt 1661e1b Update test1.txt
与本文前面的
git log
结果比较一下,可以看到分支历史被修改了:d574d8e (HEAD -> master) add 'uvwxy' to test1.txt
这个提交被删除ca0ad8e (origin/master, origin/HEAD) modified: test1.txt
这个提交被改为ddfa3c8 (HEAD -> master) add some numbers to test1.txt
454d25c add 'klmno' to test1.txt
这个提交不变