Làm cách nào để xóa các đối tượng không sử dụng khỏi kho lưu trữ git?


89

Tôi đã vô tình thêm, cam kết và đẩy một tệp nhị phân khổng lồ với cam kết mới nhất của mình vào kho lưu trữ Git.

Làm cách nào để tôi có thể yêu cầu Git xóa (các) đối tượng đã / được tạo cho cam kết đó để .gitthư mục của tôi thu nhỏ lại kích thước bình thường?

Chỉnh sửa : Cảm ơn câu trả lời của bạn; Tôi đã thử một số giải pháp. Không có tác dụng nào. Ví dụ: một từ GitHub đã xóa các tệp khỏi lịch sử, nhưng .gitkích thước thư mục không giảm:

$ 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 :-(

13
Chỉ là một lời nhắc nhở cho người điều hành, câu hỏi này 100% thuộc về SO, không phải superuser.
VonC


Như đã đề cập ở đây ( stackoverflow.com/questions/685319/… ), bạn đã thử đóng gói lại sau gc của mình chưa? git-repack -atiếp theo là git-prune-packedví dụ. Xem blog.felipebalbi.com/2007/12/19/…
VonC

2
@Jonas: và điều gì sẽ xảy ra nếu sau khi bạn làm tất cả những điều đó, bạn sao chép repo của mình? Sau đó, bạn có nhận được một bản sao với kích thước giảm mong muốn không?
VonC

1
@Jonas: sau khi tất cả những gì bạn đã làm ( filter-branch, gc, repack, ...), không có, bạn nên không thấy bất kỳ xấu cam kết gì cả. Đây là dấu hiệu cho thấy việc dọn dẹp không diễn ra như mong đợi.
VonC

Câu trả lời:


127

Tôi đã trả lời điều này ở nơi khác, và sẽ sao chép ở đây vì tôi tự hào về nó!

... và không cần bổ sung thêm, tôi có thể giới thiệu cho bạn tập lệnh hữu ích này, git-gc-all, được đảm bảo loại bỏ tất cả git rác của bạn cho đến khi chúng có thể xuất hiện thêm các biến cấu hình:

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

Tùy chọn --aggressive có thể hữu ích.

LƯU Ý: điều này sẽ xóa TẤT CẢ những thứ không được tham chiếu, vì vậy đừng khóc với tôi nếu sau này bạn quyết định rằng bạn muốn giữ một số trong số chúng!

Bạn cũng có thể cần chạy một cái gì đó như thế này trước, bạn ơi, git rất phức tạp !!

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

Tôi đặt tất cả điều này trong một kịch bản, ở đây:

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


Như trong stackoverflow.com/questions/1904860/… , +1 lại cho bạn.
VonC

18
tuyệt vời: D kế hoạch ác của tôi để có được nhiều điểm hơn bằng cách nhân bản câu trả lời đã làm việc !! 1;)
Sam Watkins

Đúng! Điều này đã hiệu quả, nhưng tôi phải chạy toàn bộ kịch bản. Chỉ chạy lệnh gc (với các tùy chọn cấu hình) là không đủ.
Daniel

4
102m đến 160k .. hiệu quả và hủy diệt
prusswan

4
Cảm ơn rất nhiều cho kịch bản! Thông tin bổ sung: xargsLệnh tạo ra lỗi trên OS X do tùy chọn không được công nhận. Giải pháp đơn giản nhất: Cài đặt GNU xargs qua homebrew brew install findutilsvà thay thế xargsbằng gxargs.
qqilihq 27/09/17

26

Của bạn git reflog expire --alllà không chính xác. Nó loại bỏ các mục đăng nhập cũ hơn thời gian hết hạn, mặc định là 90 ngày. Sử dụng git reflog expire --all --expire=now.

Câu trả lời của tôi cho một câu hỏi tương tự đề cập đến vấn đề thực sự xóa các đối tượng không sử dụng khỏi kho lưu trữ.


18

1) Xóa tệp khỏi git repo (& không phải hệ thống tệp):

  • git rm --cached path/to/file

2) Thu nhỏ repo bằng cách sử dụng:

  • git gc,

  • hoặc là git gc --aggressive

  • hoặc là git prune

hoặc kết hợp của những điều trên như được đề xuất trong câu hỏi này: Giảm kích thước kho lưu trữ git


10

Hướng dẫn về cách xóa dữ liệu nhạy cảm này có thể áp dụng, sử dụng cùng một phương pháp. Bạn sẽ phải viết lại lịch sử để xóa tệp đó khỏi mọi bản sửa đổi mà nó đã có trong đó. Điều này là phá hoại và sẽ gây ra xung đột repo với bất kỳ lần kiểm tra nào khác, vì vậy hãy cảnh báo trước cho bất kỳ cộng tác viên nào.

Nếu bạn muốn giữ nhị phân có sẵn trong repo cho người khác, thì không có cách nào thực sự để làm những gì bạn muốn. Đó là khá nhiều tất cả hoặc không có.


8

Chìa khóa đối với tôi hóa ra là chạy git repack -A -d -fvà sau đó git gclà giảm kích thước của gói git duy nhất mà tôi có.


6

Hy!

Git chỉ nhận các đối tượng mà nó thực sự cần khi nhân bản kho lưu trữ (nếu tôi hiểu đúng về nó)

Vì vậy, bạn có thể sửa đổi cam kết cuối cùng, xóa tệp được thêm vào do nhầm lẫn, sau đó đẩy các thay đổi của bạn vào kho lưu trữ từ xa (với tùy chọn -f để ghi đè cam kết cũ trên máy chủ)

Sau đó, khi bạn tạo một bản sao mới của repo đó, thư mục .git của nó phải nhỏ như trước khi (các) tệp lớn được cam kết.

Theo tùy chọn, nếu bạn cũng muốn xóa các tệp không cần thiết khỏi máy chủ, bạn có thể xóa kho lưu trữ trên máy chủ và đẩy bản sao mới được nhân bản của mình (có toàn bộ lịch sử)



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

Hãy nhớ thay đổi Filenamecái bạn muốn xóa khỏi kho lưu trữ.


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.