Proje taahhüt geçmişinde silinmiş bir dosyayı nasıl bulabilirim?


1274

Bir zamanlar projemde şimdi almak istediğim bir dosya vardı.

Sorun şu: Ne zaman sildiğime ve hangi yolda olduğuna dair hiçbir fikrim yok.

Varsa bu dosyanın taahhütlerini nasıl bulabilirim?




13
Buradaki cevaplar benim için kopyalardaki cevaplardan daha yararlı .
Felipe Alvarez

5
kabul etti ... kopyaları ne olursa olsun ... onlar Google arama gelmedi .... bu yaptı ... Umarım yinelenenleri kovalayan zaman israf durur ... sadece zaman ve google algoritması olacak hangi sorunun en iyi olduğunu söyle.
Tim Boland

Yanıtlar:


1599

Kullanabileceğiniz yolu tam olarak bilmiyorsanız

git log --all --full-history -- "**/thefile.*"

Dosyanın yolunu biliyorsanız, bunu yapabilirsiniz:

git log --all --full-history -- <path-to-file>

Bu, tüm dosyalarda söz konusu dosyaya dokunan taahhütlerin bir listesini göstermelidir. Ardından, istediğiniz dosyanın sürümünü bulabilir ve ...

git show <SHA> -- <path-to-file>

Veya aşağıdakilerle çalışma kopyanıza geri yükleyin:

git checkout <SHA>^ -- <path-to-file>

Tespit edilen dosyadan önce kasayı alan düzeltme işareti sembolüne ( ^) dikkat edin, çünkü işlem sırasında dosya silinir, silinen dosyanın içeriğini almak için önceki işleme bakmamız gerekir.<SHA>


2
Mutlak bir yol yerine göreli bir yol kullanmayı deneyin (henüz yapmadıysanız).
Amber

63
Tam yolu bilmiyorsanız ne olur? Tek bildiğiniz dosya adı mı?
Priestc

17
@PedroMorteRolo git log -- <path>, dosyanın hiç var olmadığı bir dalda olduğunuzda çıktı almayacaktır. git log --all -- <path>Diğer dallarda meydana gelen değişiklikleri kaçırmadığınızdan emin olmak için her zaman kullanmalısınız . git log -- <path>Birden fazla şubeniz varsa ve yolları ve dalları (benim gibi) unutma eğilimindeyseniz komut çok tehlikeli olabilir ve diğer geliştiricilerle çalışıyorsanız da tehlikelidir.
ocaklar

4
@Aber, yanıtınıza --all(teşekkürler Philip ) eklemeyi düşünün git log, böylece insanlar diğer dallardaki değişiklikleri ve dosyaları kaçırmazlar. Benim gibi unutkan insanları çok kederden kurtaracaktı.
ocaklar

3
Aşağıdaki cevapta belirtildiği gibi, dosyanın geri yüklenmesi git checkout <SHA>^ -- <path-to-file>(^ sembolüne dikkat edin) olmalıdır, çünkü <SHA> işleminin yapıldığı anda dosya silinir, silinen dosyanın içeriğini almak için önceki işleme bakmamız gerekir
kipelovets

393

Silinen dosyaların bir listesini alın ve silinen dosyanın tam yolunu kopyalayın

git log --diff-filter=D --summary | grep delete

Bu işlemin kesin kimliğini bulmak için sonraki komutu yürütün ve kesin kimliğini kopyalayın

git log --all -- FILEPATH

Silinen dosyanın farkını göster

git show COMMIT_ID -- FILE_PATH

Unutmayın, >gibi bir dosyaya çıktı yazabilirsiniz

git show COMMIT_ID -- FILE_PATH > deleted.diff

1
Ben ilk adım yardımıyla yolunu bulmasına rağmen, ikinci aşama bu hatayı atar: unknown revision or path not in the working tree.
jvannistelrooy

6
Silme işlemleriyle birlikte karma karmaları görmek için şunları yapabilirsinizgit log --diff-filter=D --summary | grep -E 'delete|^commit\s+\S+'
Chris Middleton

1
Adım 2 hiçbir şey döndürmez. Neden olabileceğine dair bir fikrin var mı? Dosya adım doğru.
Denis Kniazhev

2
git-grep-latest(){ result_path=$(git log --diff-filter=D --summary | grep $1 | head -1 | awk '{print $4;}'); latest_commit=$(git log --all -- $result_path | head -1 | awk '{print $2;}'); git show $latest_commit -- $result_path; }git-grep-latest some_text
Üçünü

1
@TylerJones boru kullanarak linux ile her şeye her şeyi besleyebilirsiniz - google linux pipes.. hoşuna gidecek .
John Hunt

37

Kabul edilen yanıt düzenlenemedi, bu yüzden buraya yanıt olarak ekledi,

dosyayı git'e geri yüklemek için aşağıdakileri kullanın (SHA'dan hemen sonra '^' işaretini not edin)

git checkout <SHA>^ -- /path/to/file

^ Neden istediğini anlamıyorum. Dosya şu SHA ile olan bağlılık içinde ... neden oradan başka bir taahhütte bulunmak istiyorsun?
Tony K.

