Git'in izlenen ancak şimdi .gitignore'da bulunan bir dosyayı "unutması" nasıl sağlanır?


5401

İzlenen bir dosya var git, ancak şimdi dosya .gitignorelistede.

Ancak, bu dosya git statusdüzenlendikten sonra görünmeye devam eder . Bunu gittamamen unutmaya nasıl zorlarsınız ?


16
git clean -Xkulağa benzer geliyor, ancak bu durumda geçerli değil (dosyalar hala Git tarafından izlenirken). Bunu yanlış yolu takip etmemek için çözüm arayan herkes için yazıyorum.
imz - Ivan Zakharyaschev

35
Bunun tek cevabı aşağıda git update-index --assume-unchanged. Bu çözüm 1) dosyayı sunucuda (indeks) tutar, 2) yerel olarak özgürce değiştirmenizi sağlar.
Qwerty

8
Kullanmanız gerekiyor --skip-worktree, bkz: stackoverflow.com/questions/13630849/…
Doppelganger

77
Önemli bir soru şudur: dosya depoda mı kalmalı mı? Örneğin, yeni biri repoyu klonlarsa, dosyayı alsın mı almasın mı? Eğer EVET sonra git update-index --assume-unchanged <file>doğru ve dosya depoda kalır ve değişikliklerin ile eklenmez git add. Eğer NO ardından (örneğin bazı önbellek dosyası oluşturulan dosya vb idi) git rm --cached <file>deposundan kaldırılmasına neden olur.
Martin

9
@Martin @Qwerty Everyon, git'in --assume-unchangedbüyük izlenen dosyaların durumunu kontrol etmesini önlemek için hangi performans için --skip-worktreeolduğunu, ancak kullanıcının artık işlemek istemediği değiştirilmiş izlenen dosyaları tercih etmesini önermelidir . Bkz. Stackoverflow.com/questions/13630849/…
Philippe

Yanıtlar:


5702

.gitignoreizlenmeyen dosyaların add -fgit tarafından izlenen dosya kümesine ( an olmadan ) eklenmesini önler , ancak git zaten izlenen dosyaları izlemeye devam eder.

Bir dosyayı izlemeyi durdurmak için dizinden kaldırmanız gerekir. Bu, bu komutla gerçekleştirilebilir.

git rm --cached <file>

Bir klasörün tamamını kaldırmak istiyorsanız, içindeki tüm dosyaları özyinelemeli olarak kaldırmanız gerekir.

git rm -r --cached <folder>

Dosyanın başlık revizyonundan kaldırılması bir sonraki işlemde gerçekleşecektir.

UYARI: Bu işlem fiziksel dosyayı yerel ayarınızdan kaldırmayacak olsa da, dosyaları bir sonraki geliştiricilerin makinelerinden kaldıracaktır git pull.


55
benim için çalışan işlem 1 oldu. beklemede değişiklikleri ilk taahhüt 2. git rm --cached <file> ve tekrar taahhüt 3. dosyayı .gitignore ekleyin, git durumu ile kontrol ve tekrar taahhüt
mataal

117
Çok önemli ekleme. Yok sayılan dosya değiştirilirse (ancak buna rağmen işlenmemelidir), değiştirildikten ve yürütüldükten sonra git add .dizine eklenir. Ve bir sonraki taahhüt onu depoya adayacaktır. Bundan kaçınmak için tüm bu mataal bir komut daha söyledi:git update-index --assume-unchanged <path&filename>
Dao

32
@AkiraYamamoto'nun yöntemi benim için de iyi çalıştı. Benim durumumda git rm -r -q --cached .
depomda

85
Bu, dosyayı git pullyine de siler .
Petr Peller

22
git rm --cached <file> dosyayı depodan kaldır, git update-index --assume-ungedged <file> dosyada değişiklik yapılmayan değişiklikler göstermez ve yeni bir değişiklik yapmaz. Ama GIT SADECE DOSYA LÜTFEN İÇERİĞİNİ GIT istiyorum
Igor Semin

2609

Aşağıdaki komut dizileri Git Dizini'nden (çalışma dizininden veya yerel repodan değil) tüm öğeleri kaldıracak ve sonra Git yoksayılırken Git Dizini'ni güncelleştirecektir. PS. Dizin = Önbellek

İlk:

git rm -r --cached . 
git add .

Sonra:

git commit -am "Remove ignored files"

Veya tek astarlı:

git rm -r --cached . && git add . && git commit -am "Remove ignored files"

197
Bu cevap ile kabul edilen cevap arasındaki farkı vurgulamak için: Bu komutları kullanarak etkilenen dosyaları gerçekten bilmeniz gerekmez. (Dizinden temizlenmesi gereken çok sayıda rastgele dosya içeren geçici bir dizin düşünün).
Ludwig

53
Kabul edilen cevapla aynı. Dosyalar silinecek git pull.
Petr Peller

