BFG Repo-Cleaner - 从 Git 历史中真正删除文件

背景

Git 操作时,经常“不小心”上传一些不必要的(大)文件,或者私密数据,等等。

当然可以从本地把这些文件删除,加入 .gitignore, 避免下次再上传。

然而,之前已经上传过的,还遗留在 git 历史中,“有心人”还是会能挖掘到你的私密数据。。。

分析

Git - git-filter-branch 可以从历史中删除文件,但据说“挺危险的”,于是前车之鉴我也没敢试试。

从大妈那儿拿到建议用 BFG Repo-Cleaner by rtyley,值得一试,这个大概是终极工具了。

BFG 删除历史文件

网站的帮助还算清楚,直接上操作:

  • 环境:Java8+

  • git clone --mirror your-repo.git

  • cd your-repo.git

  • 下载bfg.jar,我为了省事,直接将其复制到 your-repo.git 目录下了(不建议参考哈)

  • java -jar bfg-1.12.16.jar --delete-files test1.py

如果是要删文件夹:

--delete-folders "{folderA,folderB,folderC}" 这个就好了

  • git reflog expire --expire=now --all && git gc --prune=now --aggressive

  • git push

再去看历史,那个文件test1.py不见了~done.

  • 最好把本地旧的 repo 删除了,不然可能又不小心 mess up 了
  • 通知其他仓库使用者重新 clone 吧,他们本地的旧的也好删除了。

要注意的是:

  • BFG 默认不会 touch最新的commit,即如果你要删除的文件在最新的 commit 中,则不会删除之。为什么?因为最新的 commit 很可能是已上线在 production 的,所以~
  • BFG 用的是仓库镜像,具体是什么,见下文。
  • 如果要删除的文件在受保护的commit中,BFG 不会删,不建议删。至于commit什么情况下会受保护,我还不太清楚。

Git 仓库镜像

值得注意的是,BFG 用的是仓库镜像 git clone --mirror , 它和普通的git clone有什么区别?

git-clone doc:

--mirror

Set up a mirror of the source repository. This implies --bare. Compared to --bare, --mirror not only maps local branches of the source to local branches of the target, it maps all refs (including remote-tracking branches, notes etc.) and sets up a refspec configuration such that all these refs are overwritten by a git remote update in the target repository.

我没看懂,对“refs"还是挺迷惑,模糊感觉, --mirror 类似深拷贝, 复制一切~, 具体理解还得和另外两种 git clone的方式结合起来:

  • git clone your-repo.git
  • git clone --bare your-repo.git: 这个貌似最浅层次的 copy 了(bare嘛)

What's the difference between git clone --mirror and git clone --bare - Stack Overflow 这里面有详细的讲解, 摘一段如下:

git clone --mirror origin-url: Every last one of those refs will be copied as-is. You'll get all the tags, local branches master (HEAD), next, pu, and maint, remote branches devA/master and devB/master, other refs refs/foo/bar and refs/foo/baz. Everything is exactly as it was in the cloned remote. Remote tracking is set up so that if you run git remote update all refs will be overwritten from origin, as if you'd just deleted the mirror and recloned it. As the docs originally said, it's a mirror. It's supposed to be a functionally identical copy, interchangeable with the original.

BFG 的原理

可能也是因为 --mirror 是深拷贝,复制一切,所以也便于更新修改了~

本来以为 BFG 也用了 git-filter-branch,查了一下源码,没找到类似的 git 命令,看到的是这样:

clean(commits)
updateRefsWithCleanedIds()
objectIdCleaner.stats()
objectIdCleaner.cleanedObjectMap()

后来去官网再仔细看,发现有一段和git-filter-branch的性能比较:

  • git-filter-branch 循环每一个 commit, 在每个 commit 中 walk 整个文件目录结构,慢而且浪费

  • BFG:用 git 下面这个特性,只具体处理要删除的文件或文件夹

    every file and folder is represented precisely once (and given a unique SHA-1 hash-id)

    不知道是否可以这么理解,用过 git log --oneline <文件名> 都知道,这个命令会显示文件的各个 commit 历史。BFG 大概用的这种每个文件在每次 commit 中都有一个 sha,找到这个文件所有的 commit sha, 然后再分别处理之似乎就可以了,不必考虑 commit 的文件目录循环了。

问题

我现在用的还不多,等遇到了继续补充。

附录

想贴出来这个,就因为挺好笑的~自己找, BFG repo 好多 commits message 也是 Trump~

Using repo : your-repo.git

Found 16 objects to protect
Found 26 commit-pointing refs : HEAD, refs/heads/test1, refs/heads/test2, ...

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

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

 * commit 260b0811 (protected by 'HEAD')

Cleaning
--------

Found 81 commits
Cleaning commits:       100% (81/81)
Cleaning commits completed in 430 ms.

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

        Ref                    Before     After   
        ------------------------------------------
        refs/heads/test1 | 3db4545b | 87b66f4b

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

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

        Earliest                                              Latest
        |                                                          |
        ..........................................................DD

        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 | 707a5be5 | 37820e97
        Last dirty commit     | 3db4545b | 87b66f4b

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

        Filename   Git id                          
        -------------------------------------------
        test1.py | 37677ac6 (28 B), d1758471 (20 B)


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

        your-repo.git.bfg-report/2020-01-10/21-41-09

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


--
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.theguardian.com/us-news/trump-administration
--

Reference

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,607评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,047评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,496评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,405评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,400评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,479评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,883评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,535评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,743评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,544评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,612评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,309评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,881评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,891评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,136评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,783评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,316评论 2 342

推荐阅读更多精彩内容