In einer Unix- oder GNU - Skriptumgebung (z. B. einer Linux-Distribution, Cygwin, OSX): Wie kann am besten ermittelt werden, welcher Git-Zweig derzeit in einem Arbeitsverzeichnis ausgecheckt ist?
Eine Anwendung dieser Technik wäre die automatische Kennzeichnung einer Version (wie svnversion
dies mit Subversion tun würde).
Siehe auch meine verwandte Frage: Wie kann programmgesteuert festgestellt werden, ob ein Git-Checkout ein Tag ist und wenn ja, wie lautet der Tagname?
Die richtige Lösung ist, einen Blick auf contrib/completions/git-completion zu werfen. Bash erledigt dies für die Bash-Eingabeaufforderung in __git_ps1
. Entfernen aller Extras, wie z. B. Auswählen, wie die Situation mit abgetrenntem HEAD beschrieben werden soll, d. H.
branch_name="$(git symbolic-ref HEAD 2>/dev/null)" ||
branch_name="(unnamed branch)" # detached HEAD
branch_name=${branch_name##refs/heads/}
Mit git symbolic-ref wird der vollständig qualifizierte Zweigname aus der symbolischen Referenz extrahiert. Wir verwenden es für HEAD, das derzeit in der Filiale ausgecheckt ist.
Alternative Lösung könnte sein:
branch_name=$(git symbolic-ref -q HEAD)
branch_name=${branch_name##refs/heads/}
branch_name=${branch_name:-HEAD}
wobei wir uns in der letzten Zeile mit der abgetrennten HEAD Situation befassen und einfach "HEAD" verwenden, um eine solche Situation zu bezeichnen.
Hinzugefügt am 11-06-2013
Junio C. Hamano (Git-Betreuer) Blog-Post, Programmatische Überprüfung des aktuellen Zweigs , ab dem 10. Juni 2013, erklärt warum (und wie) genauer.
Steht irgendjemand irgendetwas falsch, wenn Sie Git nur fragen, um den Zweig zu beschreiben, in dem Sie sich befinden?
git rev-parse --symbolic-full-name --abbrev-ref HEAD
Das kann innerhalb von $ () verwendet werden und problemlos in Bash, Powershell, Perl usw. übergeben werden. Es ist nicht zu täuschen, wenn Sie mehrere Äste in Ihrem Commit haben und wenn Sie derzeit nicht in einem Zweig sind antwortet mit "HEAD".
Alternativ können Sie verwenden
git symbolic-ref --short -q HEAD
Das gibt Ihnen die gleiche Ausgabe, aber es wird überhaupt nichts zurückgegeben, wenn Sie losgelöst werden. Dies ist nützlich, wenn Sie einen Fehler wünschen, wenn Sie ihn trennen, entfernen Sie einfach das -q.
sie können git name-rev --name-only HEAD
verwenden.
Aus dieser Antwort: https://stackoverflow.com/a/1418022/605356 :
$ git rev-parse --abbrev-ref HEAD
master
Funktioniert anscheinend mit Git 1.6.3 oder neuer.
Versuche es mit:
git symbolic-ref --short -q HEAD
Oder Sie versuchen mit git branch
mit --no-color
force einfachen einfachen String die Ausgabe:
git branch --no-color
Mit grep im Regex-Modus (-E
) können Sie überprüfen, ob das Zeichen '*' vorhanden ist:
git branch --no-color | grep -E '^\*'
Die Ergebnisse sind ähnlich wie:
* currentBranch
Sie können die nächsten Optionen verwenden:
sed 's/\*[^a-z]*//g'
cut -d ' ' -f 2
awk '{print $2}'
zum Beispiel:
git branch --no-color | grep -E '^\*' | sed 's/\*[^a-z]*//g'
git branch --no-color | grep -E '^\*' | sed cut -d ' ' -f 2
git branch --no-color | grep -E '^\*' | awk '{print $2}'
wenn ein Fehler vorhanden ist, können Sie keinen Standardwert verwenden:
cmd || echo 'defualt value';
Alles in eine Bash-Funktion:
function get_branch() {
git branch --no-color | grep -E '^\*' | awk '{print $2}' \
|| echo "default_value"
# or
# git symbolic-ref --short -q HEAD || echo "default_value";
}
branch_name=`get_branch`;
echo $branch_name;
anpassung der akzeptierten Antwort an Windows-Powershell:
Split-Path -Leaf (git symbolic-ref HEAD)
Dieser arbeitete für mich in der bash-Datei.
git branch | grep '^*' | sed 's/* //'
################bash file###################
#!/bin/bash
BRANCH=$(git branch | grep '^*' | sed 's/* //' )
echo $BRANCH
Dieser arbeitet für mich. Der --no-color
-Teil ist wichtig oder kann wichtig sein, wenn Sie eine einfache Zeichenfolge möchten.
git branch --no-color | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/'
Ich habe zwei wirklich einfache Wege gefunden, das zu tun:
$ git status | head -1 | cut -d ' ' -f 4
und
$ git branch | grep "*" | cut -d ' ' -f 2
Folgendes mache ich:
git branch | sed --quiet 's/* \(.*\)/\1/p'
Die Ausgabe würde so aussehen:
$ git branch | sed --quiet 's/* \(.*\)/\1/p'
master
$
Ich versuche hier für die einfachste und selbsterklärendste Methode:
git status | grep "On branch" | cut -c 11-
Hier ist meine Lösung, geeignet für den Einsatz in einer PS1 oder zum automatischen Kennzeichnen eines Releases
Wenn Sie in einer Zweigstelle ausgecheckt sind, erhalten Sie den Namen der Zweigstelle.
Wenn Sie sich in einem gerade initiierten Git-Projekt befinden, erhalten Sie einfach '@'.
Wenn Sie keinen Kopf haben, erhalten Sie einen Nice-Namen, der sich auf einen Zweig oder ein Tag bezieht, wobei ein '@' vor dem Namen steht.
Wenn Sie keinen Kopf haben und kein Vorfahre eines Zweiges oder Tags sind, erhalten Sie nur die kurze SHA1.
function we_are_in_git_work_tree {
git rev-parse --is-inside-work-tree &> /dev/null
}
function parse_git_branch {
if we_are_in_git_work_tree
then
local BR=$(git rev-parse --symbolic-full-name --abbrev-ref HEAD 2> /dev/null)
if [ "$BR" == HEAD ]
then
local NM=$(git name-rev --name-only HEAD 2> /dev/null)
if [ "$NM" != undefined ]
then echo -n "@$NM"
else git rev-parse --short HEAD 2> /dev/null
fi
else
echo -n $BR
fi
fi
}
Sie können das if we_are_in_git_work_tree
-Bit entfernen, wenn Sie möchten. Ich verwende es einfach in einer anderen Funktion in meiner PS1, die Sie hier vollständig sehen können: PS1-Zeile mit git current branch und Farben
Wenn Sie die alte NT-Befehlszeile verwenden, können Sie Folgendes verwenden:
@for /f "usebackq" %i in (`git symbolic-ref -q HEAD`) do @echo %~ni
Um sie in einer Batchdatei verwenden zu können, müssen Sie die% -Anzahl verdoppeln:
@for /f "usebackq" %%i in (`git symbolic-ref -q HEAD`) do @echo %%~ni
Die Verwendung von --porcelain ergibt eine rückwärtskompatible Ausgabe, die leicht zu analysieren ist:
git status --branch --porcelain | grep '##' | cut -c 4-
Aus der Dokumentation:
Das Porzellanformat ähnelt dem Kurzformat, ändert sich jedoch nicht auf abwärtskompatible Weise zwischen Git-Versionen oder auf der Grundlage der Benutzerkonfiguration. Dies macht es ideal für das Parsen von Skripten.
Jemand erwähnte es in bash mit weniger als drei Zuweisungen ... wie wäre es mit einem unordentlichen Kontrollfluss wie folgt:
branch_name="$(b=$(git symbolic-ref -q HEAD); { [ -n "$b" ] && echo ${b##refs/heads/}; } || echo HEAD)"
Wenn Sie Gradle verwenden,
`` `
def gitHash = new ByteArrayOutputStream()
project.exec {
commandLine 'git', 'rev-parse', '--short', 'HEAD'
standardOutput = gitHash
}
def gitBranch = new ByteArrayOutputStream()
project.exec {
def gitCmd = "git symbolic-ref --short -q HEAD || git branch -rq --contains "+getGitHash()+" | sed -e '2,\$d' -e 's/\\(.*\\)\\/\\(.*\\)\$/\\2/' || echo 'master'"
commandLine "bash", "-c", "${gitCmd}"
standardOutput = gitBranch
}
`` `
Wenn Sie sich auf einem abgesonderten Kopf befinden (d. H. Sie haben ein Release ausgecheckt) und eine Ausgabe vom git-Status wie
HEAD detached at v1.7.3.1
Und wenn Sie die Release-Version wünschen, verwenden wir den folgenden Befehl ...
git status --branch | head -n1 | tr -d 'A-Za-z: '
Dies gibt 1.7.3.1 zurück, das wir in unseren parameters.yml (Symfony) durch ersetzen
# RevNum=`svn status -u | grep revision | tr -d 'A-Za-z: '` # the old SVN version
RevNum=`git status --branch | head -n1 | tr -d 'A-Za-z: '` # Git (obvs)
sed -i "/^ app_version:/c\ app_version:$RevNum" app/config/parameters.yml
Hoffe, das hilft :) Wenn Sie nicht-numerische Zeichen in Ihrem Zweignamen haben, müssen Sie die Argumente des Befehls tr ändern.
Ich habe festgestellt, dass der Aufruf von git ziemlich langsam ist (alle Unterbefehle), insbesondere für die Aktualisierung der Eingabeaufforderung. Die Zeit variiert zwischen 0,1 und 0,2 Sekunden innerhalb des Stammverzeichnisses eines Repos und über 0,2 Sekunden außerhalb eines Repos auf einer erstklassigen Maschine (Raid 1, 8-GB-RAM, 8 Hardwarethreads). Es läuft aber Cygwin.
Deshalb habe ich dieses Skript für Geschwindigkeit geschrieben:
#!/usr/bin/Perl
$cwd=$ENV{PWD}; #`pwd`;
chomp $cwd;
while (length $cwd)
{
-d "$cwd/.git" and do {
-f "$cwd/.git/HEAD" and do {
open IN, "<", "$cwd/.git/HEAD";
$_=<IN>;
close IN;
[email protected]: refs/heads/@@;
print $_;
};
exit;
};
[email protected]/[^/]*[email protected]@;
}
Möglicherweise ein paar Verbesserungen.
Gleiche Ergebnisse wie akzeptierte Antwort in einer einzeiligen Variablenzuordnung:
branch_name=$((git symbolic-ref HEAD 2>/dev/null || echo "(unnamed branch)")|cut -d/ -f3-)
Das ist eine Lösung. Wenn Sie es zu Ihrer .bashrc hinzufügen, wird der aktuelle Zweig in der Konsole angezeigt.
# git branch
parse_git_branch() {
git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/(\1) /'
}
$PS1="\$(parse_git_branch)$PS1"
Es ist jedoch ziemlich begrenzt. Aber es gibt ein großartiges Projekt namens git sh , das genau das tut (und noch viel mehr).