Git dallarında bir dosyayı veya dizini nasıl arayabilirim?


323

Git'te, birkaç dalda bir dosyayı veya dizini yoldan nasıl arayabilirim?

Bir şubeye bir şey yazdım ama hangisini hatırlamıyorum. Şimdi bulmam gerek.

Açıklama : Şubelerimden birinde oluşturduğum bir dosya arıyorum. İçeriğin ne olduğunu hatırlamadığım için onu içeriğine göre değil, yoluna göre bulmak istiyorum.


Soru hakkında net değilim. Bu dosya şimdi silinmiş bir şubede miydi? Dosya silindi mi?
Abizern

Yanıtlar:


444

git log+ git branchsizin için bulacaktır:

% git log --all -- somefile

commit 55d2069a092e07c56a6b4d321509ba7620664c63
Author: Dustin Sallings <dustin@spy.net>
Date:   Tue Dec 16 14:16:22 2008 -0800

    added somefile


% git branch -a --contains 55d2069
  otherbranch

Globbing'i de destekler:

% git log --all -- '**/my_file.png'

Tek tırnaklar gereklidir (en azından Bash kabuğu kullanılıyorsa), kabuk, glob desenini genişletmek yerine değişmeden gitmeye geçirir (tıpkı Unix gibi find).


2
Bu, tam yolu biliyorsanız, somefileörneğin yol / dosya adı üzerinde regex aramasına ihtiyacınız varsa, ididak'ın yanıtını kullanabilirsiniz.
ShreevatsaR

70
git log --all -- **/my_file.png
Globbing'i

3
Bunu biraz farklı bir problem için kullandım. Belirli bir şubeye taahhüt ettiğim tüm * .sql dosyalarını bulmaya çalışıyordum. Ben de kullandım git log --grep='branch' --author='me' -- *.sql. Bir cazibe gibi çalıştı. git sürüm 1.7.11.1
thepriebe

1
Not gitkdestekler de globbing. Bu mükemmel bir cevap @ webmat! Nerede silindiğini / yaratıldığını / vb. Görmek istiyorsanız git log --all --stat -- **/my_file.png, bu şekilde kullanabilirsiniz , böylece onu silen bir taahhütten kontrol edip etmediğinizi tahmin etmeniz gerekmez.
eacousineau

1
@webmat: Cevaba globbing ile ilgili bilgilerinizi ekleme özgürlüğünü aldım. Bahsettiğiniz için teşekkürler!
sleske

65

git ls-tree yardımcı olabilir. Mevcut tüm şubelerde arama yapmak için:

for branch in `git for-each-ref --format="%(refname)" refs/heads`; do
  echo $branch :; git ls-tree -r --name-only $branch | grep '<foo>'
done

Bunun avantajı, dosya adı için normal ifadelerle de arama yapabilmenizdir.


3
Umarım faydalı birkaç yorum: (a) Muhtemelen "git ls-tree" dosyasına "-r" eklemek istersiniz, böylece dosyayı bir alt dizinde olsa bile bulabilir. (b) Belki de ilk satıra daha temiz bir alternatif, "git for-each ref" kullanmaktır, örneğin "dal için git for-each-ref --format="%(refname)" refs/heads; do" (c) "git ls-tree - only name" çıktıyı daha düzenli hale getirir (d) Cevabınızda, Dustin'in çözümü üzerinde bunun bir avantajı olduğunu, yani dosya
adını

9
Ben "gitfind.sh <regex>" çalıştırabilmeniz için bunu bir komut dosyasına tamamladım; gist
Handyman5

3
Bunun yalnızca yerel şubelerde arama yapacağını unutmayın . Uzaktan izleme kollarını aramak için refs/remotesyerine kullanın refs/heads. Her şeyi (yerel şubeler, uzaktan izleme şubeleri ve etiketler) aramak için kullanın refs/.
sleske

19

