从git存储库中删除文件(历史记录)

Bor*_*zin 76 git version-control git-rewrite-history

(解决了,看到问题正文的底部)现在
寻找这个,我现在拥有的是:

几乎相同的方法,但它们都将对象留在包文件中......坚持.
我尝试了什么:

git filter-branch --index-filter 'git rm --cached --ignore-unmatch file_name'
rm -Rf .git/refs/original
rm -Rf .git/logs/
git gc
Run Code Online (Sandbox Code Playgroud)

包中还有文件,这就是我所知道的:

git verify-pack -v .git/objects/pack/pack-3f8c0...bb.idx | sort -k 3 -n | tail -3
Run Code Online (Sandbox Code Playgroud)

还有这个:

git filter-branch --index-filter "git rm -rf --cached --ignore-unmatch file_name" HEAD
rm -rf .git/refs/original/ && git reflog expire --all &&  git gc --aggressive --prune
Run Code Online (Sandbox Code Playgroud)

相同...

尝试过的git clone技巧,它删除了一些文件(约3000个)但最大的文件仍然存在...

我在存储库中有一些大的遗留文件,大约200M,我真的不希望它们在那里...而且我不想将存储库重置为0 :(

解决方案:这是摆脱文件的最短路径:

  1. 检查.git/packed-refs - 我的问题是我有refs/remotes/origin/master一个远程存储库的行,删除它,否则git将不会删除这些文件
  2. (可选) git verify-pack -v .git/objects/pack/#{pack-name}.idx | sort -k 3 -n | tail -5 - 检查最大的文件
  3. (可选) git rev-list --objects --all | grep a0d770a97ff0fac0be1d777b32cc67fe69eb9a98 - 检查这些文件是什么
  4. git filter-branch --index-filter 'git rm --cached --ignore-unmatch file_names' - 从所有修订中删除文件
  5. rm -rf .git/refs/original/ - 删除git的备份
  6. git reflog expire --all --expire='0 days' - 使所有松散物体失效
  7. git fsck --full --unreachable - 检查是否有松动的物体
  8. git repack -A -d - 重新包装
  9. git prune - 最后删除那些对象

Dan*_*ing 64

我无法确定无法访问您的存储库数据,但我相信在运行之前可能还有一个或多个打包的引用仍然引用旧提交git filter-branch.这可以解释为什么git fsck --full --unreachable不将大blob称为无法访问的对象,即使你已经使你的reflog过期并删除了原始(解包)refs.

这是我会怎么做(后git filter-branchgit gc已经完成):

1)确保原始参考已经消失:

rm -rf .git/refs/original

2)使所有reflog条目失效:

git reflog expire --all --expire='0 days'

3)检查旧的包装参考

这可能很棘手,具体取决于您拥有多少打包参考.我不知道任何自动执行此操作的Git命令,因此我认为您必须手动执行此操作.做一个备份.git/packed-refs.现在编辑.git/packed-refs.检查旧的参考(特别是,看看它是否包装了任何参考.git/refs/original).如果您发现任何旧版本不需要,请删除它们(删除该参考的行).

清理完packed-refs文件后,查看是否git fsck注意到无法访问的对象:

git fsck --full --unreachable

如果这样可行,并且git fsck现在报告您的大blob无法访问,则可以继续执行下一步.

4)重新打包您的打包存档

git repack -A -d

这将确保无法访问的对象得到解压缩并保持解压缩状态.

5)修剪松散(不可到达)的物体

git prune

这应该做到这一点.Git真的应该有更好的方法来管理打包引用.也许有一种我不了解的更好的方式.如果没有更好的方法,手动编辑packed-refs文件可能是唯一的方法.


Rob*_*ley 15

我建议使用BFG Repo-Cleaner,这是一种更简单,更快速的替代方案,git-filter-branch专门用于重写Git历史记录中的文件.它让你的生活更轻松的一种方式是,它实际上默认处理所有引用(所有标签,分支,refs/remotes/origin/master之类的东西等),但它也快10-50倍.

您应该仔细按照以下步骤操作:http://rtyley.github.com/bfg-repo-cleaner/#usage - 但核心位是这样的:下载BFG的jar(需要Java 6或更高版本)并运行此命令:

$ java -jar bfg.jar  --delete-files file_name  my-repo.git
Run Code Online (Sandbox Code Playgroud)

任何名为file_name(不在您的最新提交中)的文件将从存储库的历史记录中完全删除.然后,您可以使用git gc清除死数据:

$ git gc --prune=now --aggressive
Run Code Online (Sandbox Code Playgroud)

BFG通常比使用起来更简单git-filter-branch- 选项是围绕这两个常见用例定制的:

  • 删除疯狂的大文件
  • 删除密码,凭据和其他私人数据

完全披露:我是BFG Repo-Cleaner的作者.


Mik*_*rto 6

我发现这对于删除整个文件夹非常有帮助,因为上面的内容并没有真正帮助我:https://help.github.com/articles/remove-sensitive-data.

我用了:

git filter-branch -f --force \
--index-filter 'git rm -rf --cached --ignore-unmatch folder/sub-folder' \
--prune-empty --tag-name-filter cat -- --all

rm -rf .git/refs/original/
git reflog expire --expire=now --all
git gc --prune=now
git gc --aggressive --prune=now
Run Code Online (Sandbox Code Playgroud)


小智 5

我试图摆脱历史上的一个大文件,而上述答案在某种程度上起作用.关键是:如果你有标签,它们就不起作用.如果可以从标记访问包含大文件的提交,那么您需要调整filter-branches命令:

git filter-branch --tag-name-filter cat \
--index-filter 'git rm --cached --ignore-unmatch huge_file_name' -- \
--all --tags
Run Code Online (Sandbox Code Playgroud)