Comment puis-je rechercher des branches Git pour un fichier ou un répertoire?

Dans Git, Comment puis-je rechercher un fichier ou un répertoire par chemin à travers un certain nombre de branches?

J'ai écrit quelque chose dans une branche, mais je ne me souviens pas lequel. Maintenant, j'ai besoin de le trouver.

Clarification : je cherche un fichier que j'ai créé sur une de mes branches. J'aimerais le trouver par chemin, et non par son contenu, car je ne me souviens pas de ce que sont les contenus.

261
demandé sur Belphegor 2008-12-16 23:02:03

6 réponses

Git log le trouvera pour vous:

% 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

Prend également en charge globbing:

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

Les guillemets simples sont nécessaires (au moins si vous utilisez le shell bash) afin que le shell passe le modèle glob à git inchangé, au lieu de l'étendre (tout comme avec Unix find).

342
répondu Dustin 2016-08-11 23:34:35

Git ls-tree pourrait aider. Pour effectuer une recherche dans toutes les branches existantes:

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

L'avantage de ceci est que vous pouvez également rechercher avec des expressions régulières pour le nom de fichier.

58
répondu ididak 2012-04-17 13:01:32

Bien que @ ididak réponse soit assez cool, et @Handyman5 fournit un script pour l'utiliser, j'ai trouvé peu restreint cette approche.

Parfois, vous devez rechercher quelque chose qui peut apparaître / disparaître au fil du temps, alors pourquoi ne pas rechercher tous les commits? En plus de cela, parfois vous avez besoin d'une réponse verbeuse, d'autres fois seulement valider des correspondances. Voici deux versions de ces options. Mettez ces scripts sur votre chemin:

Git-find-file

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-find-file-verbose

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

Maintenant, vous pouvez faire

$ 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

Voyez qu'en utilisant getopt Vous pouvez modifier ce script pour alterner la recherche de tous les commits, refs, refs / heads, été verbeux, etc.

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

Commander https://github.com/albfan/git-find-file pour une éventuelle mise en œuvre

16
répondu albfan 2017-05-23 12:18:20

Vous pouvez utiliser gitk --all et rechercher des commits "touchant les chemins" et le chemin qui vous intéresse.

9
répondu Greg Hewgill 2008-12-16 21:31:20

Copiez et collez ceci pour utiliser git find-file SEARCHPATTERN

Impression de toutes les branches recherchées:

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; :'

Imprimer uniquement les branches avec les résultats:

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; :'

Ces commandes ajouteront des scripts shell minimaux directement à votre ~/.gitconfig comme alias git global .

5
répondu lumbric 2016-05-13 14:33:04

Une implémentation assez décente de la commande find pour les dépôts git peut être trouvée ici: https://github.com/mirabilos/git-find

0
répondu Dominik George 2016-06-13 22:17:15