İdidak'ın tepkisi oldukça havalı olmasına rağmen ve Handyman5 bunu kullanmak için bir senaryo sağlasa da, bu yaklaşımı kullanmak için biraz kısıtlı buldum.

Bazen zaman içinde görünebilecek / kaybolabilecek bir şey aramanız gerekir, o zaman neden tüm taahhütlere karşı arama yapmıyorsunuz? Bunun yanı sıra, bazen ayrıntılı bir yanıta ihtiyacınız olur ve diğer zamanlarda sadece eşleşme yaparsınız. İşte bu seçeneklerin iki sürümü. Bu komut dosyalarını yolunuza koyun:

Git-Bul-dosya

for branch in $(git rev-list --all)
do
  if (git ls-tree -r --name-only $branch | grep --quiet "$1")
  then
     echo $branch
  fi
done

Git-Bul-dosya-ayrıntılı

for branch in $(git rev-list --all)
do
  git ls-tree -r --name-only $branch | grep "$1" | sed 's/^/'$branch': /'
done

Şimdi yapabilirsin

$ git find-file <regex>
sha1
sha2

$ git find-file-verbose <regex>
sha1: path/to/<regex>/searched
sha1: path/to/another/<regex>/in/same/sha
sha2: path/to/other/<regex>/in/other/sha

Getopt kullanarak , tüm komutları, başvuruları, referansları / kafaları, ayrıntılı olanları vb.

$ git find-file <regex>
$ git find-file --verbose <regex>
$ git find-file --verbose --decorated --color <regex>

Ödeme https://github.com/albfan/git-find-file olası bir uygulama için.


Şunu mu demek istediniz: "git-find-file <regex>"? Çalıştırdım, teşekkürler!
Elijah Lynn

1
Şahsen $ (git rev-list --all) yerine $ (git branch | cut -c 3-) kullanmak çok daha yararlı buluyorum. Bir sürü taahhüt bulmuyorum, adlandırılmış dalları önemsiyorum.
Campadrenalin

Ayrıca tüm komutlar üzerinde döngü çok yavaş olduğundan $ (git branch | cut -c 3-) kullanmak için komut dosyalarını değiştirdim.
i4h

Ben bir şey yaratmaya değer şey için tüm yaygara gördüm. github.com/albfan/git-find-file . Bazı sorunları açıyorum, daha fazla teklifte bulunmaktan veya bunun için PR göndermekten çekinmeyin.
albfan

1
@lumbric yol üzerindeki komut dosyasını kurduktan sonra çalışır, onun bir git özelliği
albfan

10

gitk --allİlgilendiğiniz "dokunma yollarını" ve yol adını kullanabilir ve arayabilirsiniz.


3
Belirtildiği gibi gitk --all öğesini, ardından View | Yeni görünüm, Tüm Dalları etkinleştir. Ardından, sondan bir önceki alanda arama kriterlerinizi ayarlayın: dosya adları (joker kartlarla). Sonunda: Tamam.
MikeW

8

Kullanmak için kopyalayıp yapıştırın git find-file SEARCHPATTERN

Aranan tüm şubeleri yazdırma:

git config --global alias.find-file '!for branch in `git for-each-ref --format="%(refname)" refs/heads`; do echo "${branch}:"; git ls-tree -r --name-only $branch | nl -bn -w3 | grep "$1"; done; :'

Yalnızca sonuçları olan dalları yazdırın:

git config --global alias.find-file '!for branch in $(git for-each-ref --format="%(refname)" refs/heads); do if git ls-tree -r --name-only $branch | grep "$1" > /dev/null; then  echo "${branch}:"; git ls-tree -r --name-only $branch | nl -bn -w3 | grep "$1"; fi; done; :'

Bu komutlar doğrudan bazı asgari kabuk komut katacak ~/.gitconfigşekilde küresel git takma .


sadece ana dalda arama yapıyor
Nasif Imtiaz Ohi

Tüm yerel şubelerde arama yapar
Leonardo Herrera

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.