Comment puis-je afficher tous les dépôts git sur ma machine?

121

Existe-t-il un moyen de voir tous les référentiels git qui existent sur ma machine? Une commande pour ça?

n1kh1lp
la source
2
Voir git-summary . C'est un script bash qui répertorie à la fois tous les référentiels et renvoie leurs informations d'état. Avis de non-responsabilité, je suis l'un des développeurs.
cagliari2005
@ cagliari2005: Qu'en est-il des dépôts nus? stackoverflow.com/questions/60064170/…
Luciano

Réponses:

102

Si vous êtes sous Linux find / -name ".git", sinon il n'y a aucun moyen, ce sont des répertoires standard, utilisez simplement votre programme de recherche de fichiers / dossiers OS pour trouver les .gitdossiers nommés.

Arkaitz Jimenez
la source
1
Sur Windows (et je suis sûr que Mac aussi), vous pouvez faire quelque chose de similaire ... juste une recherche de répertoires nommés .git - qui est ce que git utilise pour stocker ses méta-informations.
cjstehno
3
Sur Mac, la commande ci-dessus fonctionne également. (Sauf si vous utilisez OS9 ou une version antérieure!)
Alex Feinman
1
Des bons scripts shell ou de petites applications utilitaires qui implémentent cette fonctionnalité de recherche de fichiers simple et ajoutent des informations sur l'état du référentiel à la liste? Ne devrait pas être un problème pour écrire un script shell pour le faire, mais plutôt utiliser des scripts bien adoptés que mes propres hacks non optimisés.
jmlane
6
@jmlanefor d in `find / -name ".git"`; do cd $d/..; echo `pwd`:; git status; echo; done
LJ VanKuiken
La page de manuel find a une solution. Similaire à la réponse acceptée mais en utilisant -prune pour revenir plus rapidement sans aller dans les répertoires .git. Sans élagage, la recherche irait dans le dossier .git et, selon le contenu, passerait du temps à chercher à l'intérieur inutilement. La solution de la page de manuel suit "find repo / (-exec test -d '{}' /. Svn \; -or \ -exec test -d {} /. Git \; -or -exec test -d {} / CVS \ ;) \ -print -prune Check it out. Modifiez svn et cvs si ce n'est pas obligatoire
quiet_penguin
38

RÉPONSE ORIGINALE : Cela fonctionne plutôt bien à partir de Windows Powershell:

Get-ChildItem . -Attributes Directory+Hidden -ErrorAction SilentlyContinue -Include ".git" -Recurse

EDIT # 1 : -Le filtre est deux fois plus rapide que -Include. Voici cette solution:

Get-ChildItem . -Attributes Directory+Hidden -ErrorAction SilentlyContinue -Filter ".git" -Recurse

EDIT # 2 : Keith E. Truesdell a mentionné l'envoi de la sortie vers un fichier. Voir son commentaire pour cette solution. Je préfère la sortie de la console. Mais son commentaire m'a fait penser que je préfère juste le chemin complet, pas tout le désordre qui est retourné par défaut. Si vous ne voulez que le chemin complet, utilisez ce qui suit:

Get-ChildItem . -Attributes Directory+Hidden -ErrorAction SilentlyContinue -Filter ".git" -Recurse | % { Write-Host $_.FullName }

NOTE FINALE : Les solutions ci-dessus ne renvoient que les référentiels Git sous le répertoire courant . Si vous voulez TOUS les référentiels sur un lecteur, vous devez exécuter la commande une fois à partir de la racine de chaque lecteur.

bopapa_1979
la source
1
très utile pour les utilisateurs de Windows! :)
Felix Feliciant
2
Get-ChildItem: Impossible de trouver un paramètre correspondant au nom de paramètre «Attributes». À la ligne: 1 car: 28
Dewald Swanepoel
@DewaldSwanepoel - Je n'ai aucune idée de la raison pour laquelle vous verriez cette erreur concernant le paramètre Attributes. C'est clairement dans la documentation, et je l'ai essayé maintenant sur plusieurs combinaisons de versions Windows / PowerShell. Windows 7, 8 et 10 fonctionnent tous avec différentes versions de PowerShell pour moi. Si vous découvrez pourquoi l'erreur se produit, veuillez la partager ici afin que nous puissions savoir:>)
bopapa_1979
2
@DewaldSwanepoel - Vous pouvez DEFINITIVEMENT mettre à niveau votre version de PowerShell. Nous le faisons avec du chocolat. J'utilise actuellement PowerShell version 5.0 sur Windows 7 au travail.
bopapa_1979
1
@ KeithE.Truesdell - Je suis presque sûr que les attributs "Répertoire + Caché" sont inclusifs et ne rechercheront que les répertoires. L'ajout de -Directory peut être plus rapide dans les versions plus récentes de PowerShell. Je vais chronométrer. EDIT - L'ajout du "-Directory" ne fait aucune différence importante, comme l'indique la documentation. Cependant, l'ajout de l'attribut d'annuaire comme vous le suggérez le ralentit. Je sais maintenant pourquoi, mais je l'ai testé dans les deux sens avec Measure-Command et les trois avec l'attribut Directory supplémentaire étaient plus lents que les trois sans.
bopapa_1979
18

Sur * nix, cela trouvera également tous les --baredépôts.

find / -name "*.git" -type d
gahooa
la source
3
Les référentiels nus n'ont pas besoin d'être nommés, name.gitc'est juste une convention, que je ne suis pas par exemple.
Arkaitz Jimenez
3
Étant donné que les dépôts nus n'ont pas besoin de suivre cette convention de dénomination, existe-t-il un moyen universel de findces dépôts?
jmlane
11

Dépôts Git ont tous HEAD, refset les objectsentrées.

sur GNU / n'importe quoi,