73
Bunu standart git komutu olarak kullanmak güzel olurdu. Gibi bir şey git rmignored.
Berik

12
@gudthing -r "özyinelemeli" anlamına gelir
Mark

14
Bununla , şu anda içinde bulunmayan diğer yararsız dosyaları ekleyebilirsiniz .gitignore. git statusBu komuttan sonra ne kadar gürültünüz olduğuna bağlı olarak bunu bulmak zor olabilir . Yalnızca yeni yok sayılan dosyaları kaldıran bir komut daha iyi olur. Bu yüzden thSoft'un cevabını
KurzedMetal

1122

git update-index bu işi benim için yapıyor:

git update-index --assume-unchanged <file>

Not:.gitignore Gitignore yalnızca izlenmeyen dosyalar için olduğundan bu çözüm aslında bağımsızdır .

edit: Bu cevap gönderildiği için, yeni bir seçenek oluşturuldu ve bu tercih edilmelidir. --skip-worktreeKullanıcının artık işlemek istemediği değiştirilmiş izlenen dosyalar için hangisini kullanmalı ve --assume-unchangedgit'in büyük izlenen dosyaların durumunu kontrol etmesini önlemek için performansı korumalıdır. Daha fazla ayrıntı için bkz. Https://stackoverflow.com/a/13631525/717372 ...

git update-index --skip-worktree <file>

173
Bu IS Gerçek cevap. Aslında harika, çok basit, kirletmiyor git statusve aslında çok sezgisel. Teşekkürler.
Pablo Olmos de Aguilera C.

4
rm [...] .En azından nasıl çalıştığını görebildiğim için yeterince iyi bir çözüm buldum. Ben ne update-index& ne büyük bir belge bulunamadı --assume-unchanged. Hiç kimse yoksaydı olurdu tüm dosyaları kaldırmak istiyorum, bu diğeri ile karşılaştırmak nasıl ekleyebilir miyim? (Ya da açıklamanın bir bağlantısı mı?)
Brady Trainor

25
git update-index --assume-unchanged <path> …git ne olursa olsun git'in belirtilen yollardaki değişiklikleri yok saymasına neden olur .gitignore. Bir uzaktan kumandadan çekerseniz ve bu uzaktan kumandanın bu yolda değişiklikleri varsa git, bir çakışmayla birleştirmeyi başarısızlığa uğratır ve manuel olarak birleştirmeniz gerekir. git rm --cached <path> …git'in bu yolu izlemesini durdurmasına neden olur. Yolu eklemezseniz .gitignoreileride yolu görürsünüz git status. İlk seçenek git kesinleştirme geçmişinde daha az gürültüye sahiptir ve "yok sayılan" dosyada yapılacak değişikliklerin ileride dağıtılmasını sağlar.
ManicDee

26
Bunun kabul edilen cevap nasıl olmadığı konusunda oldukça kafam karıştı. Burada kabul edilen cevap açıkça sorulan asıl soruya cevap vermiyor. Bu yanıt, depodaki dosyadaki değişiklikleri, depodan kaldırmazken yok sayar.
Dave Cooper

11
Bu yanıt, verilen komutun ne yaptığını tam olarak açıklarsa, örneğin diğer önerilen çözümlerden nasıl farklı olduğunu açıklarsa çok daha yararlı olacaktır.
LarsH

283
git ls-files --ignored --exclude-standard -z | xargs -0 git rm --cached
git commit -am "Remove ignored files"

Bu, yok sayılan dosyaların listesini alır ve bunları dizinden kaldırır, ardından değişiklikleri yapar.


7
Bunları çalışma dizininden de kaldırmanız gerekirse, çalıştırın git ls-files --ignored --exclude-standard | xargs git rm . Bu cevabın en iyisi olduğuna inanıyorum! Çünkü çok açık, Unix-yoludur ve istenen şeyi diğer daha karmaşık komutların yan etkilerini oluşturmadan doğrudan yapar.
imz - Ivan Zakharyaschev

6
Mükemmel cevap; ancak, ortada boşlukları olan yollarınız varsa komut başarısız olur, örneğin: "Yönüm / my_ignored_file.txt"
David Hernandez

8
git ls-dosyaları --ignored --exclude-standard | sed 's /.*/"&"/' | xargs git rm - önbellekli
David Hernandez

3
git rmls-fileshiçbir şey eşleşmediğinde şikayet edecek . Hiçbir dosya eşleşmediğinde çalışmamasını xargs -r git rm ...söylemek xargsiçin kullanın git rm.
Wolfgang

10
\ 0'ı ayırıcı olarak kullanmak daha iyi olur:git ls-files --ignored --exclude-standard -z|xargs -0 git rm --cached
Nils-o-mat

83

