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 prune
para 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é prune
hace aunque haya leído la página de manual) y el segundo no funcionaría en mi caso, porque evitaría que se repita find
en la .git
carpeta pero no en todos otras carpetas
Entonces, lo que realmente necesito es:
para todos los subdirectorios, verifique si contienen una .git
carpeta 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 .git
es 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
-prune
esta 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 d
para qué condicióntest -e ...
es verdadera y si es así, ejecutamos acciones, lo-print -prune
que significa imprimirlo y cortar el subárbol, ¿verdad?find . -type d -exec test -e '{}/.git' \; -print -prune | parallel cd "{}" \&\& git pull --rebase
GNUparallel
es un reemplazo muy útil paraxargs
Solución posible
Para GNU
find
y otras implementaciones que admiten-execdir
:(ver los comentarios)
Cosas discutidas previamente
Solución si la poda a continuación
.git
es suficienteSi
-printf '%h'
es compatible (como en el caso de GNU'sfind
) no necesitamosdirname
:Una vez que se encuentre con una carpeta
.git
en 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
.git
se encuentraUsando
-quit
si tu lofind
admite:(De acuerdo con esta publicación detallada de Stéphane Chazelas,
-quit
se admite en GNU y FreeBSDfind
y en NetBSD como-exit
).De nuevo con
-printf '%h'
si es compatible:Solución para podar al mismo nivel que donde está la
.git
carpetaConsulte la parte "Posible solución" para ver la solución actual para este problema en particular.
(Ah, y obviamente las soluciones que usan
xargs
asumen que no hay líneas nuevas en los caminos, de lo contrario, necesitarías magia de byte nulo).fuente
dir1
contiene dos directoriosdirx
ydiry
cada uno contiene un.git
directorio, esto solo informadirx/.git
dir1/.git
existe, 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
.git
entrada 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.git
entrada) implica generar un proceso que ejecute unatest
utilidad utilizando el-exec
predicado, que será menos eficiente que enumerar el contenido de algunos directorios.Una excepción sería si usa la
find
construcción delbosh
shell (un tenedor POSIXified del shell Bourne desarrollado por @schily ) que tiene un-call
predicado 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 -print
que ejecuta untest
comando en un nuevo proceso para cada directorio no oculto.fuente
.git
puede ser un archivo, así - a través degit worktree
-d
s 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
time
esto, para ver la diferencia con y sin-prune
.Esto se basa en una solución en el
man find
. Puede editar elCVS
ysvn
si 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,
-prune
evita el descenso innecesario a directorios que ya han sido descubiertos (por ejemplo, no buscamosproject3/src
porque ya lo encontramosproject3/.svn
), pero asegura que se encuentren los directorios hermanos (project2
yproject3
).fuente