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.
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 recherchegit --git-dir={}/.git --work-tree=$PWD/{} pull
Git tire les répertoires individuelsPour 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
.
ls | xargs -I{} git -C {} pull
Pour le faire en parallèle:
ls | xargs -P10 -I{} git -C {} pull
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).
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.
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 }
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 mr
directement 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.
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
Méthode la plus compacte, en supposant que tous les sous-répertoires sont des dépôts git:
ls | parallel git -C {} pull
gitfox
est un outil pour exécuter des commandes sur tous les sous-dépôts
npm install gitfox -g
g pull
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
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" \;
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? "
Mon humble construction qui
.git
: faible risque d'émettre une commande git dans un sous-dossier non gitfind
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 \;
Je l'utilise
for dir in $(find . -name ".git")
do cd ${dir%/*}
echo $PWD
git pull
echo ""
cd - > /dev/null
done
J'ai combiné les points de plusieurs commentaires et réponses:
find . -maxdepth 1 -type d -name .git -execdir git pull \;