İzlenmeyen dosyaları kaldırmak için her zaman bu komutu kullanırım. Tek satırlı, Unix tarzı, temiz çıktı:

git ls-files --ignored --exclude-standard | sed 's/.*/"&"/' | xargs git rm -r --cached

Tüm yok sayılan dosyalarınızı listeler, içindeki boşlukları olan yolları işlemek için her bir çıktı satırını tırnak içine git rm -r --cachedalınmış bir satırla değiştirir ve yolları / dosyaları / dizinleri dizinden kaldırmak için her şeyi iletir.


3
Harika bir çözüm! Mükemmel çalıştı ve tüm dosyaları kaldırdıktan sonra geri ekleyerek daha doğru hissediyor.
Jon Catmull

5
Ben de bu "temiz" buldum. Açık olabilir, ancak sadece ilk kısmı çalıştırmak, git ls-files --ignored --exclude-standardkendi başınıza .gitignore, devam etmeden ve finali yürütmeden önce yeni dosyalarınızın hangi dosyaları hariç tutacağını / kaldıracağını ilk önce anlamanıza / doğrulamanıza olanak tanır git rm.
JonBrave

Unutmayın, dosya adlarında belirli "kötü" karakterlerle başarısız olur, örn \n. Bunun için yiyecek ve içecek benim çözüm gönderdi.
JonBrave

3
Başka bir uyarı: çekildiğinde, bu dosyanın başkalarının çalışma dizinlerinde silinmesine neden olur, değil mi?
LarsH

denedim, ama benim için çalışmadı: sed: 1: "s/.*/": unterminated substitute in regular expressionboşluklu bir repo filtre şube komutunda. (Yine de filtre dalı dışında çalışmak gibi görünüyordu). Ben kullanılan git ls-files -z --ignored --exclude-standard | xargs -0 git rm -r --cachedden JonBrave en @ cevap yerine.
goofoloji

71

dışarı çıkarın, yerine getirin, sonra tekrar içeri alın. Bu geçmişte benim için çalıştı. Muhtemelen bunu başarmanın bir yolu vardır.


2
Daha önce göz ardı edilmeyen bir grup dosyayı yoksaymak istiyorsanız bu harika çalıştı. Söylediğin gibi, bunun için muhtemelen daha iyi bir yol var.
Oskar Persson

Ben de öyle yaptım. Dosyaları git dışında bir klasöre taşıyın, sonra "git add.", "Git commit" yapın. (Bu, dosyaları kaldırdı) sonra gitignore'u ekleyin, dosyalara / klasörlere başvurarak gitignore dosyasını git'e eklemeyi tekrar taahhüt edin, sonra klasörlere kopyalayın / geri taşıyın ve yok sayılmalıdır. Not: dosyaların GIT'den silindiği görülecektir, bu nedenle yukarıdaki çözümlerde belirtildiği gibi onları muhtemelen diğer kontrollerden / çekmelerden kaldıracaktır, ancak başlangıçta bunların kopyalarını yaptığınızdan, bu bir sorun IMHO kadar değildir. sadece ekibin geri kalanının bilmesini sağlayın ...
Del

Yanlış işlenmiş klasörlerden kurtulmanın en kolay yolu budur.
Martlark

2
Görebildiğim tek yol gibi görünüyor. Git'te büyük bir hata ('özellik' değil) .gitignore'a bir dosya / klasör eklediğinizde, bu dosyayı o noktadan itibaren - sonsuza dek - her yerde görmezden gelmez.
JosephK

Bu, onları ekledikten sonra çalıştı ve daha sonra gerçek onları .gitignore
hanzolo'ya

66

git rmİzlenen bir dosyayı başkalarına ihtiyaç duyabileceği için yapamıyorsanız (uyarı, senin git rm --cached başkası bu değişikliği aldığında, kendi dosyaları, dosya sisteminde silinecektir). Bunlar genellikle yapılandırma dosyası geçersiz kılmaları, kimlik doğrulama bilgileri vb. Nedeniyle yapılır. İnsanların sorunla ilgili çalışma yöntemleri için lütfen https://gist.github.com/1423106 adresine bakın .

Özetlemek:

  • Uygulamanızın yok sayılan config-overide.ini dosyasını aramasını sağlayın ve bunu taahhüt edilen config.ini dosyası üzerinde kullanın (veya alternatif olarak ~ / .config / myapp.ini veya $ MYCONFIGFILE dosyasını arayın)
  • Config-sample.ini dosyasını yürütün ve config.ini dosyasını yok sayın, gerekirse bir komut dosyası veya benzeri bir dosyayı kopyalayın.
  • Değişiklikleri uygulamak ve kaldırmak için gitattributes clean / smudge magic'i kullanmayı deneyin, örneğin config dosyasını alternatif bir daldan bir ödeme olarak lekeleyin ve config dosyasını HEAD'den bir ödeme olarak temizleyin. Bu zor şeyler, acemi kullanıcı için tavsiye etmiyoruz.
  • Yapılandırma dosyasını, ana sunucuya asla birleştirilmemiş bir dağıtım dalında tutun. Konuşlandırmak / derlemek / test etmek istediğinizde o dalla birleştirilir ve dosyayı alırsınız. Bu, insan birleştirme politikaları ve ekstra-git modülleri kullanmak dışında, lekelenme / temiz yaklaşımdır.
  • Anti-öneri: Varsayım değiştirmeden kullanmayın, sadece gözyaşlarıyla biter (çünkü git yalanın kendisine sahip olması, değişimin sonsuza dek kaybedilmesi gibi kötü şeylerin olmasına neden olur).

