wake-up-neo.net

Wie programmgesteuert der ausgecheckte Git-Zweig ermittelt werden

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?

249
JasonSmith

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.

279
Jakub Narębski

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.

176

sie können git name-rev --name-only HEAD verwenden.

41
jonny

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.

33
Johnny Utahh

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";
}

Benutzen:

branch_name=`get_branch`;
echo $branch_name;
18
fitorec

anpassung der akzeptierten Antwort an Windows-Powershell:

Split-Path -Leaf (git symbolic-ref HEAD)
9
tjb

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
8
muhammed basil

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/'
6
August Lilleaas

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
4
silvansky

Folgendes mache ich:

git branch | sed --quiet 's/* \(.*\)/\1/p'

Die Ausgabe würde so aussehen:

$ git branch | sed --quiet 's/* \(.*\)/\1/p'
master
$
4
JasonSmith

Ich versuche hier für die einfachste und selbsterklärendste Methode:

git status | grep "On branch" | cut -c 11-
4
tonywoode

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

2
polypus74

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
2
Peter Hart

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. 

https://git-scm.com/docs/git-status

2
Tony Baguette

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)"
2
qneill

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
            }

`` `

1
ravikanth

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.

0
Steve Childs

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.

0
Kenney

Gleiche Ergebnisse wie akzeptierte Antwort in einer einzeiligen Variablenzuordnung:

branch_name=$((git symbolic-ref HEAD 2>/dev/null || echo "(unnamed branch)")|cut -d/ -f3-)
0
Kim Taylor

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).

0
Damien MATHIEU