web-dev-qa-db-fra.com

Comment rechercher un fichier ou un répertoire dans les branches Git?

Dans Git, comment puis-je rechercher un fichier ou un répertoire par chemin d'accès sur plusieurs branches?

J'ai écrit quelque chose dans une branche, mais je ne me souviens plus lequel. Maintenant je dois le trouver.

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

297
Peeja

git log le trouvera pour vous:

% git log --all -- somefile

commit 55d2069a092e07c56a6b4d321509ba7620664c63
Author: Dustin Sallings <[email protected]>
Date:   Tue Dec 16 14:16:22 2008 -0800

    added somefile
% git branch -a --contains 55d2069
  otherbranch

Prend en charge globbing, aussi:

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

Les guillemets simples sont nécessaires (du moins si vous utilisez le shell bash) pour que le shell transmette le motif glob à git sans modification, au lieu de le développer (comme avec Unix find).

396
Dustin

git ls-tree pourrait aider. Pour rechercher 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 est que vous pouvez également rechercher des noms d'expressions avec des expressions régulières.

62
ididak

Bien que la réponse d'ididak soit plutôt cool et que Handyman5 fournisse un script pour l'utiliser, je l'ai trouvé un peu limité pour utiliser cette approche.

Parfois, vous devez rechercher quelque chose qui peut apparaître/disparaître avec le temps, alors pourquoi ne pas rechercher toutes les commits? En plus de cela, vous avez parfois besoin d'une réponse détaillée et d'autres fois, vous ne faites que 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 tu peux 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 cela en utilisant getopt vous pouvez modifier ce script pour alterner la recherche avec tous les commits, les références, les références/têtes, les commentaires, 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 implémentation possible.

17
albfan

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

9
Greg Hewgill

Copier et coller ceci pour utiliser git find-file SEARCHPATTERN

Imprimer 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 quelques scripts Shell minimaux directement à votre ~/.gitconfig comme alias de git global .

5
lumbric