7
git silme işlemi sırasında kirli olsaydı dosyayı kaldırmazdı. Kirli değilse, dosyayı almak o kadar kolay olurdu git checkout <oldref> -- <filename>- ama sonra kontrol edilir ve yoksayılır.
amenthes

Son notunuz hakkında (yaklaşık --assume-unchanged): bu kargo kültüdür ve reddedilmelidir veya neden (ikna olduğum) açıklayabilir ve yararlı olur.
RomainValeri

57

Bunu şu durumlarda kullanın:

1. Çok sayıda dosyanın izini kaldırmak istiyorsunuz veya

2. gitignore dosyanızı güncellediniz

Kaynak bağlantı: http://www.codeblocq.com/2016/01/Untrack-files-already-added-to-git-repository-based-on-gitignore/

Diyelim ki git deponuza zaten bazı dosyalar eklediniz / işlediniz ve bunları .gitignore'unuza eklediniz; bu dosyalar depo dizininizde bulunmaya devam edecektir. Bu makalede onlardan nasıl kurtulacağımızı göreceğiz.

1. Adım: Tüm değişikliklerinizi yapın

Devam etmeden önce, .gitignore dosyanız da dahil olmak üzere tüm değişikliklerin yapıldığından emin olun.

2. Adım: Depodaki her şeyi kaldırın

Repoyu temizlemek için şunu kullanın:

git rm -r --cached .
  • rm kaldır komutudur
  • -r özyinelemeli kaldırmaya izin verir
  • –Cached dosyaları yalnızca dizinden kaldırır. Dosyalarınız hala orada olacak.

rmKomut affetmez olabilir. Önceden ne yaptığını denemek istiyorsanız, -nveya--dry-run şeyleri test etmek işaretini .

3. Adım: Her şeyi yeniden ekleyin

git add .

4. Adım: Tamamlama

git commit -m ".gitignore fix"

Deponuz temiz :)

Değişiklikleri orada da görmek için değişiklikleri uzaktan kumandanıza itin.


1
Uzak depodaki dosyaları silmez mi? Dosyaları hem yerel hem de uzak repoda tutmak, ancak git onlar hakkında "unutmak" istersem ne olur?
Avishay28

AFAIK bu, geçmişten dosya silmeyecektir, çünkü herhangi bir geçmiş değiştirme komutu kullanmıyoruz (eğer yanılıyorsam beni düzelt). Tarihsel taahhütler
Dheeraj Bhaskar

49

Bunu git filtre-dalını kullanarak başardım . Kullandığım tam komut man sayfasından alındı:

UYARI : bu, dosyayı tüm geçmişinizden siler

git filter-branch --index-filter 'git rm --cached --ignore-unmatch filename' HEAD

Bu komut, git rmher bir işlemden önce yürütülerek tüm işlem geçmişini yeniden oluşturur ve böylece belirtilen dosyadan kurtulur. O kadar komutunu çalıştırmadan önce yedeklemek unutmayın edecektir kaybolabilir.


9
Bu, tüm taahhüt kimliklerini değiştirir, böylece deponuzun kopyasının dışındaki dallardan birleşmeleri keser.
bdonlan

19
UYARI: bu, dosyayı tüm geçmişinizden siler. Sürüm geçmişinde uzun zaman önce işlenen tamamen gereksiz ve büyük boyutlu bir dosyayı (asla işlenmemiş olması gereken çıktı) kaldırmak için aradığım şey buydu.
zebediah49

48

Benim için işe yaramayan

(Linux altında), buradaki ls-files --ignored --exclude-standard | xargs git rm -r --cachedyaklaşımı öneren yayınları kullanmak istedim . Ancak, kaldırılacak dosyaların (bazılarında) \nadlarında katıştırılmış yeni satır / LF / bulunur . Çözümlerin hiçbiri:

git ls-files --ignored --exclude-standard | xargs -d"\n" git rm --cached
git ls-files --ignored --exclude-standard | sed 's/.*/"&"/' | xargs git rm -r --cached

bu durumla başa çık (dosyalar hakkında hata bulunamadı).

Bu yüzden teklif ediyorum

