Git永久删除文件和历史记录

造成你想从git存储库中永久删除文件和历史记录的可能有:

  • 你不小心将一个不该加入版本管理的文件加了进去,敏感数据或大文件或别的没用的文件;
  • 你不小心将一个涉及到破解某著名软件的文章加了进Github仓库,这时你就会收到github官方的邮件来提醒你需要完全删除该文件,不然就会遭到git仓库被封禁。
  • 你希望将敏感数据或无用文件从版本库中永久删除不留痕迹,不仅仅在版本历史里看不出来,还要把它占用的空间也释放出来。

参考官方链接,github 的帮助文档:

https://help.github.com/articles/remove-sensitive-data

很详细的说明了步骤和提供了一种使用BFG工具的思路(更便利)

这里我只说使用git命令的方式,以windows平台下为例,linux类似做法:

使用filter-branch

注意: 如果在存储更改后运行git filter-branch,则无法使用其他存储命令检索更改。

在运行git filter-branch之前,建议取消所做的任何更改。要unstash最后一组隐藏的更改,运行git stash show -p | git apply -R。有关更多信息,请参阅https://git-scm.com/book/en/v1/Git-Tools-Stashing。

演示如下:

进入git存储仓库,运行以下命令,用要删除文件的相对路径(而不仅仅是文件名)替换PATH-TO-YOUR-FILE-WITH-SENSITIVE-DATA

这行长命令的参数做到的事是:

  • 强制Git处理(但不检出)每个分支和标记的全部历史;

  • 删除指定的文件,以及由此生成的任何空提交;

  • 覆盖你现有的tags

    $ git filter-branch --force --index-filter \
    'git rm --cached --ignore-unmatch PATH-TO-YOUR-FILE-WITH-SENSITIVE-DATA' \
    --prune-empty --tag-name-filter cat -- --all

    其中, PATH-TO-YOUR-FILE-WITH-SENSITIVE-DATA 就是你要删除的文件的相对路径(相对于git仓库的根目录), 替换成你要删除的文件路径即可. 注意一点,这里的文件或文件夹,如果以 '/' 开头,则文件或文件夹会被认为是从 git 的安装目录开始。

    如果你要删除的目标不是文件,而是文件夹,那么请在 git rm --cached 命令后面添加 -r 命令,表示递归的删除(子)文件夹和文件夹下的文件,类似于 rm -rf 命令。

    如果你要删除的文件很多, 可以写进一个.sh文件批量执行, 如果文件或路径里有中文, 由于MinGW或CygWin对中文路径设置比较麻烦, 你可以使用通配符*号, 例如: sound/music_*.mp3, 这样就把sound目录下以music_开头的mp3文件都删除了.

    例如:新建一个 bash 脚本文件,del-music-mp3.sh:

    #!/bin/bash
    
    git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch projects/Moon.mp3' --prune-empty --tag-name-filter cat -- --all
    git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch sound/Music_*.mp3' --prune-empty --tag-name-filter cat -- --all

    如果你看到类似下面这样的, 就说明删除成功了:

    Rewrite 48dc599c80e20527ed902928085e7861e6b3cbe6 (266/266)
    # Ref 'refs/heads/master' was rewritten

    如果显示 xxxxx unchanged, 说明repo里没有找到该文件, 请检查路径和文件名是否正确.

实际例子操作如图:

添加到.gitignore文件里并push修改后的repo

如果想以后也不会再上传这个文件或文件夹, 请把这个文件或文件夹添加到.gitignore文件里, 然后再push你的repo.

添加到.gitignore文件:

$ echo "YOUR-FILE-WITH-SENSITIVE-DATA" >> .gitignore
$ git add .gitignore
$ git commit -m "Add YOUR-FILE-WITH-SENSITIVE-DATA to .gitignore"
[master 051452f] Add YOUR-FILE-WITH-SENSITIVE-DATA to .gitignore
1 files changed, 1 insertions(+), 0 deletions(-)

再次检查是否已经从存储库的历史记录中删除了所有想要删除的内容,以及是否检出了所有分支。

以强制覆盖的方式推送你的repo, 命令如下:

git push origin --force --all
Counting objects: 1074, done.
Delta compression using 2 threads.
Compressing objects: 100% (677/677), done.
Writing objects: 100% (1058/1058), 148.85 KiB, done.
Total 1058 (delta 590), reused 602 (delta 378)
To https://github.com/YOUR-USERNAME/YOUR-REPOSITORY.git
+ 48dc599...051452f master -> master (forced update)

这个过程其实是重新上传我们的repo, 比较耗时, 虽然跟删掉重新建一个repo有些类似, 但是好处是保留了原有的更新记录, 所以还是有些不同的. 如果你实在不在意这些更新记录, 也可以删掉重建, 两者也差不太多, 也许后者还更直观些。

为了能从打了 tag 的版本中也删除你所指定的文件或文件夹,您可以使用这样的命令来强制推送您的 Git tags:

$ git push origin master --force --tags

告诉您的协作者,从您的旧(受污染的)存储库历史中重新创建分支,而不是合并它们。一个合并提交可能会重新引入一些或所有您刚刚陷入清除麻烦的受污染的历史。

清理和回收空间

经过一段时间之后,您确信git filter-branch没有意外的副作用,您可以使用以下命令强制解除对本地存储库中的所有对象的引用和垃圾回收(GC)。

$ git for-each-ref --format='delete %(refname)' refs/original | git update-ref --stdin
$ git reflog expire --expire=now --all
$ git gc --prune=now
Counting objects: 2437, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (1378/1378), done.
Writing objects: 100% (2437/2437), done.
Total 2437 (delta 1461), reused 1802 (delta 1048)

