Wie kann ich mit Bash-Skript alle lokalen Zweige in meinem Repository durchlaufen? Ich muss iterieren und prüfen, ob es einen Unterschied zwischen dem Zweig und einigen entfernten Zweigen gibt. Ex
for branch in $(git branch);
do
git log --oneline $branch ^remotes/origin/master;
done
Ich muss etwas wie oben angegeben tun, aber das Problem, mit dem ich konfrontiert bin, ist $ (Git-Zweig), der mir die Ordner im Repository-Ordner zusammen mit den im Repository vorhandenen Zweigen gibt.
Ist dies der richtige Weg, um dieses Problem zu lösen? Oder gibt es einen anderen Weg, es zu tun?
Danke dir
for b in "$(git branch)"; do git branch -D $b; done
Antworten:
Sie sollten beim Schreiben von Skripten keinen Git-Zweig verwenden . Git bietet eine "Sanitär" -Schnittstelle , die explizit für die Verwendung in Skripten entwickelt wurde (viele aktuelle und historische Implementierungen normaler Git-Befehle (Hinzufügen, Auschecken, Zusammenführen usw.) verwenden dieselbe Schnittstelle).
Der gewünschte Installationsbefehl lautet git for-each-ref :
Hinweis: Sie benötigen das
remotes/
Präfix auf der Remote-Referenz nur, wenn Sie andere Referenzen haben, die dazu führenorigin/master
, dass mehrere Stellen im Suchpfad für Referenznamen übereinstimmen (siehe „Ein symbolischer Referenzname .…“ Im Abschnitt „ Revisionen angeben“ von git-rev-parse (1) ). Wenn Sie versuchen, Mehrdeutigkeiten explizit zu vermeiden, verwenden Sie den vollständigen Referenznamen :refs/remotes/origin/master
.Sie erhalten folgende Ausgabe:
Sie können diese Ausgabe in sh leiten .
Wenn Ihnen die Idee, den Shell-Code zu generieren, nicht gefällt, können Sie auf Robustheit * verzichten und dies tun:
* Ref-Namen sollten vor der Wortteilung der Shell geschützt sein (siehe git-check-ref-Format (1) ). Persönlich würde ich mich an die frühere Version halten (generierter Shell-Code); Ich bin zuversichtlicher, dass damit nichts Unangemessenes passieren kann.
Da Sie bash angegeben haben und es Arrays unterstützt, können Sie die Sicherheit aufrechterhalten und dennoch vermeiden, die Eingeweide Ihrer Schleife zu generieren:
Ähnliches können Sie tun,
$@
wenn Sie keine Shell verwenden, die Arrays unterstützt (set --
zum Initialisieren undset -- "$@" %(refname)
Hinzufügen von Elementen).quelle
--merged
möchte , wie müsste ich die Logik in git branch duplizieren? Es muss einen besseren Weg geben, dies zu tun.git for-each-ref refs/heads | cut -d/ -f3-
git for-each-ref refs/heads --format='%(refname)'
for-each-ref
Unterstützt jetzt alle Branchenselektoren wie--merged
undgit branch
undgit tag
wird nun tatsächlich in sichgit for-each-ref
selbst implementiert , zumindest für die in der Liste vorhandenen Fälle. (Das Erstellen neuer Zweige und Tags ist nicht Teil vonfor-each-ref
.)Dies liegt daran
git branch
, dass der aktuelle Zweig mit einem Sternchen markiert ist, z.wird also
$(git branch)
auf z. B. erweitert* master mybranch
, und dann wird die*
Liste der Dateien im aktuellen Verzeichnis erweitert.Ich sehe keine offensichtliche Option, das Sternchen überhaupt nicht zu drucken. aber du könntest es abhacken:
quelle
$(git branch | sed -e s/\\*//g)
.3-
Lösung wirklich .$(git branch | sed 's/^..//')
$(git branch | tr -d " *")
Die eingebaute Bash
mapfile
ist dafür gebautAlle Git-Zweige:
git branch --all --format='%(refname:short)'
Alle lokalen Git-Filialen:
git branch --format='%(refname:short)'
Alle Remote-Git-Zweige:
git branch --remotes --format='%(refname:short)'
iteriere durch alle Git-Zweige:
mapfile -t -C my_callback -c 1 < <( get_branches )
Beispiel:
für die spezifische Situation des OP:
Quelle: Listet alle lokalen Git-Zweige ohne Sternchen auf
quelle
Ich iteriere wie es zum Beispiel:
quelle
Ich würde vorschlagen,
$(git branch|grep -o "[0-9A-Za-z]\+")
wenn Ihre lokalen Niederlassungen nur durch Ziffern, Az und / oder AZ-Buchstaben benannt sindquelle
Die akzeptierte Antwort ist richtig und sollte eigentlich der Ansatz sein, aber das Lösen des Problems in Bash ist eine großartige Übung, um zu verstehen, wie Muscheln funktionieren. Der Trick, dies mit bash zu tun, ohne zusätzliche Textmanipulationen durchzuführen, besteht darin, sicherzustellen, dass die Ausgabe des Git-Zweigs niemals als Teil eines von der Shell auszuführenden Befehls erweitert wird. Dies verhindert, dass das Sternchen in der Dateinamenerweiterung (Schritt 8) der Shell-Erweiterung jemals erweitert wird (siehe http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_03_04.html ).
Verwenden Sie das bash while- Konstrukt mit einem Lesebefehl, um die Ausgabe des Git-Zweigs in Zeilen zu zerlegen. Das '*' wird als wörtliches Zeichen eingelesen. Verwenden Sie eine case-Anweisung, um sie abzugleichen, und achten Sie dabei besonders auf die übereinstimmenden Muster.
Die Sternchen sowohl im Bash- Case- Konstrukt als auch in der Parametersubstitution müssen mit Backslashes maskiert werden, damit die Shell sie nicht als Mustervergleichszeichen interpretiert. Die Leerzeichen werden auch maskiert (um eine Tokenisierung zu verhindern), da Sie buchstäblich mit '*' übereinstimmen.
quelle
Die meiner Meinung nach am einfachsten zu merkende Option:
git branch | grep "[^* ]+" -Eo
Ausgabe:
Die Option -o von Grep (--only-matching) beschränkt die Ausgabe nur auf die übereinstimmenden Teile der Eingabe.
Da in Git-Zweignamen weder Leerzeichen noch * gültig sind, wird die Liste der Zweige ohne die zusätzlichen Zeichen zurückgegeben.
Bearbeiten: Wenn Sie sich im Status "Abgelöster Kopf" befinden , müssen Sie den aktuellen Eintrag herausfiltern:
git branch --list | grep -v "HEAD detached" | grep "[^* ]+" -oE
quelle
Was ich letztendlich getan habe, bezog sich auf Ihre Frage (& inspiriert von der Erwähnung von ccpizza
tr
):git branch | tr -d ' *' | while IFS='' read -r line; do git log --oneline "$line" ^remotes/origin/master; done
(Ich benutze While - Schleifen viel. Während für bestimmte Dinge würden Sie auf jeden Fall mit einem spitzen Variablennamen verwenden mögen [ „Zweig“, zum Beispiel], die meisten der Zeit , die ich nur mit etwas zu tun , mit jeder betroffenen bin Linie der Eingabe. Mit "Linie" hier anstelle von "Zweig" ist eine Anspielung auf Wiederverwendbarkeit / Muskelgedächtnis / Effizienz.)
quelle
Im Anschluss an die Antwort von @ finn (danke!) Können Sie im Folgenden über die Zweige iterieren, ohne ein dazwischenliegendes Shell-Skript zu erstellen. Es ist robust genug, solange der Filialname keine Zeilenumbrüche enthält :)
Die while-Schleife wird in einer Subshell ausgeführt. Dies ist normalerweise in Ordnung, es sei denn, Sie legen Shell-Variablen fest, auf die Sie in der aktuellen Shell zugreifen möchten. In diesem Fall verwenden Sie die Prozessersetzung, um die Pipe umzukehren:
quelle
Wenn Sie in diesem Zustand sind:
Und Sie führen diesen Code aus:
Sie erhalten dieses Ergebnis:
quelle
for b in "$(git branch)"; do git branch -D $b; done
Halte es einfach
Die einfache Möglichkeit, den Zweignamen mithilfe eines Bash-Skripts in eine Schleife zu bringen.
Ausgabe:
quelle
Googlians Antwort, aber ohne Verwendung für
quelle
Hierbei werden Git-Installationsbefehle verwendet , die für die Skripterstellung vorgesehen sind. Es ist auch einfach und Standard.
Referenz: Git's Bash-Vervollständigung
quelle