git ls-files -z --ignored --exclude-standard | xargs -0 git rm -r --cached
git commit -am "Remove ignored files"

Bu kullanır -ziçin argüman ls dosyaları ve -0karşı argüman Xargs hitap Dosya adlarında güvenle / doğru için "pis" karakter.

Kılavuz sayfasında git-ls-files (1) şunu belirtir:

-Z seçeneği kullanılmadığında, yol adlarındaki SEKME, LF ve ters eğik çizgi karakterleri sırasıyla \ t, \ n ve \\ olarak gösterilir.

dosya adlarında bu karakterlerden herhangi biri varsa benim çözümüm gerektiğini düşünüyorum.


1
Benim için bu en iyi çözüm. A'dan çok daha iyi bir performansa sahiptir git add .. Ayrıca yukarıdaki bazı yorumlardan en iyi gelişmeleri içerir.
Nils-o-mat

git commit -am "Remove ignored files"Daha sonra cevabınıza thSoft's ekleyebilir misiniz ? Cevaplarınız birleştirildi beni şeylere: j
kando

Amacını anlamıyorum git commit -a. Benim için git rm --cachedtam olarak endeksi etkiler, bu yüzden dosyaları sonra sahneye gerek yok ...
Jean Paul

23
  1. .gitignoreDosyanızı güncelleyin - örneğin, izlemek istemediğiniz bir klasör ekleyin .gitignore.

  2. git rm -r --cached .- İstenen ve istenmeyen dahil olmak üzere tüm izlenen dosyaları kaldırın. Yerel olarak kaydettiğiniz sürece kodunuz güvende olacaktır.

  3. git add .- Dosyaları hariç, tüm dosyalar geri eklenir .gitignore.


Bizi doğru yöne yönlendirdiği için @AkiraYamamoto'ya şapka ucu.


1
Her ne kadar rm'yi yinelemeli olarak çalıştırmak için bir -r'ye ihtiyacınız olduğu için aslında çalışmadığı gerçeği nedeniyle aşağıya düşme :) (Birisi doğru kopyalamadı)
Aran Mulholland

1
Uyarı: Bu teknik git'in dosyayı görmezden gelmesine neden olmaz, bunun yerine git'in dosyayı silmesine neden olur. Bu, bu çözümü kullanırsanız, herhangi bir kişi bir git çekme işlemi gerçekleştirdiğinde, dosyanın silineceği anlamına gelir. Yani aslında görmezden gelinmiyor. Orijinal sorunun çözümü için git update-index --assume-unchanged önerisini içeren çözüme bakın.
orrd

16

Bence, belki de git nedeniyle dosya tamamen unutulamıyor ( bölüm "Anlık Görüntüler, Farklar" bölümü ).

Bu sorun, örneğin CVS kullanılırken mevcut değildir. CVS, bilgileri dosya tabanlı değişikliklerin bir listesi olarak saklar. CVS bilgileri, bir dosya kümesidir ve zamanla her dosyada yapılan değişikliklerdir.

Ancak Git'te projenizin durumunu her kaydettiğinizde veya kaydettiğinizde, temelde o anda tüm dosyalarınızın nasıl göründüğünün bir resmini çeker ve bu anlık görüntüye bir referans depolar. Yani, bir kez dosya eklediyseniz, bu anlık görüntüde her zaman bulunacaktır.

Bu 2 makale bana yardımcı oldu:

git varsay-değişmedi vs atlama-worktree ve Git ile izlenen dosyalarda değişiklik nasıl göz ardı edilir

Buna dayanarak dosya zaten izleniyorsa aşağıdakileri yaparım:

git update-index --skip-worktree <file>

Bu andan itibaren bu dosyadaki tüm yerel değişiklikler göz ardı edilecek ve uzaktan kumandaya geçmeyecek. Dosya uzaktan kumandayla değiştirilirse, çakışma olur git pull. Stash çalışmaz. Bu sorunu çözmek için dosya içeriğini güvenli bir yere kopyalayın ve şu adımları izleyin:

git update-index --no-skip-worktree <file>
git stash
git pull 

Dosya içeriği uzak içerikle değiştirilecektir. Değişikliklerinizi güvenli yerden dosyaya yapıştırın ve tekrar gerçekleştirin:

git update-index --skip-worktree <file>

Eğer proje ile çalışan herkes performans gösterecekse git update-index --skip-worktree <file>, problemleri pullolmamalıdır. Bu çözüm, her geliştiricinin kendi proje yapılandırmasına sahip olduğu yapılandırma dosyaları için uygundur.

Dosya uzaktan kumandayla değiştirildiğinde her seferinde bunu yapmak çok uygun değildir, ancak uzak içeriğin üzerine yazılmasına karşı koruyabilir.


16

Aşağıdaki adımları seri olarak yapın, iyi olacaksınız.

