从git永久删除目录

时间:2009-08-01 14:44:31

标签: git

在我个人的git repo中,我有一个包含数千个不再需要的小图像的目录。有没有办法从整个git历史中删除它们?我试过了

git filter-branch --index-filter "git rm -rf --cached --ignore-unmatch imgs" HEAD

git filter-branch --tree-filter 'rm -fr imgs' HEAD

但是git repo的大小保持不变。有什么想法吗?

由于

7 个答案:

答案 0 :(得分:32)

ProGit书中有一个关于Removing Object的有趣部分。

它以此结束:

  

您的历史记录不再包含对该文件的引用   但是,reflog以及Git在filter-branch下执行.git/refs/original时添加的一组新引用仍然有效,因此您必须删除它们然后重新打包数据库。在重新打包之前,你需要摆脱任何指向那些旧提交的指针:

$ rm -Rf .git/refs/original
$ rm -Rf .git/logs/
$ git gc
$ git prune --expire 

git prune --expire不是强制性的,但可以从松散的对象中删除目录内容)
在执行这些命令之前备份所有内容,以防万一;)

答案 1 :(得分:14)

实际上这些技术都不适用于我。 我发现最可靠的是简单地将本地拉到另一个回购中:

git pull file://$(pwd)/myGitRepo

它还为您省去了删除旧标签的麻烦。

在我的博客上看到这个故事: http://stubbisms.wordpress.com/2009/07/10/git-script-to-show-largest-pack-objects-and-trim-your-waist-line/

答案 2 :(得分:13)

默认情况下,

git-filter-branch会在refs/original/*命名空间中保存旧的引用。

您需要删除它们,然后执行git gc --prune=now

答案 3 :(得分:10)

Brandon Thomson 在对 Rainer Blome 的解决方案的评论中询问,如果这只是修复了gitk视图或者refs真的不见了。检查这个的一个好方法是记住旧提交的sha1哈希值(或其唯一前缀)之一并尝试

$ git ls-tree hash-value

这应该显示repos主文件夹的内容,就像它在此提交中一样。之后

$ rm -Rf .git/refs/original
$ rm -Rf .git/logs/

显示 Raon Blome ,如 Raon Blome 所示,从<{1}}和refs/original/…移除.git/info/refs

.git/packed-refs

不仅制作了参考,而且旧的物体(提交,树木和斑点)也消失了。上面显示的$ git gc --prune=now 证明了这一点。 检查这个的另一个很好的命令是git ls-tree hash-value(在过滤器 - brach之前和修剪之后运行它并比较大小)。

注意:由于我不允许对其他答案发表评论,我不得不写一个新答案,尽管它主要结合以前给出的答案。

答案 4 :(得分:3)

如果您想要手动清理路线,还有一些文件也可能包含 在git-filter-branch之前引用原始分支的位置。 例如,我过滤了我的“home”分支:

.git / info / refs:

  

179ad3e725816234a7182476825862e28752746d refs / original / refs / heads / home

.git / packed-refs:

  

179ad3e725816234a7182476825862e28752746d refs / original / refs / heads / home

删除这些行后,gitk不再显示旧提交。

答案 5 :(得分:2)

由于这是一个古老的问题,当时可能有一些不可能。这也假设您正在使用bash或cygwin。

警告:第二行和第三行将永久删除分支/标记无法访问的所有提交。

运行filter-branch后,执行

for ref in $(git for-each-ref --format='%(refname)' refs/original); do git update-ref -d $ref; done
git reflog expire --expire=now --all
git gc --prune=now

git for-each-ref --format='%(refname)'获取引用名称,git update-ref -d删除引用。通常最好不要直接修改.git文件夹,特别是此命令处理引用packed-refs时的情况。

第二行和第三行直接来自How to clean up unused side-branches in your commit trees?

答案 6 :(得分:0)

2021 年的答案

出人意料的是,这是一项艰巨的任务。谷歌翻出了可追溯到 2009 年的页面,以及近十年前的 StackOverflow 讨论。很多这些东西不再起作用了!

这是有效的(也是根据 git 文档推荐的方式):

首先安装git-filter-repo

pip install git-filter-repo

接下来,从 git 历史记录中删除文件夹。这将重写除排除文件夹之外的整个 Git 历史记录!

git filter-repo --force --invert-paths --path to/folder1 --path to/folder

接下来,添加回遥控器:

git remote add origin https://...

接下来,强制向上游推送:

git push --force --set-upstream origin master

这就是一堆命令,但我还没有找到更短更好的方法。