İçeriği silmeden çok sayıda dosyayı nasıl ayıklayabilirsiniz


454

Yanlışlıkla birçok geçici dosya ekledim git add -A

Aşağıdaki komutları kullanarak dosyaları bozmayı başardım ve kirli dizini kaldırmayı başardım.

git ls-files -z | xargs -0 rm -f
git diff --name-only --diff-filter=D -z | xargs -0 git rm --cached

Yukarıdaki komutlar git help rm. Ne yazık ki, önbellek seçeneği vermiş olmama rağmen, dosyalarım yürütme sırasında da silindi. İçeriği kaybetmeden dizini nasıl temizleyebilirim?

Ayrıca birisi bu boru işleminin çalışma şeklini açıklayabilirse yararlı olacaktır.


8
rm -fgit komutu değildir ve bir --cachedseçeneği yoktur. Yürütülmeden önce yerel dosyalarınız silindi, git rmbu yüzden git rmherhangi bir şey için meşru bir şekilde suçlayabileceğinizi düşünmüyorum .
CB Bailey

8
@sarat gelen yüksek upvoted cevaba doğru cevap değiştirmeyi düşünün lütfen Ian Maddox gibi git reset --hardolan doğru yanıt değil ve aslında içeriği silecektir. Bu benim gibi kullanıcıları karıştırır.
Marco Pashkov

2
Marco'nun söylediği gibi, devam et. Bu sayfa çok fazla trafik alıyor.
Ross

@ MarcoPashkov & Ross teşekkürler çocuklar. Bitti.
sarat

Yanıtlar:


986

git reset

İstediğiniz tek şey aşırı "git add" çalışmasını geri almaksa:

git reset

Değişiklikleriniz etiketsiz olacak ve istediğiniz gibi yeniden eklemeniz için hazır olacaktır.


KOŞMAYIN git reset --hard.

Yalnızca eklenen dosyalarınızı bozmaz, aynı zamanda çalışma dizininizde yaptığınız değişiklikleri geri alır. Eğer dizin çalışma herhangi bir yeni dosyalar oluşturdu, bu olmaz olsa silin.


15
Sana bir pint borçluyum
DasBooten

1
Sık sık yapmak zorunda bulmak git checkout -- *yanı
Den-Jason

1
Çok çaba harcadın. Teşekkürler adam
RajnikantDixit

35

Eğer bir bozulmamış repo var (ya BAŞ ayarlanmazsa) Eğer [1] basitçe olabilir

rm .git/index

Tabii ki, bu o dosyaları yeniden eklemek gerekecektir vermedi eklenecek istiyorum.


[1] Not (yorumlarda açıklandığı gibi) bu genellikle sadece repo yepyeni ("bozulmamış") olduğunda veya hiçbir taahhütte bulunulmadığında gerçekleşir. Daha teknik olarak, herhangi bir ödeme veya çalışma ağacı olmadığında.

Sadece daha açık hale getirmek :)


Evet, oluşturulan dizinin kendisini silmek gibi. İyi olan şu ki, git'i yeniden başlatmaya gerek duymuyorum. Teşekkürler!
sarat

Güvenli bir operasyon olduğundan emin misiniz? Ben sadece (aslında indeks yol dışına taşındı) yaptım ve diğer tüm dosyaları silmek için hazırlandı.
inger

@inger "El değmemiş bir deponuz varsa". Bunu açıkça bilmiyordun.
sehe

Aslında, "bozulmamış repo" ile ne demek istediğini merak ediyordum (ben de google ile şanslı hissetmiyorum) .. Yani aslında boş bir repo demek istedin?
inger

1
@inger Kabul Ediyorum. OP'nin tam olarak bu duruma sahip olduğunu varsaymalıydım - bunu belirtmiyor, ancak açıklaması olasılığı bırakıyor. Her neyse, sadece bilgi paylaşıyorum ve oylamayı etkileyemiyorum :(. Gelecekte başkalarına yardımcı olması durumunda cevap metnine bir uyarı sözü ekledim.
44'te sehe

15

git reset HEADDosyaları kaldırmadan dizini sıfırlamak için kullanın . (Dizindeki yalnızca belirli bir dosyayı sıfırlamak istiyorsanız, bunu git reset HEAD -- /path/to/fileyapmak için kullanabilirsiniz .)

Bir borudaki boru operatörü, stdoutsoldaki stdinişlemi alır ve sağdaki işleme geçirir . Bu var esasen eşdeğer:

