Faire une boucle dans les sous-répertoires et exécuter une commande dans chacun


47

J'ai un ensemble de référentiels triés dans des répertoires basés sur leur VCS (Git, Mercurial, SVN). Avec Subversion, je pouvais m'exécuter svn update *dans le répertoire parent, qui parcourait chaque répertoire et mettait à jour chaque référentiel comme prévu. Ce n'est pas le cas pour Git ou Mercurial.

Je voudrais créer un script bash que je peux exécuter pour faire exactement cela, en parcourant des répertoires et l'un git pullou l' autre hg pull. Je n'ai tout simplement pas beaucoup d'expérience de script bash.


On pourrait préciser si vous voulez que les commandes soient exécutées de manière récursive (dans tous les sous-dossiers), la réponse de mj41 étant la seule réponse que j'ai essayée (à partir d'ici et sur d'autres sites SO).
r_alex_hall

* le fait avec un tweak que je mentionne dans un commentaire à ce sujet.
r_alex_hall

Réponses:


81
for dir in ~/projects/git/*; do (cd "$dir" && git pull); done

2
Thnx ... mais je dois aussi capturer les erreurs. Comment puis-je le faire Je n'ai jamais fait de programmation shell auparavant.
Shashwat

23

Si vous en avez besoin pour être récursif:

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

Cela descendra dans tous les répertoires sous le répertoire actuel et effectuera un tirage git sur les sous-répertoires contenant un répertoire .git (vous pouvez le limiter -maxdepth).


@thprivileges: intelligent!
pause jusqu'à nouvel ordre.

9
-execdirest beaucoup mieux ici:find . -type d -name .git -execdir sh -c "pwd && git pull" \;
daniel kullmann

Ceci est une meilleure réponse à mon avis subjectif ... A travaillé immédiatement pour moi .. Vive
Voke Ransom Anighoro

Contrairement à la question qui me liait ici, cette commande fonctionnait réellement. Merci.
user1445967

7

Si vous avez installé GNU Parallel http: // www.gnu.org/software/parallel/, vous pouvez le faire:

cd ~/projects/git/; ls | parallel 'cd {} && git pull'

Cela fonctionnera en parallèle, donc, si certaines connexions réseau des serveurs git sont lentes, cela peut accélérer les choses.

Regardez la vidéo d'introduction de GNU Parallel pour en savoir plus: http://www.youtube.com/watch?v=OpaiGYxkSuQ


Peut-être faire ls */pour vous assurer que vous apportez une contribution cohérente à cd.
Joe Corneli

4

Cela devrait marcher

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

En supprimant l' -maxdepth 1indicateur, c'est la seule commande que j'ai trouvée dans beaucoup de recherches et d'essais qui exécute une commande de manière récursive (dans tous les sous-répertoires, pas seulement les répertoires d'un niveau inférieur).
r_alex_hall

0

Pour le faire récursif sans utiliser findmaisforloop

for dir in ~/projects/git/*/*/; do (cd "$dir" && git pull); done
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.