使用 BFG Repo-Cleaner 修改 Git 提交历史

发布日期:2020年03月16日本文同步发表于公众号:

Cover

为什么要修改 Git 提交历史

修改 Git 历史,一般有以下两个原因:

  • 删除密码、API Key 等敏感数据,因为即使你在最新的提交删除了他们,在历史提交里也存在;
  • 删除超大文件。

超大文件问题经常出现在当你从一个 Git 托管网站换到另一个时,常因为后者不支持大文件,导致推送不上去。即使最新版删除了大文件,因为大文件存在在历史中,依然不能推送。

目前我测试几个网站的文件大小限制:

操作步骤

本文演示删除历史中的大文件步骤。

安装 bfg

如果是 MacOS,直接安装即可:

brew install bfg

如果是其他系统,可以下载 1.13.0 版的 jar 包,并将下面命令中的 bfg 替换成 java -jar path/to/bfg-1.13.0.jar

克隆仓库

git clone --mirror git@xxxxxx.com:jitao/project.git

这里使用 --mirror 参数,表示克隆出来的是一个 bare 仓库。

这一步最好备份一下仓库。

改历史

bfg --delete-files home.mp4 project.git

删除 home.mp4 这个文件,注意参数只能是文件名,不包含路径。如果传入一个路径,会报错:

Error: *** Can only match on filename, NOT path *** - remove '/' path segments

正常运行大概输出如下:

Using repo : /Users/jitao/workspace/project.git

Found 527 objects to protect
Found 2 commit-pointing refs : HEAD, refs/heads/master

Protected commits
-----------------

These are your protected commits, and so their contents will NOT be altered:

 * commit 9bbd9c4e (protected by 'HEAD')

Cleaning
--------

Found 336 commits
Cleaning commits:       100% (336/336)
Cleaning commits completed in 435 ms.

Updating 1 Ref
--------------

    Ref                 Before     After
    ---------------------------------------
    refs/heads/master | 9bbd9c4e | bc0c11c6

Updating references:    100% (1/1)
...Ref update completed in 24 ms.

Commit Tree-Dirt History
------------------------

    Earliest                                              Latest
    |                                                          |
    .............................DDDDDmmmmmmmmmmmmmmmmmmmmmmmmmm

    D = dirty commits (file tree fixed)
    m = modified commits (commit message or parents changed)
    . = clean commits (no changes to file tree)

                            Before     After
    -------------------------------------------
    First modified commit | 4021098d | ce77dc85
    Last dirty commit     | d73ece33 | e26922da

Deleted files
-------------

    Filename   Git id
    ------------------------------
    home.mp4 | 8ab9914d (114.1 MB)


In total, 187 object ids were changed. Full details are logged here:

    /Users/jitao/workspace/project.git.bfg-report/2020-03-15/15-02-30

BFG run is complete! When ready, run: git reflog expire --expire=now --all && git gc --prune=now --aggressive

信息的最后 bfg 还夹带了点私货:

--
You can rewrite history in Git - don't let Trump do it for real!
Trump's administration has lied consistently, to make people give up on ever
being told the truth. Don't give up: https://www.rescue.org/topic/refugees-america
--

呵呵。

清理仓库

cd project.git
git reflog expire --expire=now --all && git gc --prune=now --aggressive

推送

git push

参考文章