$ proc1 > proc1.out
$ proc2 < proc1.out
$ rm proc1.out

ancak bunun yerine $ proc1 | proc2, ikinci işlem, çıktı alınmadan önce veri almaya başlayabilir ve gerçek bir dosya yoktur.


ancak birden çok dosyayla nasıl kullanılacağına dair. Bu dosyaları daha önce hiç taahhüt etmedim.
sarat

3
git reset HEADBaşka bir şey belirtmeden yazmanız yeterlidir ve tüm dizini sıfırlar. Daha sonra yalnızca istediğiniz dosyaları yeniden ekleyebilirsiniz.
Amber

Aşağıdaki hatayı aldım. Bu eşyaları daha önce hiç taahhüt etmedim. $ git reset HEAD fatal: ambiguous argument 'HEAD': unknown revision or path not in the working tree. Use '--' to separate paths from revisions
sarat

1
Sadece git reseto zaman deneyin HEAD.
Amber

Zaten aşağıdaki hatayı buldum denedim. $ git reset fatal: Failed to resolve 'HEAD' as a valid ref.
sarat

9
git stash && git stash pop

2
Ben de 'git stash & & git stash pop' yapmak istiyorum böylece stash da silinir. 'Uygula', saklamak saklamak listesinde kalır.
chitti

8

HEAD ayarlanmadıysa (yani, henüz taahhütte bulunmadıysanız, ancak .gitkorumak istediğiniz başka bir repo yapılandırması ayarladığınız için sadece havaya uçmak istemezsiniz), ayrıca

git rm -rf --cached .

herşeyi bozmak için. Bu, sehe'nin çözümü ile etkili bir şekilde aynıdır, ancak Git dahili ile mucking yapmaktan kaçınır.


bu aslında Git'e önbellekteki alandaki her şeyi silmesini söyler.
Vizyoner Yazılım Çözümleri

1
Önbellek, hazırlama alanı olarak da bilinir, bu yüzden ne elde ettiğinden emin değilim.
jjlin

Sehe'den rm .git / index çok tehlikelidir - yepyeni bir repo ile ilgili NOT'u okuduğunuzdan emin olun! Bu, zamanın% 99,999'u için daha güvenlidir. Dikkatle okumadım ve çalışma kopyamda rm .git / index yaptıktan sonra çalışma kopyamı uçurup yeniden klonlamak zorunda kaldım.
phpguru

Bu komutu KULLANMAYIN! TÜM projeyi izlenmeyen duruma (aşamalı olmayanlar da dahil) değiştirecektir. Bu orijinal sorunun çözümü değildir. 'Git rm' komutunu kullanarak doğru çözüm SADECE etiketsiz olmasını istediğiniz dosyaları belirtmektir: git rm -rf --cached <dizginlemek istediğiniz dosyalar>.
Monte Creasor

Bu komutu yalnızca henüz taahhütleri olmayan yeni bir repo'unuz olduğunda kullanmalısınız ("HEAD ayarlanmadı" anlamına gelir), ancak .gitbaşka bir repo yapılandırması kurduğunuz için sadece havaya uçmak istemezsiniz. tutmak istiyorum. Bunu açıklığa kavuşturmak için düzenledim.
jjlin

5

Uyarı: Taahhütsüz çalışmayı kaybetmek istemiyorsanız aşağıdaki komutu kullanmayın!

Kullanımı git resetaçıklanmıştır, ancak borulu komutların da açıklanmasını istediniz, işte burada:

git ls-files -z | xargs -0 rm -f
git diff --name-only --diff-filter=D -z | xargs -0 git rm --cached

Komut git ls-files, git'in bildiği tüm dosyaları listeler. Seçenek -z, kendilerine beklenen bir formatı xargs -0bekler rm -f, bu da onları çağırır , bu da onayınızı kontrol etmeden kaldırmanız anlamına gelir.

Başka bir deyişle, "git bildiği tüm dosyaları listele ve yerel kopyanızı kaldır".

