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仓库的跟目录), 替换成你要删除的文件即可. 注意一点,这里的文件或文件夹,都不能以 '/' 开头,否则文件或文件夹会被认为是从 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 (/)
# Ref 'refs/heads/master' was rewritten
如果显示 xxxxx unchanged, 说明repo里没有找到该文件, 请检查路径和文件名是否正确.
注意: 补充一点, 如果你想以后也不会再上传这个文件或文件夹, 请把这个文件或文件夹添加到.gitignore文件里, 然后再push你的repo.
步骤二: 推送我们修改后的repo
以强制覆盖的方式推送你的repo, 命令如下:
$ git push origin master --force --all
这个过程其实是重新上传我们的repo, 比较耗时, 虽然跟删掉重新建一个repo有些类似, 但是好处是保留了原有的更新记录, 所以还是有些不同的. 如果你实在不在意这些更新记录, 也可以删掉重建, 两者也差不太多, 也许后者还更直观些.
执行结果类似下面:
Counting objects: , done.
Delta compression using up to threads.
Compressing objects: % (/), done.
Writing objects: % (/), 35.16 MiB | KiB/s, done.
Total (delta ), reused (delta )
To https://github.com/defunkt/github-gem.git
+ beb839d...81f21f3 master -> master (forced update)
为了能从打了 tag 的版本中也删除你所指定的文件或文件夹,您可以使用这样的命令来强制推送您的 Git tags:
$ git push origin master --force --tags
步骤三: 清理和回收空间
虽然上面我们已经删除了文件, 但是我们的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目录文件大小是不是变小了.
参考自:
http://whoop.sinaapp.com/blog/article/21
http://blog.csdn.net/meteor1113/article/details/4407209
.
Git如何永久删除文件(包括历史记录)的更多相关文章
- Git永久删除文件和历史记录
目录 Git永久删除文件和历史记录 使用filter-branch 添加到.gitignore文件里并push修改后的repo 清理和回收空间 Git永久删除文件和历史记录 造成你想从git存储库中永 ...
- 【Git的基本操作四】永久删除文件后找回
永久删除文件后找回 1. 已经添加到本地库的文件 使用 reset 命令回退到未删除的历史记录即可 2.添加到缓存区,没有提交到本地库的文件找回 git reset --hard HEAD 命令即可找 ...
- Git如何永久删除某个重要文件文件或文件夹 (包括历史记录) 强制
有些时候不小心上传了一些敏感文件(例如密码), 或者不想上传的文件(没及时或忘了加到.gitignore里的), 而且上传的文件又特别大的时候, 这将导致别人clone你的代码或下载zip包的时候也必 ...
- Git教程之删除文件(8)
在Git中,删除也是一个修改操作,我们实战一下,先添加一个新文件test.txt到Git并且提交:
- git教程:删除文件
在Git中,删除也是一个修改操作,我们实战一下,先添加一个新文件test.txt到Git并且提交: $ git add test.txt $ git commit -m "add test. ...
- git学习笔记 ---删除文件
在Git中,删除也是一个修改操作,我们实战一下,先添加一个新文件test.txt到Git并且提交: $ git add test.txt $ git commit -m "add test. ...
- git命令如何删除文件或文件夹
拉取远程仓到本地 git clone ×× cd ××× 查看分支 git branch -a 切换到想要操作的分支 git checkout 想要操作的分支 在本地仓库删除文件 git rm 我的文 ...
- mzy git学习,删除文件(三)
删除一个文件(工作区删除,并且在本地版本库中也删除) 第一种方式: rm test.txt 先删除工作区的test.txt git add test.txt (我的理解是,将删除test.txt这个动 ...
- [git 学习篇]删除文件
1 现在本地文件管理器删除了readme.txt(这个readme.txt已经在创库存在的) rm -rf readme.txt 2 此时git status查看 $ git status # On ...
随机推荐
- 局域网使用visual studio配合iis调试手机app
描述:开发一款手机应用程序,服务器配置在iis,当局域网中即只有路由器无外网如何设置实时调试手机应用程序? vs配合iis调试程序的两种方式? 使用vs的debug(f5)调试网站比较常见,然而当网站 ...
- Redis有序集合操作
有序集合存储着成员和分值之间的映射,并且提供了分值处理命令,以及根据分值大小有序的获取或扫描成员和分值的命令 (常用命令) ZADD : ZADD key-name score member [sco ...
- WebForm 【复合控件】
一 复合控件(取值,赋值用法相近) RadioButtonList --单选按钮 (一组列表) <asp:RadioButtonList ID="RadioButtonL ...
- [javaSE] 看知乎学习工厂模式
factory的“本质”就是根据不同的输入创建出不同类型的对象. 引入factory的原因就是你需要根据不同的输入创建不同类型的对象. 简单工厂模式相当于是一个工厂中有各种产品,创建在一个类中,客户无 ...
- JSP与Servlet之间传值的一般方法,适合新手做练习
#JSP与Servlet之间传值 Jsp与Servlet之间的传值有两种,一种是Jsp传值给Sevlet,另一种是Servlet传值给Jsp:使用request.response对象完成传值,具体实现 ...
- Java中类的线程安全问题
java中各种集合(字符串类)的线程安全性!!! 一.概念: 线程安全:就是当多线程访问时,采用了加锁的机制:即当一个线程访问该类的某个数据时,会对这个数据进行保护,其他线程不能对其访问,直到该线程读 ...
- Nett的Http表头赋值
DefaultFullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseSta ...
- EF DataFirst修改数据类型
在做软件的时候我们可能会遇到这样的问题,就是在使用EF的时候,有时候精度不一样, 我们用整数来计算肯定是比浮点数来得快的,但我在MySQL里面存储的数据类型是decimal的,我生成EF后, 里面的数 ...
- python学习之老男孩python全栈第九期_数据库day005知识点总结 —— MySQL数据库day5
三. MySQL视图(不常用) 给某个查询语句设置个别名(视图名),日后方便使用 - 创建: create view 视图名 as SQL; PS:视图是虚拟的 - 修改: alter view 视图 ...
- js弹窗 js弹出DIV,并使整个页面背景变暗
1.首先写一个遮罩层div,然后再写一个弹窗的div <!-- 遮罩层 --> <div id="cover" style="background: # ...