19
Bu sha ile "silinmiş" olarak taahhütte bulunuyor, yani hala var olmayacak. Aslında geri almak için bundan önce taahhütte bulunmalısınız.
tandrewnichols

6
@tandrewnichols Bu sadece yanlış taahhüt SHA kullandığınız anlamına gelir - istediğiniz dosyanın sürümü için taahhüt istiyorsanız ... muhtemelen dosyanın silinmediği sürüm değildir.
Amber

6
@Amber ve istediğiniz taahhüt silinmeden önceki en son olasılıktır, dolayısıyla bu cevaptır.
Sam Holder

1
@AlexR: <SHA>~1alıntı işaretleri ile sarmaya gerek kalmadan aynı şekilde çalışmalıdır.
CodeManX

37

Diyelim ki adlı bir dosyayı kurtarmak istiyorsunuz MyFile, ancak yolundan (veya bunun için uzantısından) emin değilsiniz :

Prelim .: git köküne atlayarak karışıklıktan kaçının

Önemsiz bir proje, benzer veya özdeş isimlere sahip birden fazla dizine sahip olabilir.

> cd <project-root>
  1. Tam yolu bulun

    git log --diff-filter = D - özet | grep sil | grep Dosyam

    delete mode 100644 full/path/to/MyFile.js

full/path/to/MyFile.js aradığınız yol ve dosyadır.

  1. Bu dosyayı etkileyen tüm taahhütleri belirleyin

    git log --oneline --follow - full / path / to / MyFile.js

    bd8374c Some helpful commit message

    ba8d20e Another prior commit message affecting that file

    cfea812 The first message for a commit in which that file appeared.

  2. Dosyayı teslim alma

İlk listelenen taahhüdü (son kronolojik olarak burada bd8374c) seçerseniz, dosya bu taahhütte silindiğinden bulunmaz.

> git checkout bd8374c -- full/path/to/MyFile.js

`error: pathspec 'full/path/to/MyFile.js' did not match any file(s) known to git.`

Sadece önceki (bir düzeltme işareti ekleyin) taahhüdünü seçin:

> git checkout bd8374c^ -- full/path/to/MyFile.js

3
Bu kabul edilen cevaptan çok daha açık
Pouyan Khodabakhsh

Windows konsolu (cmd) için, adım 2'deki grep yerine find komutunu kullanın: git log --diff-filter=D --summary | find "delete" | find "MyFile"Ve git checkout "bd8374c^" -- full/path/to/MyFile.js
adım3

30

@Amber doğru cevabı verdi! Sadece bir ek daha, dosyanın tam yolunu bilmiyorsanız joker karakterler kullanabilirsiniz! Bu benim için çalıştı.

git log --all -- **/thefile.*

4
@YaseminYasemin Mevcut bir cevabı en çok oy alan cevaplara kopyalama konusunda nasıl hissettiğimi bilmiyorum: / Bu cevap kendi başına da faydalıydı; bir oy yeterli olabilir mi?
Clément

1
Proje kökünde ise bu dosyayı bulamaz (Cygwin'de test edilmiştir).
wortwart

19

Aşağıda, bir dev veya git kullanıcısının depo kök dizininden silinmiş bir dosya adını geçirebileceği ve geçmişi alabileceği basit bir komut vardır:

git log --diff-filter=D --summary | grep filename | awk '{print $4; exit}' | xargs git log --all -- 

Herhangi biri, komutu geliştirebilirse, lütfen yapın.


1
Harika, teşekkürler! Görünüşe göre benim dosya hiç yoktu, ama bu ayrı ve çok kıllı bir sorun…

dosyanız 'eksik' gibi görünüyorsa bunu depo kök dizininden çalıştırdığınızdan emin olun
samaspin

Teşekkürler @samaspin cevabı güncelledi.
Jason

18

gitkAnımsanan yarım dosyayı bulmak için geçmişe göz atabilmek için görüntüleyenlerden birini kullanmayı deneyin . ( gitk --allgerekirse tüm şubeler için kullanın )


4
Bu --allseçenek hem cevabınız hem de kabul edilen cevabınız için önemlidir.
ocaklar

3
Geçmişte gezinmek çoğu proje için olağanüstü zaman alacaktır.
mikemaccana

5

Özet:

  1. Aşama 1

Silinen dosyaların geçmişinde dosya tam yolunda arama yaparsınız git log --diff-filter=D --summary | grep filename

  1. Adım 2

Dosyanızı silinmeden önce işlemden geri yüklersiniz

restore () {
  filepath="$@"
  last_commit=$(git log --all --full-history -- $filepath | grep commit | head -1 | awk '{print $2; exit}')
  echo "Restoring file from commit before $last_commit"
  git checkout $last_commit^ -- $filepath
}

restore my/file_path

0

İşte benim çözümüm:

git log --all --full-history --oneline -- <RELATIVE_FILE_PATH>
git checkout <COMMIT_SHA>^ -- <RELATIVE_FILE_PATH>
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.