Silinmiş bir satırı nasıl “gider suçlayabilirim”?


506

git blamedeğiştirilen ve eklenen satırlar için mükemmeldir, ancak belirli bir önceki işlemde bulunan bir satırın sonunda silindiğini nasıl bulabilirim. Düşünüyorum bisect, ama daha kullanışlı bir şey umuyordum.

(Sormadan önce: bu durumda, sadece bir yaptım git log -pve kod satırını aradım ve (a) bazı aptal önceki taahhütte yaşamsal çizgiyi yeni silmişti ve (b) o salaktı.)


4
Bir var takip etmediğini açıkça bir cevap git log -S<string> /path/to/filebir istediği -cya -ccbirleştirme sırasında kaldırma göstermek için de (çakışma)
cfi

3
Olmalı -cve --cc. @Steen: Doğru, işaret ettiğiniz için teşekkürler! Aptal gözetim. Yorumunu düzenleyebilseydim. Yeni bir tane eklemek, sonra benimkini silmek, o zaman seninkini silmek çok zahmetli sanırım :)
cfi

4
Keşke git blamesilinen satırları (belki üstü çizili veya kırmızı metinle) silindikleri düzeltmeyle gösterme seçeneği olsaydı .
Craig McQueen

Bunu yazmak zor olur mu? Git dahili hakkında pek bir şey bilmiyorum.
Malvolio

Yanıtlar:


636

Hattın içeriğini biliyorsanız, bu aşağıdakiler için ideal bir kullanım durumudur:

git log -S <string> path/to/file

bu, o dizenin bir örneğini tanıtan veya silen taahhütleri gösterir. Orada da -G<regex>düzenli ifadeler ile yaptığı aynı şey! Ve seçeneklerine bakın man git-logve arayın veya daha fazla bilgi için kazma (bu özellikler için kolay ad).-G-S

Bu -Sseçenek aslında git-blamekılavuzun başlığında , açıklama bölümünde, örnek olarak verildiği yerde belirtilmiştir git log -S....


Brilliant ... sadece bu taşıma işinde ihtiyacım olan şey +1 üzerinde çalışıyorum
jkp

37
Git'i 1+ yıl boyunca kullandıktan sonra, Git'in neredeyse her türlü kullanım senaryosuna yönelik bir yerde her zaman bir komutu / seçeneği olduğunu görmek beni şaşırtıyor . Bunu paylaştığınız için teşekkürler, tam da şimdi ihtiyacım olan şey!
Pascal Bourque

22
Bu yöntem daha önce benim için çalıştı, ancak şimdi hattın silindiği taahhüdü bulamadığı bir dava gördüm. Söz konusu satırın birleştirme işleminde silindiği ortaya çıktı - bu başarısızlığı açıklar mı? ( git blame --reverseYöntem olsa da buldu.)
Haziran'da antinome

9
@antinome Birleştirme işlemindeki taahhütleri göstermek için, -cseçeneği ayrıca kullanın .
yunzen

2
Manpage üzerinde "-s" üzerinde bir ctrl + f yaptım ve hiçbir şey bulamadım. Sayfada nerede görüyorsun ?? Git 1.8.5.2 kullanıyorum
temporary_user_name

134

Bence gerçekten istediğin şey

git blame --reverse START..END filename

Gönderen man :

Geçmişi geriye doğru değil ileriye doğru yürütün. Bir çizginin göründüğü revizyonu göstermek yerine, bir çizginin var olduğu son revizyonu gösterir. Bu, suçlamanın yolunun START'ta bulunduğu START..END gibi bir dizi düzeltme gerektirir.

İle git blame reverse, çizginin göründüğü son taahhüdü bulabilirsiniz. Hala gelen taahhüdü almanız gerekir.

Tersine çevrilmiş bir git günlüğünü göstermek için aşağıdaki komutu kullanabilirsiniz. Gösterilen ilk işlem, bu satırın en son görüntülendiği tarih ve sonraki işlem, değiştirildiği veya kaldırıldığı tarih olacaktır.

git log --reverse --ancestry-path COMMIT^..master

