web-dev-qa-db-fra.com

Exécutez git pull sur tous les sous-répertoires

Comment puis-je mettre à jour plusieurs référentiels git à partir du répertoire de leur parent partagé sans cd 'ing dans le répertoire racine de chaque référentiel? J'ai le suivant qui sont tous des dépôts séparés git (not sous-modules):

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

Je souhaite les mettre à jour tous en même temps ou du moins simplifier mon flux de travail actuel:

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

etc.

207
Petah

Exécutez ce qui suit à partir du répertoire parent, plugins dans ce cas:

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

Clarifier:

  • find . Recherche dans le répertoire actuel
  • -type d Pour trouver des répertoires, pas des fichiers
  • -depth 1 Pour une profondeur maximale d'un sous-répertoire
  • -exec {} \; Exécute une commande personnalisée pour chaque recherche
  • git --git-dir={}/.git --work-tree=$PWD/{} pull Git tire les répertoires individuels

Pour jouer avec find, je vous recommande d’utiliser echo après -exec Pour avoir un aperçu, par exemple:

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

Remarque: si l'option -depth 1 N'est pas disponible, essayez -mindepth 1 -maxdepth 1.

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

Pour le faire en parallèle:

ls | xargs -P10 -I{} git -C {} pull
161
Dmitry Mitskevich

Un peu plus low-tech que la solution de Léo:

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

Cela mettra à jour tous les référentiels Git de votre répertoire de travail. Pas besoin de lister explicitement leurs noms ("cms", "admin", "chart"). La commande "cd" affecte uniquement un sous-shell (créé avec la parenthèse).

49
Ingo Blechschmidt

J'utilise celui-ci:

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

Universel: met à jour tous les référentiels git situés sous le répertoire actuel.

21
Liudvikas

En fait, si vous ne savez pas si les sous-dossiers ont un repo git ou pas, le mieux serait de laisser find obtenir le repo pour vous:

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

L'équivalent PowerShell serait:

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

L'utilitaire mr (ou myrepos ) fournit une solution exceptionnelle à ce problème. problème. Installez-le en utilisant votre gestionnaire de paquets préféré, ou prenez simplement le script mrdirectement depuis github et mettez-le dans $HOME/bin Ou ailleurs sur votre PATH . Ensuite, cd dans le dossier parent plugins partagé par ces dépôts et créez un fichier de base .mrconfig Avec un contenu similaire au suivant (en modifiant les URL si nécessaire):

# 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'

Après cela, vous pouvez exécuter mr up À partir du dossier plugins de niveau supérieur pour extraire les mises à jour de chaque référentiel. (Notez que ceci fera également le clonage initial si la copie de travail cible n’existe pas encore.) Les autres commandes que vous pouvez exécuter sont: mr st, mr Push, mr log, mr diff, Etc. - lancez mr help Pour voir ce qui est possible. Il existe une commande mr run Qui sert de passerelle, vous permettant d'accéder aux commandes VCS non directement suportées par mr lui-même (par exemple, mr run git tag STAGING_081220015). Et vous pouvez même créer vos propres commandes personnalisées qui exécutent des bits arbitraires du script Shell ciblant tous les dépôts!

mr est un outil extrêmement utile pour traiter plusieurs pensions. Puisque le dossier plugins se trouve dans votre répertoire personnel, vous pourriez également être intéressé par vcsh . Avec mr, il fournit un mécanisme puissant pour gérer tous tous vos fichiers de configuration. Voir ceci blog post par Thomas Ferris Nicolaisen pour un aperçu.

11
evadeflow

Cela devrait se faire automatiquement, tant que cms, admin et chart font tous partie du référentiel.

Un problème probable est que chacun de ces plugins est un sous-module git.

Courir git help submodule pour plus d'informations.

EDIT

Pour le faire en bash:

cd plugins
for f in cms admin chart
do 
  cd $f && git pull Origin master && cd ..
done
11
Jamie Wong

Méthode la plus compacte, en supposant que tous les sous-répertoires sont des dépôts git:

ls | parallel git -C {} pull
10
cmcginty

gitfox est un outil pour exécuter des commandes sur tous les sous-dépôts

npm install gitfox -g
g pull
4
eqfox

Aucune des cinq principales réponses ne fonctionnait pour moi et la question portait sur les annuaires.

Cela a fonctionné:

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

Tu peux essayer ça

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

En outre, vous pouvez ajouter votre sortie personnalisée en ajoutant un argument supplémentaire comme &.

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

Réponse originale 2010:

Si tous ces répertoires sont des git repo distincts, vous devez les référencer comme suit: submodules.

Cela signifie que votre "Origine" serait ce dépôt à distance 'plugins' qui ne contient que des références à subrepos 'cms', 'admin', 'chart '.

UNE git pull suivi d'un git submodule update réaliserait ce que vous recherchez.


Mise à jour janvier 2016:

Avec Git 2.8 (Q1 2016), vous pourrez récupérer des sous-modules en parallèle (!) Avec git fetch --recurse-submodules -j2.
Voir " Comment accélérer/paralléliser les téléchargements de sous-modules git avec git clone --recursive? "

1
VonC

Mon humble construction qui

  • affiche le chemin actuel (en utilisant python, pratique et fonctionne simplement, voir Comment obtenir le chemin complet d'un fichier? )
  • cherche directement le sous-dossier .git: faible risque d'émettre une commande git dans un sous-dossier non git
  • se débarrasse de certains avertissements de find

comme suit:

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

Bien sûr, vous pouvez ajouter d'autres commandes git avec des options -execdir Supplémentaires à find, en affichant la branche par exemple:

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

Je l'utilise

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

Github

0
P Pang

J'ai combiné les points de plusieurs commentaires et réponses:

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