【问题标题】:Git - Delete a BlobGit - 删除一个 Blob
【发布时间】:2015-08-06 12:12:22
【问题描述】:

有没有办法或命令使用它的 ID 从 git 中删除一个 blob

我使用了命令

$ git rev-list --objects --all | git cat-file --batch-check='%(objectname) %(objecttype) %(rest)' | grep '^[^ ]* blob' | cut -d" " -f1,3-

并获得了所有版本中的 blob 列表,例如

62f7e0df0b80bce8d0a4cb388be8988df1bec5ef NodeApplication/NodeApplication/public/javascripts/homescript.js
b1d69387fbd4d4e84bbe9eb2c7f59053c0355e11 NodeApplication/NodeApplication/iisnode/index.html
624642d6f2a86844dc145803260537be0fe40090 NodeApplication/NodeApplication/.ntvs_analysis.dat

现在我想删除 blob

NodeApplication/NodeApplication/.ntvs_analysis.dat. 

我该怎么做?

【问题讨论】:

  • 你需要git filter-branch,见help.github.com/articles/remove-sensitive-data
  • 实际上我做了 git filter,gc 所有减少我的 repo 大小并推送到 TFS 中的 repo 的东西,TFS 不允许删除文件或 gc,所以只有提交被重写。现在我从 TFS 克隆,它仍然是较旧的大小,但提交被重写(所以如果我过滤分支,那么这些文件不存在)。我什至尝试了 gc 一切

标签: git


【解决方案1】:

我使用BFG cleaner 清理了不需要的大文件,然后做了

git reflog expire --expire=now --all
git gc --aggressive --prune=now

【讨论】:

  • OP 询问如何按 ID 删除 blob。如果不直接回答问题,请考虑解释如何使用 BFG --strip-blobs-with-ids CLI 标志。
  • 感谢提到 BFG,但需要更多解释。对于 OSX:1.brew install bfg 2.bfg --strip-blobs-with-ids <id> 3.git reflog expire --expire=now --all && git gc --prune=now --aggressive
  • 为什么两次调用 git gc?
【解决方案2】:

执行此操作的“正确”方法是使用 git 的垃圾收集器。

首先找到所有引用该 blob 的树。然后找到所有引用其中一棵树的提交。

完全删除这些提交(从所有 head 的历史记录、所有标签和 reflog 中),垃圾收集器将清理 blob。

删除 blob 而不首先删除引用它的对象会损坏您的存储库。

使整个过程自动化的一种简单方法是使用git filter-branch,它使您能够生成从未签入该特定文件的备用历史记录。

【讨论】:

  • 我已经完成了 git filter-branch,现在提交被重写了,但是 git repo 中仍然存在 blob
  • @keerthee 查看filter-branch 的手册页 - 请参阅标有“缩小存储库的清单”的部分。如果你正确地删除了引用,清除了 reflog,并强制 gc,垃圾就会消失。
  • 实际上我做了上面这减少了我的 repo 大小并推送到 TFS 中的 repo,TFS 不允许删除文件或 gc,所以只有提交被重写。现在我从 TFS 克隆,它是仍然是较旧的大小,但提交被重写(所以如果我过滤分支,那么这些文件不存在)。我什至尝试了 gc 一切
  • @keerthee 那么你的问题是 TFS 而不是 git。
  • 我明白,但是有没有办法清理本地克隆的 repo
【解决方案3】:

如果您已经拥有 blob ID,则可以使用 git verify-pack 找到文件名(反之亦然)

git verify-pack -v .git/objects/pack/*.idx | grep <reference_id or filename>

一旦你有了文件名,你应该

  • 从 git 中删除对 blob 的所有引用,然后
  • 使用git filter-branch 重写历史记录以从分支中的每个提交中删除 blob。

这样,git 垃圾收集器git gc 将清理它并释放空间。

看看脚本git forget-blob 一步完成所有这些

git forget-blob file-to-forget

https://ownyourbits.com/2017/01/18/completely-remove-a-file-from-a-git-repository-with-git-forget-blob/

基本上这会删除所有标签,远程引用,就像这样

git tag | xargs git tag -d
git filter-branch --index-filter "git rm --cached --ignore-unmatch $FILE"
rm -rf .git/refs/original/ .git/refs/remotes/ .git/*_HEAD .git/logs/
git for-each-ref --format="%(refname)" refs/original/ | \
  xargs -n1 --no-run-if-empty git update-ref -d
git reflog expire --expire-unreachable=now --all
git repack -A -d
git prune

【讨论】:

    猜你喜欢
    • 2017-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-17
    • 1970-01-01
    • 1970-01-01
    • 2021-01-09
    • 1970-01-01
    相关资源
    最近更新 更多