Wie überprüfe ich, ob ein Remote-Zweig in einem bestimmten Remote-Repository vorhanden ist?

105

Ich muss eine Teilbaumzusammenführung für einen bestimmten Zweig durchführen, wenn dieser in einem bestimmten Remote-Repository vorhanden ist. Das Problem ist, dass das Remote-Repository nicht lokal ausgecheckt ist, sodass ich es nicht verwenden kann git branch -r. Ich habe nur eine entfernte Adresse, so etwas https://github.com/project-name/project-name.git. Gibt es eine Möglichkeit, entfernte Zweige nur anhand einer entfernten Adresse aufzulisten? Ich konnte nichts Nützliches finden :(

Daran interessiert
quelle

Antworten:

123
$ git ls-remote --heads [email protected]:user/repo.git branch-name

Falls branch-namegefunden wird, erhalten Sie folgende Ausgabe:

b523c9000c4df1afbd8371324083fef218669108        refs/heads/branch-name

Andernfalls wird keine Ausgabe gesendet.

Wenn Sie es also wcweiterleiten, erhalten Sie 1oder 0:

$ git ls-remote --heads [email protected]:user/repo.git branch-name | wc -l

Alternativ können Sie ein --exit-codeFlag setzen, git ls-remotedas den Exit-Code 2zurückgibt, falls keine passenden Refs gefunden werden. Dies ist die idiomatischste Lösung. Das Ergebnis kann direkt in einem Shell-Test oder durch Überprüfen der Statusvariablen überprüft werden $?.

$ git ls-remote --exit-code --heads  [email protected]:user/repo.git branch-name
user487772
quelle
7
Ich benutzte git ls-remote --heads ${REPO} ${BRANCH} | grep ${BRANCH} >/dev/nullgefolgt vonif [ "$?" == "1" ] ; then echo "Branch doesn't exist"; exit; fi
sibaz
1
Ich habe ein paar Stunden lang nach dieser ordentlichen und präzisen Antwort gesucht, brillant.
medik
Sie müssen den Filialnamen als angeben /refs/heads/branch-name. Andernfalls foo/branch-namewürde die Verzweigung zurückgegeben, auch wenn keine vorhanden ist branch-name.
FuzzY
Herzlichen Glückwunsch zu Ihrem Goldabzeichen "Great Answer". :)
jmort253
3
Hinweis: Wenn Sie die Repo-URL nicht angeben müssen, können Sie stattdessen den Namen der Repo-Fernbedienung angeben, z. B.:git ls-remote --heads origin branch-name
daveruinseverything
50
git ls-remote --heads https://github.com/rails/rails.git
5b3f7563ae1b4a7160fda7fe34240d40c5777dcd    refs/heads/1-2-stable
81d828a14c82b882e31612431a56f830bdc1076f    refs/heads/2-0-stable
b5d759fd2848146f7ee7a4c1b1a4be39e2f1a2bc    refs/heads/2-1-stable
c6cb5a5ab00ac9e857e5b2757d2bce6a5ad14b32    refs/heads/2-2-stable
e0774e47302a907319ed974ccf59b8b54d32bbde    refs/heads/2-3-stable
13ad87971cc16ebc5c286b484821e2cb0fc3e3b1    refs/heads/3-0-stable
3df6c73f9edb3a99f0d51d827ef13a439f31743a    refs/heads/3-1-stable
f4db3d72ea564c77d5a689b850751ce510500585    refs/heads/compressor
c5a809e29e9213102351def7e791c3a8a67d7371    refs/heads/deps_refactor
821e15e5f2d9ef2aa43918a16cbd00f40c221e95    refs/heads/encoding
8f57bf207ff4f28fa8da4544ebc573007b65439d    refs/heads/master
c796d695909c8632b4074b7af69a1ef46c68289a    refs/heads/sass-cleanup
afd7140b66e7cb32e1be58d9e44489e6bcbde0dc    refs/heads/serializers
Dogbert
quelle
Ich wusste auch nichts über ls-remote. Danke dir!
Keen
7
Ich musste einen Test in einem Bash-Skript durchführen und war daher nur wirklich am Exit-Code interessiert, also habe ich in einem lokalen Klon Folgendes getan: git ls-remote --exit-code . origin/branch-name &> /dev/nulldann $?als Testoperand verwendet
Darren Bishop
5
@Darren ist die Verwendung des Befehls direkt in einer Bedingung wie bei if git ls-remote ...; then ...; fiweniger fehleranfällig als die Überprüfung $?(die durch Protokollieren von Anweisungen, Traps usw. geändert werden kann).
Charles Duffy
Warum das --heads?
Steve
@JohnLinux --headslistet nur Zweige auf. Verwenden Sie --tagsdiese Option, um nur Tags aufzulisten.
Rymo
19

Eine andere Möglichkeit, die Sie im aktuellen Ordner verwenden können, wenn es sich um ein Git-Repo handelt , das ausgeführt werden soll