1. kaldır yanlışlıkla eklenen dosyaları / depodan . "Rm -r" (linux için) komutunu kullanabilir veya dizinlere göz atarak bunları silebilirsiniz. Veya bunları PC'nizdeki başka bir konuma taşıyın. [ Taşıma / çıkarma için çalıştırıyorsanız IDE'yi kapatmanız gerekebilir ]

2. dosyaları / dizinleri gitignoreşimdi dosyaya ekleyin ve kaydedin.

3. onları kaldır bu komutları kullanarak git önbellekten (birden fazla dizin varsa, bu komutu tekrar tekrar bunları tek tek kaldırın)

git rm -r --cached path-to-those-files

4.Now yapmak bir taahhüt ve itme , bu komutları kullanabilirsiniz. Bu, bu dosyaları git remote'dan kaldırır ve git'in bu dosyaları izlemeyi durdurmasını sağlar.

git add .
git commit -m "removed unnecessary files from git"
git push origin

13

Kopyala / yapıştır yanıtı git rm --cached -r .; git add .; git status

Bu komut, Git deposuna zaten taahhüt edilmiş olan dosyaları yok sayar, ancak şimdi bunları ekledik .gitignore.


9

Matt Fear'ın cevabı en etkili IMHO'ydu. Aşağıdakiler, pencerelerde bulunanlar için yalnızca dışlama listesiyle eşleşen git git deposundan dosyaları kaldırmak üzere kullanılan bir PowerShell betiğidir.

# Get files matching exclusionsfrom .gitignore
# Excluding comments and empty lines
$ignoreFiles =  gc .gitignore | ?{$_ -notmatch  "#"} |  ?{$_ -match  "\S"} | % {
                    $ignore = "*" + $_ + "*"
                    (gci -r -i $ignore).FullName
                }
$ignoreFiles = $ignoreFiles| ?{$_ -match  "\S"}

# Remove each of these file from Git 
$ignoreFiles | % { git rm $_}

git add .

Hangi durumda bu dosya listesi özyinelemeli --cached'a eşit olmaz?
John Zabroski

8

Dosyayı güvenli bir konuma taşıyın veya kopyalayın, böylece kaybetmezsiniz. Sonra git rm dosyasını ve taahhüt. Daha önceki taahhütlerden birine veya kaldırılmadığı başka bir şubeye dönerseniz dosya görünmeye devam eder. Ancak, gelecekteki tüm taahhütlerde dosyayı bir daha görmezsiniz. Dosya git yoksay öğesindeyse, dosyayı tekrar klasöre taşıyabilirsiniz ve git dosyayı görmez.


34
git rm --cacheddosyayı diskten silmeden dizinden kaldıracaktır, bu yüzden taşımaya / kopyalamaya gerek yoktur
bdonlan

7

git rm --cachedKomutun kullanılması orijinal soruya cevap vermez:

git[Bir dosyayı] tamamen unutmaya nasıl zorlarsınız ?

Aslında, bu çözüm bir !! Yürütülürken dosyanın deponun diğer tüm örneklerinde silinmesine neden olur git pull.

Git'i bir dosyayı unutmaya zorlamanın doğru yolu, GitHub tarafından burada belgelenir .

Belgeleri okumanızı tavsiye ederim, ancak temel olarak:

git fetch --all
git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch full/path/to/file' --prune-empty --tag-name-filter cat -- --all
git push origin --force --all
git push origin --force --tags
git for-each-ref --format='delete %(refname)' refs/original | git update-ref --stdin
git reflog expire --expire=now --all
git gc --prune=now

full/path/to/filedosyanın tam yolu ile değiştirin . Dosyayı bilgisayarınıza eklediğinizden emin olun .gitignore.

Git geçmişinizi değiştirdiğiniz için deponuza hızlı ileriye doğru olmayan itmelere de (geçici olarak) izin vermeniz gerekir.


5

BFG o (-in-your-akım-işlemediği) dosyaları herhangi bir büyük tarihsel kaldıracaktır basit bayrağı vardır, böylece özellikle Git repo dan büyük dosyaları veya şifreler gibi istenmeyen verileri kaldırmak için tasarlanmıştır: '--strip-blobs- daha büyük'

$ java -jar bfg.jar --strip-blobs-bigger-than 100M

Dosyaları ada göre belirtmek isterseniz, bunu da yapabilirsiniz:

$ java -jar bfg.jar --delete-files *.mp4

BFG, git filtre kolundan 10-1000x daha hızlıdır ve genellikle kullanımı çok daha kolaydır - daha fazla ayrıntı için tüm kullanım talimatlarını ve örneklerini kontrol edin .

Kaynak: https://confluence.atlassian.com/bitbucket/reduce-repository-size-321848262.html


5

