Git'teki göz ardı edilen dizinlerin alt dizinlerini yoksayma


103

Diyelim ki bir dizini görmezden geldim, ancak buradaki belirli alt dizinleri yok saymak istiyorum. Bu yüzden kurulumum var:

/uploads/
/uploads/rubbish/
/uploads/rubbish/stuff/KEEP_ME/
/uploads/foo/
/uploads/foo/bar/lose/

Ve KEEP_MEdizin hariç her şeyi görmezden gelmek istiyorum . Umarım görmezden gelenin şöyle bir şeye benzemesi:

/uploads/*
!/uploads/rubbish/stuff/KEEP_ME/

Ama bu işe yaramıyor ve aynı tema üzerinde birkaç permütasyon da yok.

İşe yarayan biri

/uploads/**/**/**/
!/uploads/rubbish/stuff/KEEP_ME/

Ama bu biraz kısıtlayıcı ve ayrıntılı hissettiriyor?


1
Sağladığınız kod benim için çalışmadı (git sürüm 1.9.1 kullanılarak). İşe yarayan biri / uploads / *! / Uploads / çöp / / uploads / çöp / *! / Uploads / çöp / malzeme / uploads / çöp / malzeme / *! / Uploads / çöp / malzeme / tutmak (örneğe benzer içinde git-scm.com/docs/gitignore ). Klasör yapım; └ README.md └ uploads / foo / bar / lost / lost.txt └ uploads / rubbish / stuff / keep / keep.txt
gihanchanuka

Yanıtlar:


119

Gitignore belgelerinin desen biçimi bölümüne göre :

