Kullanılmayan nesneler git deposundan nasıl kaldırılır?


90

Bir Git deposuna en son taahhüdümle yanlışlıkla büyük bir ikili dosya ekledim, işledim ve ittim.

.gitDizinim yeniden makul bir boyuta küçültülmesi için Git'in bu yürütme için yaratılmış / yaratılmış nesneleri kaldırmasını nasıl sağlayabilirim ?

Düzenleme : Cevaplarınız için teşekkürler; Birkaç çözüm denedim. Hiçbiri işe yaramadı. Örneğin, GitHub'dan biri dosyaları geçmişten kaldırdı, ancak .gitdizin boyutu azalmadı:

$ 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
Moderatörler için bir hatırlatma, bu soru süper kullanıcıya değil,% 100 SO'ya aittir.
VonC


Burada belirtildiği gibi ( stackoverflow.com/questions/685319/… ), gc'nizden sonra yeniden paketlemeyi denediniz mi? git-repack -aardından git-prune-packedörneğin. Bkz. Blog.felipebalbi.com/2007/12/19/…
VonC

2
@Jonas: Peki ya bunları yaptıktan sonra deponuzu klonlarsanız? Eğer misiniz ardından istenen azaltılmış boyutta bir klon olsun?
VonC

1
@Jonas: hem bütün bundan sonra ( filter-branch, gc, repack, ...), hayır, hiçbir kötü hiç işlemek görmemelidir. Bu, temizliğin beklendiği gibi yapılmadığının bir işaretidir.
VonC

Yanıtlar:


129

Bunu başka bir yerde yanıtladım ve gurur duyduğum için burada kopyalayacağım!

... ve daha fazla uzatmadan, size bu kullanışlı komut dosyasını, git-gc-all'i sunabilir miyim, ekstra yapılandırma değişkenleri bulana kadar tüm git çöplerinizi kaldırmayı garanti eder:

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

Agresif seçeneği yardımcı olabilir.

NOT: Bu, referans gösterilmeyen TÜM şeyleri ortadan kaldıracaktır, bu yüzden daha sonra bazılarını saklamak istediğinize karar verirseniz bana ağlamaya gelmeyin!

Ayrıca önce bunlara benzer bir şey çalıştırmanız gerekebilir, oh canım, git karmaşıktır !!

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üm bunları burada bir senaryoya koydum:

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


Stackoverflow.com/questions/1904860/… 'de olduğu gibi size tekrar +1.
VonC

18
mükemmel: D cevapları klonlayarak daha fazla puan alma planım işe yaradı !! 1;)
Sam Watkins

Evet! Bu işe yaradı, ancak tam komut dosyasını çalıştırmam gerekiyordu. Yalnızca gc komutunu çalıştırmak (yapılandırma seçenekleriyle) yeterli değildi.
Daniel

4
102
dk

4
Senaryo için çok teşekkürler! Bonus bilgi: xargsKomut, tanınmayan bir seçenek nedeniyle OS X'te bir hata oluşturur. En basit çözüm: homebrew yoluyla GNU xargs takın brew install findutilsve yerine xargsgöre gxargs.
qqilihq

26

Sizin git reflog expire --allyanlıştır. Varsayılan olarak 90 gün olan sona erme süresinden daha eski olan yeniden günlüğe kaydetme girdilerini kaldırır. Kullanın git reflog expire --all --expire=now.

Benzer bir soruya verdiğim yanıt , kullanılmayan nesneleri bir depodan gerçekten temizleme sorunuyla ilgilidir.


18

1) Dosyayı git deposundan kaldırın (& dosya sisteminden değil):

  • git rm --cached path/to/file

2) Depoyu kullanarak küçültün:

  • git gc,

  • veya git gc --aggressive

  • veya git prune

veya bu soruda önerildiği gibi yukarıdakilerin bir kombinasyonu: Git depo boyutunu azaltın


10

Hassas verilerin kaldırılmasına ilişkin bu kılavuz , aynı yöntemi kullanarak geçerli olabilir. Bu dosyayı içinde bulunduğu her revizyondan kaldırmak için geçmişi yeniden yazacaksınız. Bu, yıkıcıdır ve diğer ödünç alma işlemleriyle repo çakışmalarına neden olacaktır, bu nedenle önce ortak çalışanları uyarın.

İkili dosyayı diğer insanlar için depoda tutmak istiyorsanız, o zaman istediğinizi yapmanın gerçek bir yolu yoktur. Hemen hemen hepsi ya da hiçbiri.


8

Benim için anahtarın çalıştığı git repack -A -d -fve ardından git gcsahip olduğum tek git paketinin boyutunu azalttığı ortaya çıktı .


6

Hy!

Git yalnızca depoları klonlarken gerçekten ihtiyaç duyduğu nesneleri alır (eğer doğru anladıysam)

Böylece, yanlışlıkla eklenen dosyayı kaldırarak son işlemi değiştirebilir, ardından değişikliklerinizi uzak depoya aktarabilirsiniz (sunucudaki eski kaydetmenin üzerine yazmak için -f seçeneği ile)

Daha sonra bu deponun yeni bir klonunu oluşturduğunuzda, bunun .git dizini büyük dosya (lar) kaydedilmeden önceki kadar küçük olmalıdır.

İsteğe bağlı olarak, gereksiz dosyaları sunucudan da kaldırmak isterseniz, sunucudaki depoyu silebilir ve yeni klonlanmış kopyanızı (tam geçmişe sahip olan) itebilirsiniz.


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

Depodan Filenamekaldırmak istediğinizi değiştirmeyi unutmayın .



Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.