2017-01-31 1 views
5
for k in $(git branch -r --merged origin/master | cut -d" " -f 3); do 
    echo $k 
done 

Klonen Ich habe eine Liste von git Projekte, die ich will, in den alten Zweigen aufzuräumen, was ich tun möchte, ist die Liste und löschen Sie alle Zweige, die zu Master zusammengeführt werden.Liste und löschen git Zweige ohne

Gibt es eine Möglichkeit, das obige zu tun, ohne jedes Repo lokal zu klonen?

+0

Verwenden Sie 'git branch' und das Löschen mit' git branch -d '. – phunsukwangdu

+0

ich werde 'git branch -d branch_name' verwenden, um branch zu löschen yes, was ich wissen möchte, ist, wenn es eine Möglichkeit gibt, es zu tun, ohne eine lokale Kopie des repository zu haben –

+0

verweist dies [link] (http: // stackoverflow .com/questions/2003505/how-to-löschen-a-git-branch-sowohl-lokal-und-remote) – phunsukwangdu

Antwort

8

Sie benötigen git ls-remote:

Name

git-ls-remote - Liste Referenzen in einem Remote-Repository

SYNTAX

git ls-remote [--heads] [--tags] [--refs] [--upload-pack=<exec>] 
       [-q | --quiet] [--exit-code] [--get-url] 
       [--symref] [<repository> [<refs>...]] 

BESCHREIBUNG

Zeigt Referenzen an, die in einem Remote-Repository zusammen mit den zugehörigen Commit-IDs verfügbar sind.

So funktioniert es wie:

% git ls-remote origin 
af51dfb080728117d898e1d0a10e3fe01ed67063  HEAD 
6a60cc68a2953f1a62b0dca641eb29509b5b6e8c  refs/heads/expdate-fix 
af51dfb080728117d898e1d0a10e3fe01ed67063  refs/heads/master 
4c42e43b4ccfd37074d115f6e9a694ddb8b70d55  refs/heads/redux 
fd18a67bbc5cbf8aa6cda136afa4e5c20ed2d522  refs/heads/rest 
7ad17cdf8b0dcd1a29a1795a363279fb3c76ac66  refs/tags/test.key 
be0b2d6881902600fb3d6686c10d0a47f1e6751a  refs/tags/test.pub 

nur Zweig (Köpfe) zu erhalten, müssen Sie die Refspec verengen:

% git ls-remote origin 'refs/heads/*' 
6a60cc68a2953f1a62b0dca641eb29509b5b6e8c  refs/heads/expdate-fix 
af51dfb080728117d898e1d0a10e3fe01ed67063  refs/heads/master 
4c42e43b4ccfd37074d115f6e9a694ddb8b70d55  refs/heads/redux 
fd18a67bbc5cbf8aa6cda136afa4e5c20ed2d522  refs/heads/rest 

Jetzt könnten Sie Skript, um diesen Ausgang wie

git ls-remote origin 'refs/heads/*' | while read sha ref; do 
    # test if $sha is merged 
done 

Um einen Zweig zu löschen, müssen Sie "nichts drücken g“, um es, wie in

git push origin :refs/heads/feature-x 

(eine leere Zeichenfolge links von bemerken,‚:‘, das definiert, was zu drücken, was auf der rechten Seite).

So bekommen wir so etwas wie

#!/bin/sh 
set -e -u 
git ls-remote origin 'refs/heads/*' | while read sha ref; do 
    # test if $sha is merged 
    E=`git cat-file -t "$sha" 2>&1` 
    test $? -ne 0 -a "${E#*git cat-file: *}" = "could not get object info" && continue 
    git branch --merged "$sha" && printf ':%s\0' "$ref" 
done | xargs -0 git push origin 

Bitte beachte, dass wir verwenden printf Shell builtin die Namen des Refs geben wir mit dem ASCII-Zeichen NUL zu begrenzen und dann -0-xargs passieren NUL-terminiert zu erwarten Eingang. Auf diese Weise arbeiten wir funky Ref Namen (mit Leerzeichen usw.).

Einige Erklärungen:

  • Wenn git cat-file -t <object_sha1_name> das Objekt mit dem angegebenen SHA1 Namen im lokalen Repository zu lokalisieren fehlschlägt, es mit einem Nicht-Null-Exit-Code beendet und Druck

    fatal: git cat-file: konnte keine Objekt Info

    zu seinem stder bekommen r.

  • So die Geschichte zu testen, ob ein Remote-ref Punkte auf im lokalen Repository existiert wir git cat-file -t auf dem SHA1 Namen des Objekts es Punkte an, greifen die kombinierte Ausgabe dieses Befehls und dann Test ob es laufen verlassen mit einem nicht-Null-Beendigungscode ($? -ne 0) und ob seine Fehlermeldung ein fehlendes Objekt zeigt (die ${VAR#PATTERN} entfernt das Präfix PATTERN aus dem Inhalt der variablen VAR und gibt den sich ergebenden Wert entspricht).

  • Wenn die Geschichte ein Remote-ref Punkte an nicht im lokalen Repository vorhanden sind, ist es per Definition nicht zu einem lokalen Refs zusammengefügt werden können, also, wenn wir eine solche ref erkennen wir seine weitere Tests mit überspringen git branch --merged.

+0

Das ist genau das, was ich brauchte, ich hatte die LS-Fernbedienung schon einmal gesehen, aber nicht verstanden. Danke –

+0

Es gibt ein großes Problem hier: Wenn Ihr Repository mit dieser Fernbedienung nicht auf dem neuesten Stand ist, kann 'git branch --merged' Ihnen keine richtigen Antworten geben. Dies bedeutet, dass Sie zuerst 'git fetch' ausführen und dann lokal arbeiten können. – torek

+0

@torek, das ist richtig. Auf der anderen Seite sollte die Frage eigentlich dazu dienen, das Herunterladen von Geschichte zu vermeiden (ich nehme "ohne Klonen" auch "ohne zu holen" an). Ein Umweg wäre das Testen für den Spezialfall "Commit not in the repository". Leider ist die Handhabung dieses Falles in 'git branch {--contains | --merged}' (für mich) überraschend: da sie * annehmen * existiert das Objekt mit dem gegebenen Namen und spuckt eine nicht sehr hilfreiche Fehlermeldung aus es tut es nicht. Angeblich würde 'git cat-file -t" $ sha "' für den Commit-Namen zuerst besser sein, da es sich IMO in einer besser vorhersagbaren Weise verhält. – kostix