前言
本章教大家如何使用 GIT 进行一些关于已提交历史的修改、删除操作。比如碰到下列情况时,如何使用 GIT 实现想要的操作:
代码或日志中的注释误提交了,怎么修改它?
我想丢弃指定的提交历史可不可以?
在提交很久历史记录中存在敏感信息,如何修改或删除它?
阅读本文章时默认大家都具备使用
GIT进行基本操作的水平。
提交至远程前的修复操作
$ git status
On branch master
Your branch is up to date with 'origin/master'.
Untracked files:
(use "git add <file>..." to include in what will be committed)
test.txt
nothing added to commit but untracked files present (use "git add" to track)
可以看到,这里有一个新文件等待添加提交,我们现在来将文件加入索引缓存中并构建索引树:
$ git add test.txt
$ git commit -m '测试上传一个文'
因为输入描述有误,原本应该是 测试上传一个文件,因为少打了一个字此时的 log 描述就变成了:

这时候我们可以用 $ git commit --amend 命令来修改最近一次的提交描述。我这里用的为 VIM ,所以补上缺失的字后 :wd 保存退出即可。

再通过 $ git log 查看本地历史:

此时已经将文字补全,最后执行 push 推送至远程服务器即可。
移除指定的提交历史
比如,刚修复了一条的测试反馈的错误,最终定位到并不是代码问题只需要重启下服务就可以了,但改过的代码已经进入了 GIT ,此时重新进行 add -> commit -> push 提交有可以。
只是会在 log 中产生一条垃圾记录,如果后期会查看 log 进行一些 diff 时,看到这段改动会很懵逼。

现在我们在刚才的基础上增加了一次提交,存在了一个 test2.txt 文件。
先通过 $ git log 命令在历史记录中查找到想要删除的某次提交的 commit id,我这里是:5e63d3cfa09176422b0b52714bd77af1a0ce8e63。
执行: $ git rebase -i "5e63d3cfa09176422b0b52714bd77af1a0ce8e63"^(注意,这个 ^ 符号一定要带后面)。
此时会进入一个 VIM 编辑:

删除第一行内容 :wq 保存并退出,再用 log 看看记录,测试已经不存在 测试上传一个文件 的操作及文件 test.txt 了。
最后通过 $ git push origin master -f 指令,将本地对应修改后的分支推送至远端强制覆盖。
改写已提交的历史记录

当我们根据关键词 log 搜索提交历史存在敏感信息,是很久以前提交的并且那次提交改动了很多文件的内容,不能通过移除 commit id 的方式进行删除,此时该怎么办呢?
核弹级选项: filter-branch
官方文档上的实例:要从整个历史中删除一个名叫password.txt的文件,你可以在filter-branch上使用—tree-filter选项 :
$ git filter-branch --tree-filter 'rm -f passwords.txt' HEAD
所以这里我们需要替换成 $
git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch passwords.txt' --prune-empty --tag-name-filter cat -- --all
passwords.txt 替换成实际要删除的文件或相对目录即可。


如图中所示,已经没有 userpasswod.ini 的记录,关键字也搜索不到了,最后将修改后的分支推送至远端强制覆盖即可