CLI'yi kullanmak istemiyorsanız ve Windows üzerinde çalışıyorsanız, TortoiseGit'i kullanmak için çok basit bir çözüm, iyi çalışan menüde "Sil (yerel tut)" Eylemine sahiptir.


5

JonBrave'nin cevabını beğendim, ancak -a beni biraz korkutacak kadar dağınık çalışma dizinlerim var, işte yaptığım şey:

git config - küresel alias.exclude-ignored '! git ls-files -z --ignored --exclude-standard | xargs -0 git rm -r - önbelleğe alınmış && git ls-files -z --ignored --exclude-standard | xargs -0 git stage && git stage .gitignore && git commit -m "yeni gitignore ve yok sayılan dosyaları dizinden kaldır"

parçalamak:

git ls-files -z --ignored --exclude-standard | xargs -0 git rm -r --cached 
git ls-files -z --ignored --exclude-standard | xargs -0 git stage 
git stage .gitignore 
git commit -m "new gitignore and remove ignored files from index"
  • yok sayılan dosyaları dizinden kaldır
  • stage .gitignore ve az önce kaldırdığınız dosyalar
  • işlemek

4

Bu artık en son git'te (yazma sırasında v2.17.1) bir sorun değildir.

.gitignoreSonunda izlenen-ama-silinen dosyaları yoksayar. Aşağıdaki komut dosyasını çalıştırarak bunu kendiniz test edebilirsiniz. Son git statusaçıklamada "yapılacak hiçbir şey yok" ifadesi yer almalıdır.

# Create empty repo
mkdir gitignore-test
cd gitignore-test
git init

# Create a file and commit it
echo "hello" > file
git add file
git commit -m initial

# Add the file to gitignore and commit
echo "file" > .gitignore
git add .gitignore
git commit -m gitignore

# Remove the file and commit
git rm file
git commit -m "removed file"

# Reintroduce the file and check status.
# .gitignore is now respected - status reports "nothing to commit".
echo "hello" > file
git status

Git bunu şimdi yaptığım için memnunum. Ancak OP, .gitignore dosyasında bulunan dosyalarda yapılan değişiklikleri izlememeyi, hala durum gösteren dosyaları silmemeyi soruyordu.
mrturtle

2

Önceden taahhüt edilmiş olması halinde DS_Store:

find . -name .DS_Store -print0 | xargs -0 git rm --ignore-unmatch

Bunları yoksay:

echo ".DS_Store" >> ~/.gitignore_global
echo "._.DS_Store" >> ~/.gitignore_global
echo "**/.DS_Store" >> ~/.gitignore_global
echo "**/._.DS_Store" >> ~/.gitignore_global
git config --global core.excludesfile ~/.gitignore_global

Son olarak, bir taahhütte bulunun!


2

Özellikle IDE tabanlı dosyalar için bunu kullanıyorum:

Örneğin slnx.sqlite, ben sadece tamamen aşağıdaki gibi kurtulmak:

git rm {PATH_OF_THE_FILE}/slnx.sqlite -f
git commit -m "remove slnx.sqlite"

Bu dosyaların bazılarının bazı yerel kullanıcı ayarlarını ve projeler için tercihleri ​​(açtığınız dosyalar gibi) depoladığını unutmayın. Dolayısıyla, IDE'nizde her gezinişinizde veya bazı değişiklikler yaptığınızda, bu dosya değiştirilir ve bu nedenle dosyayı kontrol eder ve taahhüt edilmemiş değişiklikler olduğunu gösterir.


2

Kabul edilen cevap Git'i bir dosya hakkında "unutturmaz" ... (tarihsel olarak). Bu sadece git'in şimdiki / gelecekteki dosyayı yoksaymasını sağlar .

Bu yöntem markaları git'e unutmak tamamen göz ardı dosyaları ( geçmiş / bugün / gelecek), ancak does not (uzaktan gelen yeniden çekti bile) çalışma dizinden silme şey.

Bu yöntem /.git/info/exclude(tercih edilen) VEYA bir önceden varolan .gitignore içinde tüm dosyaları var kaydedilmesini unutulmuş / göz ardı edilecek.1

Git'in uygulanmasına yönelik tüm yöntemler, gerçekte etkili bir şekilde yeniden yazma geçmişinden sonra davranışı görmezden gelir ve bu nedenle, bu işlemden sonra çekilebilecek herhangi bir kamu / paylaşılan / işbirlikçi depo için önemli sonuçlar doğurur. 2

Genel tavsiye: temiz bir repo ile başlayın - her şey yapıldı, çalışma dizininde veya dizinde bekleyen hiçbir şey yok ve bir yedek alın !

Ayrıca, yorum / düzeltme geçmişi içinde bu cevabı ( ve düzeltme geçmişi arasında bu soruya ) aydınlatarak / faydalı olabilir.

#commit up-to-date .gitignore (if not already existing)
#this command must be run on each branch

git add .gitignore
git commit -m "Create .gitignore"

