El enfoque ingenuo es find dir1 dir2 dir3 -type d -name .git | xargs -I {} dirname {}
, pero es demasiado lento para mí, porque tengo muchas estructuras de carpetas profundas dentro de los repositorios de git (al menos creo que esta es la razón). He leído sobre eso que puedo usar prunepara evitar que el hallazgo vuelva a aparecer en los directorios una vez que encuentra algo, pero hay dos cosas. No estoy seguro de cómo funciona esto (quiero decir, no entiendo qué prunehace aunque haya leído la página de manual) y el segundo no funcionaría en mi caso, porque evitaría que se repita finden la .gitcarpeta pero no en todos otras carpetas
Entonces, lo que realmente necesito es:
para todos los subdirectorios, verifique si contienen una .gitcarpeta y si es así, deje de buscar en esta rama del sistema de archivos e informe el resultado. Sería perfecto si esto también excluyera cualquier directorio oculto de la búsqueda.

getpof .gites lo que uso github.com/thrig/scripts/blob/master/filesys/getpof.cRespuestas:
De acuerdo, todavía no estoy totalmente seguro de cómo funciona esto, pero lo he probado y funciona.
Tengo muchas ganas de hacer lo mismo más rápido.
fuente
-pruneesta manera: comienza en la raíz de un árbol, lo mueve hacia abajo y cuando se aplica una determinada condición, corta un subárbol completo (como una "poda" real), por lo que no verá más nodos en este subárbol .-type dpara qué condicióntest -e ...es verdadera y si es así, ejecutamos acciones, lo-print -pruneque significa imprimirlo y cortar el subárbol, ¿verdad?find . -type d -exec test -e '{}/.git' \; -print -prune | parallel cd "{}" \&\& git pull --rebaseGNUparalleles un reemplazo muy útil paraxargsSolución posible
Para GNU
findy otras implementaciones que admiten-execdir:(ver los comentarios)
Cosas discutidas previamente
Solución si la poda a continuación
.gites suficienteSi
-printf '%h'es compatible (como en el caso de GNU'sfind) no necesitamosdirname:Una vez que se encuentre con una carpeta
.giten la ruta actual, la generará y luego dejará de mirar hacia abajo en el subárbol.Solución si todo el árbol de carpetas se debe podar una vez que
.gitse encuentraUsando
-quitsi tu lofindadmite:(De acuerdo con esta publicación detallada de Stéphane Chazelas,
-quitse admite en GNU y FreeBSDfindy en NetBSD como-exit).De nuevo con
-printf '%h'si es compatible:Solución para podar al mismo nivel que donde está la
.gitcarpetaConsulte la parte "Posible solución" para ver la solución actual para este problema en particular.
(Ah, y obviamente las soluciones que usan
xargsasumen que no hay líneas nuevas en los caminos, de lo contrario, necesitarías magia de byte nulo).fuente
dir1contiene dos directoriosdirxydirycada uno contiene un.gitdirectorio, esto solo informadirx/.gitdir1/.gitexiste, aún desciendedir1/dirx, lo que, según mi lectura de los requisitos de OP, no es deseableIdealmente, desearía rastrear árboles de directorios en busca de directorios que contengan una
.gitentrada y dejar de buscar más abajo (suponiendo que no tenga más git repos dentro de git repos).El problema es que con el estándar
find, hacer este tipo de verificación (que un directorio contiene una.gitentrada) implica generar un proceso que ejecute unatestutilidad utilizando el-execpredicado, que será menos eficiente que enumerar el contenido de algunos directorios.Una excepción sería si usa la
findconstrucción delboshshell (un tenedor POSIXified del shell Bourne desarrollado por @schily ) que tiene un-callpredicado para evaluar el código en el shell sin tener que generar un nuevo intérprete sh:O use
perl'sFile::Find:Más largo, pero más rápido que
zsh'sprintf '%s\n' **/.git(:h)(que desciende a todos los directorios no ocultos), o GNUfind' sfind . -name '.?*' -prune -o -type d -exec test -e '{}/.git' \; -prune -printque ejecuta untestcomando en un nuevo proceso para cada directorio no oculto.fuente
.gitpuede ser un archivo, así - a través degit worktree-ds a-e.Si usa localizar, puede encontrar directorios con:
La lista de resultados es rápida y el procesamiento posterior también es fácil.
fuente
locate '*/.git'debería ser suficiente.Utilizar
timeesto, para ver la diferencia con y sin-prune.Esto se basa en una solución en el
man find. Puede editar elCVSysvnsi no es necesario. sigue el contenido de la página manDado el siguiente directorio de proyectos y sus directorios administrativos SCM asociados, realice una búsqueda eficiente de las raíces de los proyectos:
En este ejemplo,
-pruneevita el descenso innecesario a directorios que ya han sido descubiertos (por ejemplo, no buscamosproject3/srcporque ya lo encontramosproject3/.svn), pero asegura que se encuentren los directorios hermanos (project2yproject3).fuente