Цикл по подкаталогам и запуск команды в каждом

42

У меня есть набор репозиториев, отсортированных по каталогам на основе их VCS (Git, Mercurial, SVN). С Subversion я смог запустить svn update * в родительском каталоге, и он будет проходить через каждый каталог и обновлять каждый репозиторий, как ожидалось. Это не относится к Git или Mercurial.

Я хотел бы придумать сценарий bash, который я могу запустить, чтобы сделать именно это, цикл по каталогам и git pull или же hg pull в каждом. У меня просто нет большого опыта написания сценариев bash.

Bryan Veloso
источник

Ответы:

74
for dir in ~/projects/git/*; do (cd "$dir" && git pull); done
jtimberman
источник
2
Thnx ... но мне нужно также фиксировать ошибки. Как я могу это сделать. Я никогда раньше не занимался программированием оболочки.
shashwat
20

Если вам нужно, чтобы он был рекурсивным:

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

Это спустится во все каталоги под текущим и выполнит git pull для тех подкаталогов, которые имеют каталог .git (вы можете ограничить его -maxdepth ).

Dennis Williamson
источник
@thprivileges: умный!
Dennis Williamson
8
-execdir здесь намного лучше find . -type d -name .git -execdir sh -c "pwd && git pull" \;
daniel kullmann
Это лучший ответ по моему субъективному мнению ... Сработало сразу для меня .. Ура
Voke Ransom Anighoro
7

Если у вас установлен GNU Parallel http: // www.gnu.org/software/parallel/, вы можете сделать это:

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

Это будет работать параллельно, поэтому, если некоторые из сетевых соединений git-серверов работают медленно, это может ускорить процесс.

Посмотрите вступительное видео для GNU Parallel, чтобы узнать больше: http://www.youtube.com/watch?v=OpaiGYxkSuQ

Ole Tange
источник
Может быть, сделать ls */ чтобы убедиться, что вы вносите последовательный вклад в cd,
Joe Corneli
3

Это должно работать

find . -maxdepth 1 -type d -name '.git' -exec sh -c 'cd "{}" && pwd && git pull' \;
mj41
источник
0

Сделать это рекурсивный без использования find но forloop

for dir in ~/projects/git/*/*/; do (cd "$dir" && git pull); done
loretoparisi
источник