Durchlaufen von Unterverzeichnissen und Ausführen eines Befehls in jedem

47

Ich habe eine Reihe von Repositorys, die auf der Grundlage ihres VCS (Git, Mercurial, SVN) in Verzeichnisse sortiert sind. Mit Subversion konnte ich svn update *das übergeordnete Verzeichnis ausführen und es durchlief jedes Verzeichnis und aktualisierte jedes Repository wie erwartet. Das ist bei Git oder Mercurial nicht der Fall.

Ich möchte ein Bash-Skript entwickeln, das ich ausführen kann, um genau das zu tun, Verzeichnisse zu durchlaufen und entweder git pulloder hg pullin jedem. Ich habe nur nicht viel Erfahrung mit Bash-Skripten.

Bryan Veloso
quelle
Es könnte geklärt werden, ob Sie die Befehle rekursiv ausführen möchten (in allen Unterordnern), wobei die Antwort von mj41 die einzige ist, die ich versucht habe (von hier und an anderen SO-Standorten), die dies tut.
r_alex_hall
* macht das mit einem Tweak, den ich in einem Kommentar erwähne.
r_alex_hall

Antworten:

81
for dir in ~/projects/git/*; do (cd "$dir" && git pull); done
jtimberman
quelle
2
Danke ... aber ich muss auch Fehler erfassen. Wie kann ich das machen? Ich habe noch nie zuvor Shell-Programmierung gemacht.
Shashwat
23

Wenn Sie es brauchen, um rekursiv zu sein:

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

Dies wird in alle Verzeichnisse unter dem aktuellen Verzeichnis absteigen und einen Git-Pull für die Unterverzeichnisse ausführen, die ein Git-Verzeichnis haben (Sie können es mit einschränken -maxdepth).

Dennis Williamson
quelle
@thprivileges: klug!
Dennis Williamson
9
-execdirist hier viel besser:find . -type d -name .git -execdir sh -c "pwd && git pull" \;
Daniel Kullmann
Dies ist eine bessere Antwort in meiner subjektiven Meinung ... Hat sofort für mich gearbeitet .. Cheers
Voke Ransom Anighoro
Im Gegensatz zu der Frage, die mich hier verbunden hat, hat dieser Befehl tatsächlich funktioniert. Danke.
user1445967
7

Wenn Sie GNU Parallel http: // www.gnu.org/software/parallel/ installiert haben, können Sie dies tun:

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

Dies wird parallel ausgeführt. Wenn einige der Netzwerkverbindungen der Git-Server langsam sind, kann dies die Dinge beschleunigen.

Sehen Sie sich das Einführungsvideo zu GNU Parallel an, um mehr zu erfahren: http://www.youtube.com/watch?v=OpaiGYxkSuQ

Ole Tange
quelle
Vielleicht tun ls */Sie dies , um sicherzugehen, dass Sie einen schlüssigen Beitrag leisten cd.
Joe Corneli
4

Das sollte funktionieren

find . -maxdepth 1 -type d -name '.git' -exec sh -c 'cd "{}" && pwd && git pull' \;
mj41
quelle
Das Entfernen des -maxdepth 1Flags ist der einzige Befehl, den ich bei vielen Suchen und Versuchen gefunden habe, bei denen ein Befehl rekursiv ausgeführt wird (in allen Unterverzeichnissen, nicht nur in den Verzeichnissen eine Ebene tiefer).
r_alex_hall
0

Um es rekursiv zu machen, ohne findaber zu verwendenforloop

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