git branch -a | egrep 'remotes/origin/${YOUR_BRANCH_NAME}$'
ИВИ
quelle
2
Verwenden Sie doppelte Anführungszeichen:git branch -a | egrep "remotes/origin/${YOUR_BRANCH_NAME}$"
Ivan
3
Dies ist nicht optimal, da es true zurückgibt, selbst wenn Sie nur einen Teil eines vorhandenen Zweignamens abgeglichen haben, aber nicht genau mit dem Zielzweig übereinstimmen. Daher kann dies in einem Skript nicht sicher verwendet werden, um zu testen, ob der Zweig vorhanden ist, bevor er ausgecheckt wird. Trotzdem danke fürs Teilen, da ich es nützlich fand. Kann wie git branch -a | grep "\b${BRANCH}$"
folgt
2
git fetchist erforderlich, wenn bei dieser Verwendung git branch -aalle Fernbedienungsreferenzen zuerst abgerufen werden. Andernfalls verwenden Sie, git ls-remotewie von anderen angegeben.
Hippy
git branch -a --list '<pattern>'ist auch eine Option. Pipe to grep, wenn Sie einen Rückkehrcode für Ihr Skript benötigen.
LOAS
17

Sie können auch Folgendes verwenden:

git show-branch remotes/origin/<<remote-branch-name>>

gibt das letzte Commit und den Wert von $ zurück? ist 0, sonst wird "fatal: bad sha1 reference remotes / origin / <>" und der Wert von $ zurückgegeben? ist 128

Ajo Paul
quelle
Dadurch werden vor der Überprüfung keine Zweige von der Fernbedienung abgerufen, sodass Sie nicht den neuesten Fernbedienungsstatus erhalten.
Siemanko
11

Dann müssen Sie den Repository-Namen nicht jedes Mal manuell übergeben.

git ls-remote origin <branch>

Anstatt

git ls-remote <full repo url> <branch>

Beispiel:

git ls-remote [email protected]:landmarkgroupme/in-store-application.git  uat_21dec

ODER

git ls-remote origin uat_21dec

Beide geben die gleiche Ausgabe:

Geben Sie hier die Bildbeschreibung ein

Mehr zu Origin : Git hat das Konzept von "Fernbedienungen", bei denen es sich einfach um URLs zu anderen Kopien Ihres Repositorys handelt. Wenn Sie ein anderes Repository klonen, erstellt Git automatisch eine Fernbedienung mit dem Namen "origin" und zeigt darauf. Sie können weitere Informationen zur Fernbedienung anzeigen, indem Sie git remote show origin eingeben.

Amitesh Bharti
quelle
11

Alle Antworten hier sind Linux-Shell-spezifisch, was nicht sehr hilfreich ist, wenn Sie sich in einer Umgebung befinden, die diese Art von Vorgängen nicht unterstützt - beispielsweise die Windows-Eingabeaufforderung.

Akzeptiert glücklicherweise git ls-remoteein --exit-codeArgument, das 0 oder 2 zurückgibt, je nachdem, ob der Zweig existiert oder nicht. So:

git ls-remote --exit-code --heads origin <branch-that-exists-in-origin>

gibt 0 zurück und

git ls-remote --exit-code --heads origin <branch-that-only-exists-locally>

wird 2 zurückgeben.

Für PowerShell können Sie einfach die integrierte Semantik für den Umgang mit Wahrhaftigkeit verwenden:

if (git ls-remote --heads origin <branch-that-exists-in-origin>) { $true } else { $false }

ergibt $true, während:

if (git ls-remote --heads origin <branch-that-only-exists-locally>) { $true } else { $false }

ergibt $false.

Ian Kemp
quelle
10

Sie können so etwas im Bash-Terminal tun. Ersetzen Sie einfach die Echos durch die Befehle, die Sie ausführen möchten.

if git ls-remote https://username:[email protected]/project-name/project-name.git | grep -sw "remote_branch_name" 2>&1>/dev/null; then echo "IT EXISTS..START MERGE" ; else echo "NOT FOUND" ; fi

Ich hoffe es hilft.

Sagunmen
quelle
1
Ich mag das. andere Antworten haben auch ls-remote, was ich mag, ist das "wenn".
Stony
6
$ git ls-remote --heads origin <branch> | wc -l

funktioniert die meiste Zeit.

Funktioniert aber nicht, wenn der Zweig teilweise wie unten übereinstimmt.

$ git branch -a
creative/dev
qa/dev

$ git ls-remote --heads origin dev | wc -l
2

Verwenden

git ls-remote --heads origin <branch> | \
    cut -d$'\t' -f2 | \
    sed 's,refs/heads/,,' | \
    grep ^<branch>$ | wc -l

wenn Sie einen zuverlässigen Weg wollen.

Wenn Sie in Skript verwenden möchten und nicht originals Standardfernbedienung annehmen möchten, dann

git ls-remote --heads $(git remote | head -1) "$branch" | \
    cut -d$'\t' -f2 | \
    sed 's,refs/heads/,,' | \
    grep ^"$branch"$ | wc -l

sollte arbeiten.

Beachten Sie, dass dies git branch -a | grep ...nicht zuverlässig ist, da es eine Weile dauern kann, bis der letzte ausgeführt fetchwurde.

