Fazendo loop em subdiretórios e executando um comando em cada

47

Eu tenho um conjunto de repositórios classificados em diretórios com base em seus VCS (Git, Mercurial, SVN). Com o Subversion, eu era capaz de executar svn update *no diretório pai e ele percorria cada diretório e atualizava cada repositório conforme o esperado. Esse não é o caso do Git ou do Mercurial.

Gostaria de chegar a um script que eu posso correr para fazer exatamente isso, percorrer diretórios e ou git pullou hg pullem cada um. Eu simplesmente não tenho muita experiência com scripts bash.

Bryan Veloso
fonte
Pode ser esclarecido se você deseja que os comandos sejam executados recursivamente (em todas as subpastas), onde a resposta do mj41 é a única que eu tentei (daqui e em outros sites da SO) que faz isso.
r_alex_hall 8/11
* faz isso com um ajuste que eu mencionei em um comentário.
r_alex_hall 8/11

Respostas:

81
for dir in ~/projects/git/*; do (cd "$dir" && git pull); done
jtimberman
fonte
2
Thnx ... mas eu preciso capturar erros também. Como eu posso fazer isso. Eu nunca fiz programação de shell antes.
Shashwat
23

Se você precisar que seja recursivo:

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

Isso irá descer para todos os diretórios abaixo do atual e executar um pull git nos subdiretórios que possuem um diretório .git (você pode limitá-lo -maxdepth).

Dennis Williamson
fonte
@ privilégios: inteligente!
Dennis Williamson
9
-execdiré muito melhor aqui:find . -type d -name .git -execdir sh -c "pwd && git pull" \;
daniel kullmann
Esta é uma resposta melhor na minha opinião subjetiva ... Trabalhou imediatamente para mim .. Cheers
Voke Ransom Anighoro
Ao contrário da pergunta que me ligou aqui, esse comando realmente funcionou. Obrigado.
user1445967
7

Se você possui o GNU Parallel http: // www.gnu.org/software/parallel/ instalado, você pode fazer isso:

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

Isso será executado em paralelo, portanto, se a conexão de rede de alguns servidores git estiver lenta, isso poderá acelerar as coisas.

Assista ao vídeo de introdução do GNU Parallel para saber mais: http://www.youtube.com/watch?v=OpaiGYxkSuQ

Ole Tange
fonte
Talvez faça ls */para ter certeza de que você está dando uma contribuição coerente cd.
1811 Joe Corneli
4

Isso deve funcionar

find . -maxdepth 1 -type d -name '.git' -exec sh -c 'cd "{}" && pwd && git pull' \;
mj41
fonte
Ao remover o -maxdepth 1sinalizador, este é o único comando que encontrei em várias pesquisas e tentativas que executam um comando recursivamente (em todos os subdiretórios, não apenas nos diretórios de um nível abaixo).
r_alex_hall 8/11
0

Para fazê-lo recursivo sem usar, findmasforloop

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