簡體   English   中英

如何從 git 存儲庫中刪除未使用的對象?

[英]How to remove unused objects from a git repository?

我不小心添加、提交並推送了一個巨大的二進制文件,其中包含我對 Git 存儲庫的最新提交。

如何讓 Git 刪除為該提交創建的對象,以便我的.git目錄再次縮小到合理的大小?

編輯:感謝您的回答; 我嘗試了幾種解決方案。 沒有一個工作。 例如,來自 GitHub 的那個從歷史記錄中刪除了文件,但.git目錄大小並沒有減少:

$ BADFILES=$(find test_data -type f -exec echo -n "'{}' " \;)

$ git filter-branch --index-filter "git rm -rf --cached --ignore-unmatch $BADFILES" HEAD
Rewrite 14ed3f41474f0a2f624a440e5a106c2768edb67b (66/66)
rm 'test_data/images/001.jpg'
[...snip...]
rm 'test_data/images/281.jpg'
Ref 'refs/heads/master' was rewritten

$ git log -p # looks nice

$ rm -rf .git/refs/original/
$ git reflog expire --all
$ git gc --aggressive --prune
Counting objects: 625, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (598/598), done.
Writing objects: 100% (625/625), done.
Total 625 (delta 351), reused 0 (delta 0)

$ du -hs .git
174M    .git
$ # still 175 MB :-(

我在別處回答了這個問題,我會在這里復制,因為我為此感到自豪!

... 不用多說,我可以向您展示這個有用的腳本 git-gc-all,它保證刪除所有 git 垃圾,直到他們可能提出額外的配置變量:

git -c gc.reflogExpire=0 -c gc.reflogExpireUnreachable=0 \
  -c gc.rerereresolved=0 -c gc.rerereunresolved=0 \
  -c gc.pruneExpire=now gc "$@"

--aggressive 選項可能會有所幫助。

注意:這將刪除所有未引用的東西,所以如果您以后決定要保留其中的一些,請不要向我哭泣!

您可能還需要先運行類似的東西,哦,天哪,git 很復雜!!

git remote rm origin
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

我把所有這些放在一個腳本中,在這里:

http://sam.nipl.net/b/git-gc-all-ferocious

您的git reflog expire --all不正確。 它會刪除早於過期時間(默認為 90 天)的 reflog 條目。 使用git reflog expire --all --expire=now

對類似問題的回答涉及從存儲庫中真正清除未使用的對象的問題。

1)從git repo(而不是文件系統)中刪除文件:

  • git rm --cached path/to/file

2)使用以下方法收縮回購:

  • git gc ,

  • git gc --aggressive

  • git prune

或以上問題的組合: Reduce git repository size

可以使用相同的方法應用有關刪除敏感數據的指南。 您將重寫歷史記錄以從它存在的每個修訂版中刪除該文件。這是破壞性的,會導致與任何其他檢出的 repo 沖突,因此請先警告任何合作者。

如果您想讓其他人在 repo 中使用二進制文件,那么沒有真正的方法可以做您想做的事。 它幾乎全部或沒有。

對我來說,關鍵是運行git repack -A -d -f然后運行git gc來減小我擁有的單個 git pack 的大小。

嗨!

Git 只在克隆存儲庫時接收它實際需要的對象(如果我理解正確的話)

因此,您可以修改最后一次提交刪除錯誤添加的文件,然后將您的更改推送到遠程存儲庫(使用 -f 選項也可以覆蓋服務器上的舊提交)

然后,當您創建該 repo 的新克隆時,它的 .git 目錄應該與提交大文件之前一樣小。

(可選)如果您也想從服務器中刪除不必要的文件,您可以刪除服務器上的存儲庫並推送新克隆的副本(具有完整歷史記錄)

git filter-branch --index-filter 'git rm --cached --ignore-unmatch Filename' --prune-empty -- --all

請記住更改要從存儲庫中刪除的Filename

請參閱 Pro Git 書中的“移除對象”:

http://git-scm.com/book/en/Git-Internals-Maintenance-and-Data-Recovery#Removing-Objects

更新:另見 BFG 回購清潔器: http : //rtyley.github.io/bfg-repo-cleaner/

2020 年, git-filter-branch的文檔不鼓勵使用它,並建議使用替代方法,例如git-filter-repo 它也可以用來代替 BFG

請注意,git 書中關於重寫歷史記錄的章節尚未更新。 GitHub也沒有刪除敏感數據的建議

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM