Ejecutar git pull over todos los subdirectorys

¿Cómo puedo actualizar varios repositorys de git desde el directory de padres compartidos sin tener que entrar en el directory raíz de cada repository? Tengo los siguientes que son todos repositorys git separados ( no submodules):

 /plugins/cms /plugins/admin /plugins/chart 

Quiero actualizarlos todos a la vez o al less simplificar mi flujo de trabajo actual:

 cd ~/plugins/admin git pull origin master cd ../chart git pull 

etc.

Ejecute lo siguiente desde el directory principal, plugins en este caso:

 find . -type d -depth 1 -exec git --git-dir={}/.git --work-tree=$PWD/{} pull origin master \; 

Para aclarar:

  • find . busca en el directory actual
  • -type d para encontrar directorys, no files
  • -depth 1 para una profundidad máxima de un subdirectory
  • -exec {} \; ejecuta un command personalizado para cada búsqueda
  • git --git-dir={}/.git --work-tree=$PWD/{} pull git extrae los directorys individuales

Para jugar con find, recomiendo usar echo after -exec para get una vista previa, por ejemplo:

 find . -type d -depth 1 -exec echo git --git-dir={}/.git --work-tree=$PWD/{} status \; 

Nota: si la opción -depth 1 no está disponible, intente -mindepth 1 -maxdepth 1 .

 ls | xargs -I{} git -C {} pull 

Para hacerlo en paralelo:

 ls | xargs -P10 -I{} git -C {} pull 

Un poco más de baja tecnología que la solución de Leo:

 for i in */.git; do ( echo $i; cd $i/..; git pull; ); done 

Esto actualizará todos los repositorys de Git en su directory de trabajo. No es necesario enumerar explícitamente sus nombres ("cms", "admin", "chart"). El command "cd" solo afecta a una subcadena (generada usando el paréntesis).

Esto debería suceder automáticamente, siempre que cms, admin y chart sean todas partes del repository.

Un problema probable es que cada uno de estos complementos es un submodule de git.

Ejecute el git help submodule para get más información.

EDITAR

Para hacer esto en bash:

 cd plugins for f in cms admin chart do cd $f && git pull origin master && cd .. done 

Yo uso este:

 find . -name ".git" -type d | sed 's/\/.git//' | xargs -P10 -I{} git -C {} pull 

Universal: Actualiza todos los repositorys de git que están debajo del directory actual.

La utilidad mr (aka, myrepos ) proporciona una excelente solución a este problema. Instálalo usando tu administrador de packages favorito, o simplemente toma el script mr directamente desde github y ponlo en $HOME/bin o en otro lugar en tu PATH . Luego, cd a la carpeta de plugins padres compartida por estos repositorys y cree un file .mrconfig básico con contenido similar al siguiente (ajustando las URL según sea necesario):

 # File: .mrconfig [cms] checkout = git clone 'https://<username>@github.com/<username>/cms' 'cms' [admin] checkout = git clone 'https://<username>@github.com/<username>/admin' 'admin' [chart] checkout = git clone 'https://<username>@github.com/<username>/chart' 'chart' 

Después de eso, puede ejecutar mr up desde la carpeta de plugins nivel superior para extraer actualizaciones de cada repository. (Tenga en count que esto también hará el clon inicial si la copy de trabajo objective aún no existe.) Otros commands que puede ejecutar incluyen mr st , mr push , mr log , mr diff , etc., ejecute mr help para ver qué es posible. Hay un command de mr run que actúa como paso a través, lo que le permite acceder a los commands de VCS no directamente respaldados por el propio mr (por ejemplo, mr run git tag STAGING_081220015 ). ¡Incluso puede crear sus propios commands personalizados que ejecutan bits arbitrarios de script de shell dirigidos a todos los repositorys!

mr es una herramienta extremadamente útil para tratar múltiples repositorys. Como la carpeta de plugins está en su directory de inicio, es posible que también esté interesado en vcsh . Junto con mr , proporciona un poderoso mecanismo para administrar todos sus files de configuration. Vea esta publicación del blog de Thomas Ferris Niqueueisen para una descripción general.

El método más compacto, suponiendo que todos los subdirectores son repositorys git:

 ls | parallel git -C {} pull 

En realidad, si no sabe si las subcarpetas tienen un repository de git o no, lo mejor sería dejar que find obtenga los repos para usted:

 find . -type d -name .git -exec git --git-dir={} --work-tree=$PWD/{}/.. pull origin master \; 

El equivalente de PowerShell sería:

 Get-ChildItem -Recurse -Directory -Hidden -Filter .git | ForEach-Object { & git --git-dir="$($_.FullName)" --work-tree="$(Split-Path $_.FullName -Parent)" pull origin master } 

Puedes intentar esto

 find . -type d -name .git -exec sh -c "cd \"{}\"/../ && pwd && git pull" \; 

Además, puede agregar su salida personalizada agregando un argumento más && como.

 find . -type d -name .git -exec sh -c "cd \"{}\"/../ && pwd && git pull && git status" \; 

Ninguna de las 5 respuestas principales funcionó para mí, y la pregunta habló sobre directorys.

Esto funcionó:

 for d in *; do pushd $d && git pull && popd; done 

Respuesta original 2010:

Si todos esos directorys están separados git repo, debe referencerlos como submodules .

Eso significa que su "origen" sería el de los " plugins " repo remotos que solo contienen references a los subrepos ' cms ', ' admin ', ' chart '.

Un git pull seguido de una git submodule update lograría lo que estás buscando.


Actualización enero de 2016:

Con Git 2.8 (Q1 2016), podrá search submodules en paralelo (!) Con git fetch --recurse-submodules -j2 .
Consulte " Cómo acelerar / paralelizar descargas de submodules de git usando git clone –recursive? "

gitfox es una herramienta para ejecutar commands en todos los subrepos

 npm install gitfox -g g pull 

yo uso esto

 for dir in $(find . -name ".git") do cd ${dir%/*} echo $PWD git pull echo "" cd - > /dev/null done 

Github

Como tiene un directory padre compartido, simplemente puede hacer

git do pull de los plugins / directory

Combiné puntos de varios comentarios y respuestas:

 find . -maxdepth 1 -type d -name .git -execdir git pull \; 

Mi humilde construcción que

  • muestra la ruta actual (usando python, conveniente y simplemente funciona, consulte ¿Cómo get la ruta completa de un file? )
  • busca directamente la subcarpeta .git : baja probabilidad de emitir un command git en una subcarpeta no git
  • se deshace de algunas advertencias de find

de la siguiente manera:

 find . \ -maxdepth 2 -type d \ -name ".git" \ -execdir python -c 'import os; print(os.path.abspath("."))' \; \ -execdir git pull \; 

Por supuesto, puede agregar otros commands git con opciones adicionales -execdir para find , mostrando la twig, por ejemplo:

 find . \ -maxdepth 2 -type d \ -name ".git" \ -execdir python -c 'import os; print(os.path.abspath("."))' \; \ -execdir git branch \; -execdir git pull \; 

Si tiene muchos subdires con repositorys git, puede usar paralelo

 ls | parallel -I{} -j100 ' if [ -d {}/.git ]; then echo Pulling {} git -C {} pull > /dev/null && echo "pulled" || echo "error :(" else echo {} is not a .git directory fi '