Git 没有改变历史的工具,但是可以使用交互式变基来修改历史,该命令为 git rebase -i
如果想修改最近三次提交,那就要将最近的第三次提交的 父提交 作为参数传递给 git rebase -i
,即 HEAD~2^
或 HEAD~3
,如下所示:
$ git rebase -i HEAD~3
pick cdb4e0d modified readme.md file
pick 30b0518 add H1 to index.html
pick 608b87b signed commit
就可以看到,他将最近三次提交都展示出来了。值得注意的是,他的顺序是和 git log
的显示顺序是 相反 的。因为它会依次的根据指令进行提交的修改,所以旧的提交就列在最上面,按照顺序修改,就可以形成 git log
的顺序了。
当然,也可以指定区间进行变基,但必须是旧提交在前,新提交在后
$ git rebase -i 8fcd8b6 c87d6f8
pick 4b6f30d add index file
pick b445fad modified to a README.md file
pick 33c3895 add next array file
pick c87d6f8 create kmp cpp file
可以看到,它变基的区间是 8fcd8b6 的 子提交 与 c87d6f8 之间来进行变基。
根据上面的指令,必须要知道一个提交的父提交才能进行交互式变基。那如果要重写根提交(第一个提交)怎么办?比较笨的方法是在提交列表中,手动将根提交添加进来。更简单的方法是 git rebase -i --root
需要注意的是,这是一个变基命令,在你变基的范围内,每一个修改了的提交都会被重写。所以确保变基的提交没有推送到远程,避免不必要的麻烦 。
命令
在交互式变基中,我们可以看到很多操作:
# 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
下列操作用到的频率比较高:
pick
: 使用该提交reword
: 使用该提交,会直接进入提交信息来修改提交信息edit
: 使用该提交,会短暂回到命令行,来进行提交(可以在命令行中增加提交)squash
: 使用该提交,并且与上一个提交合并fixup
: 与squash
一样,但是会丢弃提交信息exec
: 使用 shell 运行命令drop
: 删除该提交filter-branch
filter-branch 可以全局改写提交历史,比如: ``` $ git filter-branch —tree-filter ‘rm -f passwords.txt’ HEAD
``
该命令会检出项目的每一个提交后运行
rm -f passwords.txt` 然后重新提交结果。更多详情可以查看 pro git