İsteğe bağlı bir ön ek "!" kalıbı olumsuzlayan; önceki bir kalıp tarafından hariç tutulan eşleşen herhangi bir dosya tekrar dahil edilecektir. Bir dosyanın üst dizini dışarıda bırakılırsa, bir dosyayı yeniden dahil etmek mümkün değildir. Git, performans nedenlerinden ötürü hariç tutulan dizinleri listelemez; bu nedenle, içerilen dosyalardaki herhangi bir örüntü, nerede tanımlanırsa tanımlansın, hiçbir etkiye sahip değildir. İlk "!" Karakterinin önüne bir ters eğik çizgi ("\") koyun. gerçek bir "!" ile başlayan desenler için, örneğin, "! önemli! .txt".

Bu nedenle, önceden hariç tutulan üst dizin /uploads/rubbish/stuff/keep/kalıbı, içeriği olumsuzlanmadan önce özel olarak olumsuzlanmalıdır:

#ignore everything within /uploads/ 
/uploads/*

#include everything within /uploads/rubbish/stuff/keep
!/uploads/rubbish/stuff/keep/  
!/uploads/rubbish/stuff/keep/*

Alt dizinleri dahil etmek /uploads/rubbish/stuff/keep/için üçüncü satırı ekleyin:

!/uploads/rubbish/stuff/keep/**/*

1
Git'in hangi sürümünü kullanıyordun? Belki de yalnızca belirli sürümlerde bulunan bir şeydir.

Mahçup. Bu yorumu yayınladığımı unuttum. Yine de çalıştırdım. FWIW, baştaki eğik çizgileri kullanmıyorum. Sorun bu muydu hatırlamıyorum. 1.7.2.5 kullanıyorum.

Tüm * .zip dosyasını yok saydığım global bir gitignore dosyam var. Yine de belirli bir proje için zip dosyalarını eklemek istiyorum. Bu satırı o projeye ekledim .gitignoreve harika çalışıyor !:!*.zip
Jinghao Shi

Hem klasörü hariç tutarken hem de alt klasörü dahil ederken verilen klasörden önce ve sonra rasgele dizinleri açıkça belirtmeyi gerekli buldum . ( Tam cevap ).
Josiah Yoder

1
Bu yöntem çalışmıyor (git 2.25'ten itibaren - belki git'te bir şey değişti). Düzeltme olarak aşağıda stackoverflow.com/a/60288435/295691 yayınladım .
user295691

35

Bir şey eklemek bile .gitignoreyapabilirsiniz zorlamak indeksi eklemek için git

git add --force uploads/rubbish/stuff/KEEP_ME/

Ancak, "KEEP_ME" bir dizin gibi görünüyor ve git genellikle boş klasörü sevmiyor, bu nedenle klasör boşsa bunun yerine bir "yer tutucu" tutucu dosyası eklemelisiniz

git add --force uploads/rubbish/stuff/KEEP_ME/.keep_me

Bununla ilgili tek sorun, bu özel örneğin bahsetmem gereken küresel bir gitignore'a atıfta bulunmasıdır. Öğeleri eklemeye zorlayabileceğimi biliyorum, ancak başlangıçta her yeni depo için olduğu gibi yeni öğeler eklenirse bunu yapmam gerekecek. .Keep, içeriğin göz ardı edilmemesini sağlıyor mu?
Wil

1
Küçük bir test yaptım. Evet, içindeki git add --forceher yeni öğe veya klasör için kullanmanız gerekir KEEP_ME. ancak bundan sonra, güncellemeler git add -usanki dosyalar 'imzalanmamış' gibi (örneğin yapılırken) eklenir . .keep_meO git klasörü çalışır böylece, onun sadece bir dosya hiçbir şey yapmaz.
commonpike

1
git add --forcebunun için yanlış çözüm. Bir dizini başka bir dizine taşırsanız veya dosyayı başka bir dizine taşırsanız, git'in izlemesi dosyayı siler ancak yeni konuma eklemez ve git add --forcetekrar yapmanız gerekir . genel bir model üzerinde yok sayarak git, depo içindeki bir dosyanın hareketini takip edecektir.
Merlin

Benim için işe yarayan tek çözüm bu. Klasörüm göz ardı edilmedi, ancak hiçbir şekilde ekleyemedim. Bu şekilde benim için çözdü.
Akito

6

Genel dışlama ile tüm klasörleri dışlarken belirli bir klasörü nasıl dahil edeceğinizi anlamaya çalışıyordu

**/build

/*genel dışlamanızın sonuna eklerseniz, tüm derleme dosyalarını hariç tutmaya devam edersiniz**/build/*

Ardından, dahil edilmesini istediğiniz yolu düzeltmek için başka bir satır eklersiniz.

!**/folder/build/* 

bize okuyan bir gitignore bırakıyor

**/build/* 
!**/folder/build/* 

4

Buo-Ren Lin ve John'un cevapları oldukça yardımcı oldu, ancak ikisini de birleştirmem gerekiyordu.

Diğer alt klasörleri ve yüklemelerdeki dosyaları hariç tutmak istediğimde, hem klasörü hariç tutarken hem de alt klasörü dahil ederken verilen klasörden önce rasgele dizinleri açıkça belirtmeyi gerekli buldum.

**/uploads/*
!**/uploads/rubbish/
!**/uploads/rubbish/*

Klasör ve alt klasörler içindeki hem öğeleri göstermek için hem alt klasörü hem de içeriğini açıkça yeniden dahil etmeyi gerekli buldum.


İç çekmek. Burada sıfır şans. Bu saatlerdir şimdi. Git 2.20.1
RichieHH

@ HörmannHH Bunu duyduğuma üzüldük. Belki de yeni bir soru sormanın zamanı gelmiştir?
Josiah Yoder

4

En çok oylanan cevap olarak sunulan çözüm yanlıştır ve bu nedenle kolayca ispatlanabilir.

Yüklemelerde her şeyi göz ardı ederek başlayın / *:

mkdir -p uploads/rubbish/stuff/KEEP_ME
touch uploads/a uploads/rubbish/a uploads/rubbish/stuff/a uploads/rubbish/stuff/KEEP_ME/a
echo '/uploads/*' >> .gitignore
git init
git add .
git commit -m "Initial commit"

Şimdi, yukarıdaki gibi göz ardı edilen öğelerin ana dizinini yoksayın:

echo 'uploads/rubbish/stuff/KEEP_ME/' >> .gitignore
echo 'uploads/rubbish/stuff/KEEP_ME/*' >> .gitignore
git status -u

İzlenmemiş dosya göstermez.

Çalışmasını sağlamak için, uploads/ağacın altındaki tüm dosyaları ( uploads/**/*sadece en üst seviyeyi değil) yok saymanız uploads/*ve ardından saklamak istediğiniz ağacın tüm ana dizinlerini eklemeniz gerekir.

echo '/uploads/**/*' > .gitignore
echo '!/uploads/rubbish/' >> .gitignore
echo '!/uploads/rubbish/stuff' >> .gitignore
echo '!/uploads/rubbish/stuff/KEEP_ME' >> .gitignore
echo '!/uploads/rubbish/stuff/KEEP_ME/*' >> .gitignore
git status -u

Hangi verir:

On branch master
...
Untracked files:
  (use "git add <file>..." to include in what will be committed)
        uploads/rubbish/stuff/KEEP_ME/a

Kullandığımız olsaydı uploads/*içinde .gitignoreyukarıdaki kuyu, böylece örneğin, o zaman tüm ara dosyalar dahil olurdu uploads/rubbish/aYukarıdaki durum komuta kadar gösterecek.


teşekkür ederim, benim için işe yarayan tek şey
Sebastien Lorber
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.