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. Android面试题(3)

    1.  请描述下Activity的生命周期. activity的生命周期方法有: onCreate().onStart().onReStart().onResume().onPause().onSto ...

  2. Rails/ActiveRecord order by Array

    ActiveRecord中如果想根据自定义的一个数组id集合排序: ids = [2,1,3] users = User.where("id in (?)",ids) result ...

  3. 深度学习之PyTorch实战(2)——神经网络模型搭建和参数优化

    上一篇博客先搭建了基础环境,并熟悉了基础知识,本节基于此,再进行深一步的学习. 接下来看看如何基于PyTorch深度学习框架用简单快捷的方式搭建出复杂的神经网络模型,同时让模型参数的优化方法趋于高效. ...

  4. linux图形化客户端

    很多服务器都用linux 但这些linux都是没有图形化界面的, 一般也不建议在服务器上装图形化界面 我们都知道,维护linux,大部分都是使用命令 那么,为什么不能开发一个应用程序, 把图形化操作转 ...

  5. netty源码解解析(4.0)-2 Chanel的接口设计

    全名: io.netty.channel.Channel Channel内部定义了一个Unsafe类型,Channel定义了对外提供的方法,Unsafe定义了具体实现.我把Channel定义的的方法分 ...

  6. memcached优化方案实例

    <?php //引入memcached require_once '../class/memcached.class.php'; //连接MySQL $link = mysqli_connect ...

  7. JS截取字符串substr 和 substring方法的区别

    substr 方法 返回一个从指定位置开始的指定长度的子字符串. stringvar.substr(start [, length ]) 参数 stringvar 必选项.要提取子字符串的字符串文字或 ...

  8. 【SQLite】简单的基本使用步骤

    SQLite介绍SQLite is a software library that implements a self-contained, serverless, zero-configuratio ...

  9. MYSQL中SHOW的使用整理收藏

    好记性不如乱笔头吧....下面收藏整理了mysql中show 的使用技巧....有需要的博友可以看看哈 a. show tables或show tables from database_name; / ...

  10. Java基础——Servlet(七)过滤器&监听器 相关

    一.过滤器简介 Filter 位于客户端和请求资源之间,请求的资源可以是 Servlet Jsp html (img,javascript,css)等.用于拦截浏览器发给服务器的请求(Request) ...