14
Çizginin eksik olduğu dalda satırın eklendiği daldan birden fazla birleşme varsa (veya START'dan END'e kadar satırda birden çok yolun bulunduğu başka bir durum), git blame --reversekronolojik olarak birleştirme işleminden önceki düzeltmeyi gösterir son olarak, çizginin alınmaması kararının verildiği ilk birleşmeden önceki revizyon değil. Hattın en sonuncusundan ziyade var olduğu en eski revizyonu bulmanın bir yolu var mı?
rakslice

2
@ rakslice, bunun için suçu kullanabilirsiniz - geri - ilk-ebeveyn, biraz daha iyidir.
max630

17

Cascabel'in cevabını tamamlamak için :

git log --full-history -S <string> path/to/file

Burada bahsettiğim sorunun aynısı vardı, ancak hattın eksik olduğu ortaya çıktı, çünkü bir şubeden birleştirme taahhüdü geri döndü ve daha sonra tekrar birleştirildi ve söz konusu hattı etkili bir şekilde kaldırdı. --full-historyBayrak önler, bu hareketin atlama.


9

git blame --reverse sizi satırın silindiği yere yaklaştırabilir . Ama aslında değil çizgi silinir revizyon etmektedir. Bu işaret geçen çizgi oldu revizyon mevcut . Sonra aşağıdaki revizyon basit bir taahhüt ise, şanslısınız ve silme revizyonunu aldınız. OTOH, eğer aşağıdaki revizyon birleştirme taahhüdü ise , işler biraz çılgına dönebilir.

Yaygınlık yaratma çabasının bir parçası olarak, bu çok problemi ele aldım, böylece kutunuza zaten Python yüklediyseniz ve denemeye hazırsanız , daha fazla beklemeyin ve nasıl gittiğini bana bildirin.

https://github.com/eantoranz/difflame


0

Birleştirme işlemlerinde gizlenen değişiklikler için

Birleştirme işlemlerinin değişiklikleri Git günlük çıktısından otomatik olarak gizlenir. Hem kazma hem de ters suçlama değişikliği bulamadı. Böylece istediğim çizgi eklendi ve daha sonra kaldırıldı ve onu kaldıran birleştirmeyi bulmak istedim. Dosya git log -p -- path/filegeçmişi yalnızca eklendiğini gösterdi. İşte onu bulmanın en iyi yolu:

git log -p -U9999 -- path/file

Değişikliği arayın, ardından "^ commit" için geriye doğru arama yapın - ilk "^ commit", dosyanın en son bu satıra sahip olduğu işlemdir. İkinci "^ taahhüt" kaybolduktan sonradır. İkinci taahhüt, onu kaldıran komisyon olabilir. Bunun -U9999anlamı, dosyalarınızın en fazla 9999 satır olduğu varsayılarak (dosyanın her değiştirilmesinden sonra) dosya içeriğinin tamamını göstermek içindir.

Kaba kuvvet yoluyla ilgili birleşmeleri bulur (ton başına verilen taahhütlere karşı çalışan ilk ebeveyni ile olası her birleştirme taahhüdünü ayırır)

git log --merges --pretty=format:"git diff %h^...%h | grep target_text" HEAD ^$(git merge-base A B) | sh -v 2>&1 | less

(Revizyon filtresini daha fazla kısıtlamaya çalıştım, ancak sorunla karşılaştım ve bunu önermiyorum. Aradığım ekleme / kaldırma değişiklikleri, farklı zamanlarda birleştirilen farklı dallardaydı ve A ... B içermiyordu değişiklikler aslında ana hatta birleştirildiğinde.)

Bu iki işlemle Git ağacını göster (ve karmaşık Git geçmişinin birçoğu kaldırıldı):

git log --graph --oneline A B ^$(git merge-base A B) (A yukarıdaki ilk taahhüttür, B yukarıdaki ikinci taahhüttür)

A tarihini ve B eksi geçmişini A ve B tarihini göster.

Alternatif sürüm (yolu normal Git geçmiş ağacından ziyade daha doğrusal gösteriyor gibi görünüyor - ancak normal git geçmişi ağacını tercih ediyorum):

git log --graph --oneline A...B

Üç değil, iki nokta - üç nokta, "r1 r2 - not $ (git merge-base --all r1 r2) anlamına gelir. R1 (sol taraf) veya r2 (sağ) ancak her ikisinden de değil. " - kaynak: "man gitrevisions"

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.