Sonra git diff gidiyoruz, git bildiği öğelerin farklı sürümleri arasındaki değişiklikleri gösterir. Bunlar farklı ağaçlar arasındaki değişiklikler, yerel kopyalar ile uzak kopyalar arasındaki farklar vb. Olabilir.
Burada kullanılan şekliyle değişmemiş değişiklikleri gösterir; değiştirdiğiniz ancak henüz işlemediğiniz dosyalar. Bu seçenek --name-onlyyalnızca (tam) dosya adlarını istediğiniz --diff-filter=Danlamına gelir ve yalnızca silinen dosyalarla ilgilendiğiniz anlamına gelir. (Hey, sadece bir sürü şeyi silmedik mi?) Bu, daha xargs -0önce gördüğümüz borulara bindirilir, bu git rm --cachedda onları çağırır , yani çalışma ağacı tek başına bırakılırken, önbellekten kaldırıldıkları anlamına gelir. çalışma ağacınızdaki tüm dosyaları yeni kaldırdınız. Şimdi onlar da dizininizden kaldırıldı.

Başka bir deyişle, aşamalı veya düzensiz tüm değişiklikler gitti ve çalışma ağacınız boş. Ağlayın, dosyalarınızı başlangıçtan veya uzaktan yeni olarak kontrol edin ve çalışmanızı yeniden yapın. Bu şeytani çizgileri yazan sadisti lanetleyin; Neden kimse bunu yapmak isteseydi hiçbir fikrim yok.


TL; DR: herşeyi az önce barındırdınız; baştan başla ve kullangit reset .


2

Korkarım bu komut satırlarından ilki çalışmadan koşulsuz olarak silinen git'in hazırlama alanındaki tüm dosyaları kopyalar. İkincisi, izlenen ancak şimdi silinmiş olan tüm dosyaların etiketlerini kaldırdı. Maalesef bu, bu dosyalarda taahhüt edilmeyen değişiklikleri kaybetmiş olacağınız anlamına gelir.

Çalışma kopyanızı ve dizininizi son işlemde nasıl olduklarına geri döndürmek istiyorsanız , aşağıdaki komutu ( dikkatlice ) kullanabilirsiniz:

git reset --hard

"Dikkatli" diyorum çünkü git reset --hard çalışma kopyanızdaki taahhüt edilmemiş değişiklikleri yok edecek ve endeksinizdeki . Bununla birlikte, bu durumda, son taahhüdünüzde devlete geri dönmek istiyormuşsunuz gibi geliyor ve taahhüt edilmemiş değişiklikler yine de kayboldu.

Güncelleme: Amber'in cevabı hakkındaki yorumlarınızdan henüz herhangi bir taahhüt oluşturmadığınız anlaşılıyor (HEAD çözülemediğinden), bu yüzden yardımcı olmaz, korkarım.

Bu boruların nasıl çalıştığına gelince: git ls-files -zve git diff --name-only --diff-filter=D -zher ikisi de baytla ayrılmış dosya adlarının bir listesini çıkarır 0. (Bu, faydalıdır, çünkü yeni satırların aksine 0, Unix benzeri sistemlerde dosya adlarında baytların oluşmaması garanti edilir.) Program xargs, varsayılan olarak standart girdiden satırlar alıp sonuna ekleyerek komut satırlarını standart girdisinden oluşturur . komut satırı. -0Seçenek ile ayrılmış tarafından standart giriş beklemek diyor 0bayt. xargskomut satırının hiçbir zaman çok uzun olmamasını sağlayarak, standart girdideki tüm parametreleri kullanmak için komutu birkaç kez çağırabilir.

Basit bir örnek olarak, test.txtşu içeriğe sahip adlı bir dosyanız varsa :

hello
goodbye
hello again

... sonra komut şu komutu xargs echo whatever < test.txtçağırır:

echo whatever hello goodbye hello again

Ben herhangi bir taahhütte bulunmadım bu yüzden HEAD çözemez gibi diyecek. Bu gibi durumlarda ne yapıyoruz. Boruyu ayrıntılı olarak açıkladığınız için çok teşekkürler.
sarat

8
Git yok saymayı yeni değiştirdiyseniz ve git add --all dosyasını bir sürü dosya içerecek şekilde değiştirdiyseniz, git reset --hard'ı bunlardan çıkarmak için YAPMAYIN. SİLİNECEKLER !!
Ajoy

5
Uwaaahh !! Belki "dikkatlice" kelimesini vurgulamanız gerekir . Ben sadece bu üç kelime "git reset --hard" gördüm ve tüm unstaged dosyaları ... fufff !! gone !!!!!
Vineeth Chitteti

1

Tüm değişikliklerden vazgeçmek istiyorsanız aşağıdaki komutu kullanın,

git reset --soft HEAD

Değişiklikleri değiştirmeden çalışma dizininden geri döndürmek istediğinizde,

git reset --hard HEAD
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.