#apply standard git ignore behavior only to current index, not working directory (--cached)
#if this command returns nothing, ensure /.git/info/exclude AND/OR .gitignore exist
#this command must be run on each branch

git ls-files -z --ignored --exclude-standard | xargs -0 git rm --cached

#Commit to prevent working directory data loss!
#this commit will be automatically deleted by the --prune-empty flag in the following command
#this command must be run on each branch

git commit -m "ignored index"

#Apply standard git ignore behavior RETROACTIVELY to all commits from all branches (--all)
#This step WILL delete ignored files from working directory UNLESS they have been dereferenced from the index by the commit above
#This step will also delete any "empty" commits.  If deliberate "empty" commits should be kept, remove --prune-empty and instead run git reset HEAD^ immediately after this command

git filter-branch --tree-filter 'git ls-files -z --ignored --exclude-standard | xargs -0 git rm -f --ignore-unmatch' --prune-empty --tag-name-filter cat -- --all

#List all still-existing files that are now ignored properly
#if this command returns nothing, it's time to restore from backup and start over
#this command must be run on each branch

git ls-files --other --ignored --exclude-standard

Son olarak, bu GitHub kılavuzunun geri kalanını izleyin (6. adımdan başlayarak) komutlarla ilgili önemli uyarıları / bilgileri içeren .

git push origin --force --all
git push origin --force --tags
git for-each-ref --format="delete %(refname)" refs/original | git update-ref --stdin
git reflog expire --expire=now --all
git gc --prune=now

Şimdi değiştirilmiş uzak repodan gelen diğer geliştiriciler bir yedek oluşturmalı ve sonra:

#fetch modified remote

git fetch --all

#"Pull" changes WITHOUT deleting newly-ignored files from working directory
#This will overwrite local tracked files with remote - ensure any local modifications are backed-up/stashed

git reset FETCH_HEAD

Dipnotlar

1 Çünkü /.git/info/excludebelki de yukarıdaki talimatları kullanarak tüm tarihi kaydedilmesini uygulanan alma hakkında ayrıntılı bilgi alınabilir .gitignoredosyası içine tarihsel bunun bu yanıt kapsamı dışındadır gerek (ler) işlemek. Yaptığım .gitignoreilk şeymiş gibi kök salmış olmak istedim . Diğerleri umursamayabilir, çünkü taahhüt tarihinde var olan /.git/info/excludeyere bakılmaksızın aynı şeyi başarabilir ve sonuçların farkında olsa bile .gitignoretarihin açıkça yeniden yazılması çok hassas bir konudur .

FWIW, potansiyel yöntemler, bu sorunun cevapları gibi her bir taahhüde haricigit rebase bir git filter-branchkopya içerebilir .gitignore

2 Git git rm --cachedkomutunun, aslında bağımsız bir komutun sonuçlarını uygulayarak yoksayma davranışını zorlamak, zorla itilen uzaktan kumandanın gelecekteki çekmelerinde yeni yok sayılan dosya silinmesine neden olabilir . Aşağıdaki --prune-emptykomuttaki bayrak, git filter-branchyalnızca "tüm yok sayılan dosyaları sil" dizinine yalnızca otomatik olarak kaldırarak bu sorunu önler. Git tarihinin yeniden yazılması , kamusal / paylaşılan / işbirlikçi depolardan gelecekteki çekimlere zarar verecek olan karma karmaları da değiştirir . Lütfen böyle bir repoya yapmadan önce sonuçları tam olarak anlayın . Bu GitHub kılavuzu aşağıdakileri belirtir:

Ortak çalışanlarınıza yeniden pazarlamasını söyleyin , değil birleştirme, bunlar eski (kusurlu) depo tarihin kapalı oluşturulan herhangi dalları. Bir birleştirme taahhüdü, tasfiye etme sorununa gittiğiniz lekeli tarihin bir kısmını veya tamamını yeniden başlatabilir.

Alternatif çözümler yok uzak repo etkileyecek olan git update-index --assume-unchanged </path/file>veya git update-index --skip-worktree <file>örnekleri bulunabilir, burada .


0

Windows'da zor zamanlar geçiren ve tüm klasörü yoksaymak istiyorsanız, 'cd' yi 'klasör' ye getirin ve 'Git Bash Here' yapın.

git ls-files -z | xargs -0 git update-index --assume-unchanged

0

Burada benim durumumda, kaldırmak için gereken birkaç dizin birkaç .lock dosyaları vardı. Aşağıdaki koştu ve bunları kaldırmak için her dizine gitmek zorunda kalmadan çalıştı:

git rm -r --cached **/*.lock

Bunu yaptığım yerde 'kök' altındaki her bir klasöre gitti ve desen ile eşleşen tüm dosyaları hariç tuttu.

Umarım bu başkalarına yardımcı olur!

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.