find -name HEAD -execdir test -e refs -a -e objects \; -printf %h\\n

La .gitsimple vérification manquera de nombreux dépôts et sous-modules nus.

Pour devenir complètement paranoïaque sur la vérification, vous pouvez demander à git de faire toutes ses propres vérifications avant d'imprimer,

find -name HEAD -execdir test -e refs -a -e objects \; \
      -execdir sh -ec 'GIT_DIR=$PWD git rev-parse --absolute-git-dir 2>&-' \;

(modifier: je pensais que le .git/configfichier était nécessaire, il s'avère que ce n'est pas le cas, donc le minimum absolu git init newrepoest

mkdir -p newrepo/.git/{objects,refs}
echo ref: refs/heads/master >newrepo/.git/HEAD

)

jthill
la source
4

Sous Linux, un moyen plus rapide serait:

locate -r "\.git$"

en supposant que vous mainteniez la base de données de Locate à jour avec sudo updatedb

Ernesto
la source
Décidément, localiser est plus rapide, utilisez-le avec précaution, voir ici: unix.stackexchange.com/questions/60205/…
AjayKumarBasuthkar
3

Sous Linux et OS X, la commande suivante est probablement la plus rapide (en ignorant les référentiels sans .git) lorsque le répertoire racine de findest /:

find / -name .git -exec dirname {} \; -prune

Mais pour les racines qui ont principalement des référentiels en dessous, ce qui suit est probablement le plus rapide (vous voudrez peut-être remplacer /par .ou une autre racine):

find / -type d -exec test -d {}/.git \; -prune -print

Explication rapide des primaires de findutilisé (puisqu'aucun opérateur n'est présent ici, -andest implicite, c'est-à-dire que pour chaque nœud visité, les primaires sont évaluées de gauche à droite jusqu'à ce que l'un d'eux soit évalué false):

  • -nameest truesi le nom correspond (souvent, mais pas ici, avec des caractères génériques)
  • -execexécute une commande terminée par ;(qui est échappée par \pour éviter l'interprétation par le shell), et est truesi l'état de retour est 0(c'est-à-dire, OK). Le nœud actuel est disponible en tant que {}(qui ne nécessite aucun échappement)
  • -pruneest toujours true, et fait sauter tous les nœuds enfants
  • -type dest truepour les répertoires
  • -printest nécessaire ici car si -execest présent, il n'est pas implicitement ajouté
Walter Tross
la source
2

Sous Linux, essayez cette commande avec l'autorisation root:

find / | grep \\.git$

cela recherche simplement tous les fichiers qui se terminent par .git ... vous pouvez le faire avec des outils de recherche sous Windows, Linux, etc.

Michel Gokan
la source
7
Il ne sert à rien de findtout laisser sortir puis de filtrer avec grep. Je préférerais utiliser--name "*.git"
Gregory Pakosz
2
@Gregory Pakosz: Quelle est la différence?
Michel Gokan
11
@Michel, vous démarrez 2 processus et faites en sorte que le premier transmette par un tube tout l' /arbre pour le second à grep, quand le premier peut tout faire et éviter l'énorme utilisation inutile des IO. Pas une vraie différence pour l'utilisateur normalement, mais pour les gros systèmes de fichiers, cela peut faire une différence.
Arkaitz Jimenez
2
de toute façon, si vous voulez utiliser la commande JUST find, il est préférable d'utiliser -regex au lieu de -name ... dans ce cas, utilisez cette commande: sudo find / -regex '. * \. git'
Michel Gokan
4
@MichelKogan mieux pourquoi?
Mark Amery
2

Une version simple de PowerShell:

Get-ChildItem . -Recurse -Hidden .git
Julien Brdy
la source
1
Cela a fonctionné pour moi! Je vous remercie! J'ai eu des erreurs pour quelques emplacements auxquels il a essayé d'accéder à ce fonctionnement en tant qu'utilisateur normal auquel le script PowerShell n'avait pas accès, mais après un examen plus approfondi, ce sont des endroits dont je ne devrais pas m'inquiéter de toute façon (c'est-à-dire - C:\users\<username>\PrintHood Aussi, je a trouvé utile d'ajouter une sortie à un fichier et puisque je ne me souciais que du chemin (car ce script obtient un tas d'informations) de filtrer également uniquement les informations de chemin / répertoire. Get-ChildItem . -Recurse -Hidden .git | Out-file -FilePath C:\Dev\GitRepoList.txt
Keith E. Truesdell
1

Pour Linux:

dir="/home/${USER}"
dir_not="${dir}/miniconda3"
find /home/aeug -type d -iname ".git" -o -path "${dir_not}" -prune | xargs -0 echo 
En loi
la source
1

Petite variation par rapport à la réponse d'Eric Burcham. Cette réponse ajoute \ .git à la fin, celle-ci non.

Get-ChildItem . -Attributes Directory+Hidden -ErrorAction SilentlyContinue -Filter ".git" -Recurse | % { Write-Host $_.Parent.FullName }

J'utilise cette commande en début de journée. Il ajoute simplement quelques commandes git à ce qui précède. Pour une raison quelconque, notre dépôt git fonctionne mieux si l'on exécute une extraction puis une extraction, je ne sais pas pourquoi. Et nous avons beaucoup de sous-modules pour une raison quelconque. Quoi qu'il en soit, mettez ce dont vous avez besoin entre les {}.

push-location; Get-ChildItem . -Attributes Directory+Hidden -ErrorAction SilentlyContinue -Filter ".git" -Recurse | % { cd $_.parent.fullname; write-host '*************'; $(get-location).path; git fetch; git pull; git checkout .; git clean -f; git submodule update; git status; write-host '*************'; write-host ' '; }; pop-location
Afficher un nom
la source