您还可以通过将过滤后的历史推入一个新的或空的存储库,然后从GitHub创建一个新的克隆来实现这一点。

上面命令的第一句也可以换成:

$ rm -rf .git/refs/original/

参考自:

https://help.github.com/articles/removing-sensitive-data-from-a-repository/

https://www.cnblogs.com/shines77/p/3460274.html

文:铁乐与猫

2018-11-17

【end】

Git永久删除文件和历史记录的更多相关文章

  1. Git如何永久删除文件(包括历史记录)

    有些时候不小心上传了一些敏感文件(例如密码), 或者不想上传的文件(没及时或忘了加到.gitignore里的), 而且上传的文件又特别大的时候, 这将导致别人clone你的代码或下载zip包的时候也必 ...

  2. 【Git的基本操作四】永久删除文件后找回

    永久删除文件后找回 1. 已经添加到本地库的文件 使用 reset 命令回退到未删除的历史记录即可 2.添加到缓存区,没有提交到本地库的文件找回 git reset --hard HEAD 命令即可找 ...

  3. git仓库删除所有提交历史记录

    stackoverflow原问题地址:http://stackoverflow.com/questions/13716658/how-to-delete-all-commit-history-in-g ...

  4. git 批量删除文件夹和文件

    git 批量删除文件夹和文件 硬盘删除文件后,执行$ git status   会提示你仍然需要$ git rm <文件>   此时如果是要删除大批量文件,这么一个一个命令下去不得累死人啊 ...

  5. Git学习 -- 删除文件

    1 从版本库删除文件 git rm <file> git commit -m "xxx" 2 工作区中文件被误删,但版本库中没有删除,可以恢复到工作区 git chec ...

  6. git批量删除文件和批量提交

    1. 单个删除文件: ① 通常直接在文件管理器中把没用的文件删了,或者用rm命令删了:(可选操作,可直接执行②删除) $ rm test.txt ② 确实要从版本库中删除该文件,那就用命令git rm ...

  7. Git项目删除文件

    场景:项目中有一个文件test_exam_copy 文件之前提交上去的,现在不想要,本地也不要 方案一(手动图示删除): 直接登录到gitLab上面,进入该文件详情,直接删除,然后本机push下,则库 ...

  8. git 命令删除文件操作

    在github上只能删除仓库,却无法删除文件夹或文件, 所以只能通过命令来解决 1.添加文件并提交命令 2.推送到git服务器命令 3.删除文件并提交命令 4.推送到git服务器 查看下git 是否存 ...

  9. 『现学现忘』Git基础 — 35、Git中删除文件

    目录 1.删除文件说明 2.删除文件操作 (1)仅删除暂存区的文件 (2)完全删除文件 3.本文用到的命令总结 1.删除文件说明 在Git工作目录中要删除某个文件,首先要清楚该文件所处的状态. 若要是 ...

随机推荐

  1. .net core在Linux下获取AD域信息

    .net core在Linux下获取AD域信息 .net Core 2.1.4 .net core现在System.DirectoryServices只支持Windows平台下使用. 参考: http ...

  2. 获取C#中方法的执行时间及其代码注入

    在优化C#代码或对比某些API的效率时,通常需要测试某个方法的运行时间,可以通过DateTime来统计指定方法的执行时间,也可以使用命名空间System.Diagnostics中封装了高精度计时器Qu ...

  3. gbk转utf-8

    1.文件转码:使用脚本   gbk转u8的脚本文件: #!/bin/bash FILE_SUFFIX="java xml html vm js" # FILE_SUFFIX=&qu ...

  4. (转)Sphinx中文分词安装配置及API调用

    这几天项目中需要重新做一个关于商品的全文搜索功能,于是想到了用Sphinx,因为需要中文分词,所以选择了Sphinx for chinese,当然你也可以选择coreseek,建议这两个中选择一个,暂 ...

  5. js从一个对象数组中根据属性值大小排序

    <script type="text/javascript"> var sdts = [ {name:"小明",age:30}, {name:&qu ...

  6. 图片人脸检测——OpenCV版(二)

    图片人脸检测 人脸检测使用到的技术是OpenCV,上一节已经介绍了OpenCV的环境安装,点击查看. 往期目录 视频人脸检测——Dlib版(六)OpenCV添加中文(五)图片人脸检测——Dlib版(四 ...

  7. 使用Asp.Net Core MVC 开发项目实践[第五篇:缓存的使用]

    项目中我们常常会碰到一些数据,需要高频率用到但是又不会频繁变动的这类,我们就可以使用缓存把这些数据缓存起来(比如说本项目的导航数据,帖子频道数据). 我们项目中常用到有Asp.Net Core 本身提 ...

  8. 快速排序的Java和python实现,亲测实际可用

    1.基本思想 快速排序每趟排序确定一个元素x的位置,使用的方式是 将大于元素x的值放大x的右边,小于元素x的值放大x的左边.当确定x的位置之后,再分别对x左边的数组和右边的数组进行快速排序即可. 2. ...

  9. 【Spring】10、Spring中用@Component、@Repository、@Service和 @Controller等标注的默认Bean名称会是小写开头的非限定类名

    @Service用于标注业务层组件(我们通常定义的service层就用这个) @Controller用于标注控制层组件(如struts中的action) @Repository用于标注数据访问组件,即 ...

  10. HTML中令人惊喜的全局属性

    1.accesskey 属性 : 规定激活元素的快捷键. 浏览器支持:几乎所有浏览器均 accesskey 属性,除了 Opera. 定义和用法 accesskey 属性规定激活(使元素获得焦点)元素 ...