hIpPy
quelle
Für mich ist dies die akzeptierte Antwort, kombiniert mit der von Amitesh (kurzer entfernter Name), kombiniert mit der von James Cache ( grep -x "$branch"ist identisch mit grep ^"$branch"$). Obwohl ich in Skripten die Langformschalter bevorzuge : --line-regexp. Es besteht auch keine Notwendigkeit zu tun wc -l. Wenn Sie eine leere Ausgabe in einen Bash einfügen, wird dies if [ -z ] effektiv als wahr ausgewertet. Dies bedeutet, dass der Zweig nicht vorhanden ist. Das spart Ihnen einige Millisekunden.
Amedee Van Gasse
1

Sie können das Repository hinzufügen, das Sie als Remote verwenden, git remote add something https://github.com/project-name/project-name.gitund dann a ausführen git remote show something, um alle Informationen über die Remote abzurufen. Dies erfordert eine Netzwerkverbindung und ist für den menschlichen Gebrauch nützlich.

Alternativ können Sie a git fetch something. Dadurch werden alle Zweige auf der aufgerufenen Fernbedienung abgerufen somethingund in Ihrem lokalen Repository gespeichert. Sie können sie dann nach Belieben in Ihrer lokalen Niederlassung zusammenführen. Ich empfehle diesen Weg da , wenn Sie schließlich entscheiden , dass Sie haben zu verschmelzen, das ist , was Sie tun müssen.

OT: Ihre Verwendung von "lokal ausgecheckt" zeigt an, dass Sie dies vom Standpunkt eines zentralisierten Versionskontrollsystems aus betrachten. Das ist normalerweise eine Sackgasse, wenn Sie mit Git zu tun haben. Es werden Wörter wie "Kasse" usw. anders verwendet als bei älteren Systemen.

Noufal Ibrahim
quelle
Danke für die Erklärungen. Ich habe mich noch nicht an Git gewöhnt und es erfordert eine andere Denkweise.
Keen
1

Du kannst es versuchen

git diff --quiet @{u} @{0}

Hier @{u}bezieht sich auf Remote / Upstream und @{0}bezieht sich auf den aktuellen lokalen HEAD (mit neuerer Version von Git, @{0}kann gekürzt werden als @). Wenn die Fernbedienung nicht vorhanden ist, tritt ein Fehler auf.

Mit Git 2.16.2 (ich bin nicht sicher, welche Version diese Funktionalität als erste hat, z. B. Git 1.7.1 hat sie nicht) können Sie dies tun

git checkout

Wenn ein Remote-Zweig vorhanden ist, wird eine Ausgabe wie z

Your branch is up to date with 'origin/master'

Ansonsten erfolgt keine Ausgabe.

nr
quelle
1

Gibt alle Zweige (remote oder lokal) zurück, die die Abfrage im Namen enthalten.

git branch --all | grep <query>

alexoviedo999
quelle
0

Wenn Ihre Filialnamen sehr spezifisch sind, müssen Sie grep möglicherweise nicht für die einfache Übereinstimmung von Filialnamen verwenden:

git ls-remote --heads $(git remote | head -1) "*${BRANCH_NAME}*" | \
    cut -d$'\t' -f2 | \
    sed 's,refs/heads/,,' | \
    wc -l

was funktioniert für

BRANCH=master
BRANCH=mas
BRANCH=NonExistingBranch (returns 0)
BRANCH=ISSUE-123

Wir verwenden eine eindeutige Issue-ID als Filialnamen und es funktioniert einwandfrei.

Fabio
quelle
0

Ich habe es gerade versucht:

git ls-remote --heads 2>/dev/null|awk -F 'refs/heads/' '{print $2}'|grep -x "your-branch"|wc -l

Dies gibt 1 zurück, wenn der Zweig "Ihr Zweig" gefunden wird, andernfalls 0.

James Cache
quelle
0

Ich kombiniere einige der obigen Antworten in einem Skript:

BRANCHES=(develop master 7.0 7.0-master)
ORIGIN=bitbucket
REMOTE=github

for BRANCH in "${BRANCHES[@]}"; do
  BRANCH=$(git ls-remote --heads "${ORIGIN}" "${BRANCH}" \
      | cut --delimiter=$'\t' --fields=2 \
      | sed 's,refs/heads/,,' \
      | grep --line-regexp "${BRANCH}")
  if [ -n "${BRANCH}" ]
  then
    git branch --force "${BRANCH}" "${ORIGIN}"/"${BRANCH}"
    git checkout "${BRANCH}"
    git push "${REMOTE}" "${BRANCH}"
  fi
done

git push github --tags

Dieses Skript ruft 4 Zweige von einem Remote-Bitbucket ab und überträgt sie an einen Remote-Github. Anschließend werden alle Tags an Github gesendet. Ich verwende dies in einem Jenkins-Job. Deshalb sehen Sie keine git fetchoder git pull, die bereits in der Jenkins-Job-Repository-Konfiguration ausgeführt werden.

Normalerweise bevorzuge ich Langformoptionen in Skripten. Ich hätte kombinieren git branchund git checkoutverwenden können git checkout -B.

Amedee Van Gasse
quelle