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

 

有些时候不小心上传了一些敏感文件(例如密码), 或者不想上传的文件(没及时或忘了加到.gitignore里的),

而且上传的文件又特别大的时候, 这将导致别人clone你的代码或下载zip包的时候也必须更新或下载这些无用的文件,

因此, 我们需要一个方法, 永久的删除这些文件(包括该文件的历史记录).

首先, 可以参考 github 的帮助:

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

步骤一: 从你的资料库中清除文件

以Windows下为例(Linux类似), 打开项目的Git Bash,使用命令:

git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch path-to-your-remove-file' --prune-empty --tag-name-filter cat -- --all

其中, path-to-your-remove-file 就是你要删除的文件的相对路径(相对于git仓库的跟目录), 替换成你要删除的文件即可.

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

例如这样, 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.

步骤二: 推送我们修改后的repo

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

git push origin master --force

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

执行结果类似下面:

Counting objects: 4669, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (4352/4352), done.
Writing objects: 100% (4666/4666), 35.16 MiB | 51 KiB/s, done.
Total 4666 (delta 1361), reused 0 (delta 0)
To https://github.com/defunkt/github-gem.git
+ beb839d...81f21f3 master -> master (forced update)

步骤三: 清理和回收空间

虽然上面我们已经删除了文件, 但是我们的repo里面仍然保留了这些objects, 等待垃圾回收(GC), 所以我们要用命令彻底清除它, 并收回空间.

命令如下:

rm -rf .git/refs/original/

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)
git gc --aggressive --prune=now
Counting objects: 2437, done.
# Delta compression using up to 4 threads.
# Compressing objects: 100% (2426/2426), done.
# Writing objects: 100% (2437/2437), done.
# Total 2437 (delta 1483), reused 0 (delta 0)

注: 绿色字部分是命令执行后的结果.

现在你再看看你的.git目录文件大小是不是变小了.

git删除历史的更多相关文章

  1. git 仓库中删除历史大文件

    git 仓库中删除历史大文件 在git中增加了一个很大的文件,而且被保存在历史提交记录中,每次拉取代码都很大,速度很慢.而且用删除 提交历史记录的方式不是很实际. 以下分几个步骤介绍如何减小.git文 ...

  2. git删除所有历史提交记录,只留下最新的干净代码

    git删除所有历史提交记录,只留下最新的干净代码 1.Checkout git checkout --orphan latest_branch 2. Add all the files git add ...

  3. Git 删除所有历史提交记录方法

    Git 删除所有历史提交记录方法 切换分支 git checkout --orphan latest_branch 添加所有文件 git add -A 提交更改 git commit -am &quo ...

  4. git删除某次提交(某个commit)的方法【转】

    本文转载自:https://www.36nu.com/post/275 git删除某次提交(某个commit)的方法 疯狂的兔子 发表于 4个月前 阅读 536 收藏 0 推荐 0 评论 0 推荐收藏 ...

  5. Git 删除大文件的方法

    git 仓库中删除历史大文件   git 仓库中删除历史大文件 在git中增加了一个很大的文件,而且被保存在历史提交记录中,每次拉取代码都很大,速度很慢.而且用删除 提交历史记录的方式不是很实际. 以 ...

  6. git 删除和复制远程分支 储藏

    不常用到命令经常查,特别记录,方便自己开箱即用. 1. 删除本地分支 git branch -D <dev> 2. 删除远程分支 git push origin --delete < ...

  7. Git删除已提交的文件

    Git删除已提交的文件 Git删除已提交的文件 定位文件 删除文件 参考链接 昨天通过Git Bash提交代码的时候遇到了由于单个文件大小超过100M,导致代码上传失败的问题.考虑到那个大文件是用于训 ...

  8. git 删除本地分支和远程分支、本地代码回滚和远程代码库回滚

    [git 删除本地分支] git branch -D br [git 删除远程分支] git push origin :br  (origin 后面有空格) git代码库回滚: 指的是将代码库某分支退 ...

  9. 【GIT】git 删除本地分支和远程分支、本地代码回滚和远程代码库回滚

    [git 删除本地分支] git branch -D br [git 删除远程分支] git push origin :br  (origin 后面有空格) git代码库回滚: 指的是将代码库某分支退 ...

随机推荐

  1. mysql管理和基本操作

    进去mysql:mysql –uroot –p 重启数据库:[root@nanaLinux ~]# /etc/init.d/mysqld restart 1.Mysql忘记root密码 // 查看my ...

  2. CentOS7下,安装网卡驱动,命令行手动连接WIFI指导

    买了一个无线网卡,型号为TL-WN823N,谁知道在CentOS下没有驱动 于是开始了无线上网的漫漫征途 经历了无数个坑啊,解决了一个又一个的问题啊 到最后ping通的时候成就感简直爆棚 文章结构简介 ...

  3. React Native - 1 Windows下的环境配置(Windows+Android)

    参考:https://facebook.github.io/react-native/docs/getting-started.html(要FQ)     网站上建议使用Chocolatey去配环境, ...

  4. location.href、location.assign和location.replace的区别

    在写跳转页面的时候遇到个有意思的问题,RT的三个均能用来写跳转,总结了下它们之间的区别. 1.window.location.href=“url”;      改变url地址. location.hr ...

  5. Mysql错误:Every derived table must have its own alias

    Mysql报错:Every derived table must have its own alias    <缺少一个别名> 在子查询中经常会犯的错误 .这个别名其实没啥用途....  ...

  6. (转)Docker 基础 : Dockerfile

    全文来自 Docker 基础 : Dockerfile Dockerfile 是一个文本格式的配置文件,用户可以使用 Dockerfile 快速创建自定义的镜像.我们会先介绍 Dockerfile 的 ...

  7. (3)webApi postman使用

    https://www.getpostman.com/

  8. 几何+暴力【p1959】 遗址[NOI导刊2009普及(6)]

    题目描述--> P1959 遗址_NOI导刊2009普及(6) 普通方法分析: 因为题目要求是找最大正方形(如果是长方形更麻烦. 讲真,题目不难,耗时间! 根据题目要求,我们要找的是正方形. 我 ...

  9. Placement new的用法及用途【转】

    什么是placement new? 所谓placement new就是在用户指定的内存位置上构建新的对象,这个构建过程不需要额外分配内存,只需要调用对象的构造函数即可.举例来说: class foo{ ...

  10. Forward与include的区别

    Forward与include的区别 <jsp:include>标签用于把另外一个资源的输出内容插入进当前JSP页面的输出内容之中,这种在JSP页面执行时的引入方式称之为动态引入. < ...