web-dev-qa-db-fra.com

Comment déterminer par programme la branche Git actuellement extraite

Dans un environnement de script Unix ou GNU (par exemple, une distribution Linux, Cygwin, OSX), quel est le meilleur moyen de déterminer quelle branche Git est actuellement extraite dans un répertoire de travail?

Une utilisation de cette technique consisterait automatiquement à étiqueter une version (comme le ferait svnversion avec Subversion).

Veuillez également vous reporter à la question connexe: Comment déterminer par programme si une extraction Git est une balise et, dans l’affirmative, quel est le nom de la balise?

249
JasonSmith

La bonne solution est de jeter un coup d’œil à contrib/complétions/git-completion.bash fait cela pour bash Prompt dans __git_ps1. Supprimer tous les extras, comme sélectionner comment décrire la situation détachée HEAD, c’est-à-dire que lorsque nous sommes sur une branche non nommée, c’est:

branch_name="$(git symbolic-ref HEAD 2>/dev/null)" ||
branch_name="(unnamed branch)"     # detached HEAD

branch_name=${branch_name##refs/heads/}

git symbolic-ref est utilisé pour extraire le nom de branche complet de la référence symbolique; nous l'utilisons pour HEAD, qui est actuellement extrait de la branche.

Une autre solution pourrait être:

branch_name=$(git symbolic-ref -q HEAD)
branch_name=${branch_name##refs/heads/}
branch_name=${branch_name:-HEAD}

où dans la dernière ligne nous traitons de la situation détachée HEAD, en utilisant simplement "HEAD" pour désigner une telle situation.


Ajouté le 11-06-2013

Article de blog de Junio ​​C. Hamano (mainteneur), Vérification programmée de la branche en cours , à partir du 10 juin 2013, explique pourquoi (et comment) en savoir plus détail.

266
Jakub Narębski

Est-ce que quelqu'un voit quelque chose de mal à demander simplement à Git de décrire la branche sur laquelle vous vous trouvez?

git rev-parse --symbolic-full-name --abbrev-ref HEAD

Cela peut être utilisé dans $ () et passé facilement dans Bash, Powershell, Perl, etc. Ce n'est pas dupe si vous avez plusieurs branches sur le commit, et si vous n'êtes pas actuellement sur une branche, c'est répond par "HEAD".

Alternativement, vous pouvez utiliser

git symbolic-ref --short -q HEAD

Ce qui vous donnera le même résultat, mais il ne retournera rien du tout si vous êtes détaché. Celui-ci est utile si vous voulez une erreur lorsque vous êtes détaché, supprimez simplement le -q.

176
Michael Erickson

vous pouvez utiliser git name-rev --name-only HEAD

41
jonny

Depuis cette réponse: https://stackoverflow.com/a/1418022/605356 :

$ git rev-parse --abbrev-ref HEAD
master

Apparemment, fonctionne avec Git 1.6.3 ou plus récent.

33
Johnny Utahh

Essayez avec:

 git symbolic-ref --short -q HEAD

Ou vous essayez avec git branch avec --no-color force la chaîne simple et simple de la sortie:

 git branch  --no-color

Avec grep en mode regex (-E), vous pouvez vérifier si le caractère '*' existe:

 git branch  --no-color  | grep -E '^\*' 

Les résultats sont similaires à:

* currentBranch

Vous pouvez utiliser les options suivantes:

sed 's/\*[^a-z]*//g'
cut -d ' ' -f 2
awk '{print $2}'

par exemple:

 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}'

s'il existe une erreur, vous ne pouvez pas utiliser une valeur par défaut:

  cmd || echo 'defualt value';

Tous dans une fonction bash:

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

Utilisation:

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

adapter la réponse acceptée à Windows PowerShell:

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

Celui-ci a fonctionné pour moi dans le fichier bash.

git branch | grep '^*' | sed 's/* //'  


################bash file###################
#!/bin/bash
BRANCH=$(git branch | grep '^*' | sed 's/* //' )
echo $BRANCH
8
muhammed basil

Celui-ci fonctionne pour moi. La partie --no-color est, ou peut être, importante si vous voulez une chaîne en retour.

git branch --no-color | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/'
6
August Lilleaas

J'ai trouvé deux manières très simples de faire cela:

$ git status | head -1 | cut -d ' ' -f 4

et

$ git branch | grep "*" | cut -d ' ' -f 2
4
silvansky

Voici ce que je fais:

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

La sortie ressemblerait à ceci:

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

J'essaie ici la méthode la plus simple et la plus explicite:

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

Voici ma solution, adaptée à une utilisation dans une PS1 ou à l’étiquetage automatique d’une version. 

Si vous êtes extrait dans une succursale, vous obtenez le nom de la succursale.

Si vous êtes dans un projet initié par Git, vous obtenez simplement '@'

Si vous êtes sans tête, vous obtenez un joli nom humain par rapport à une branche ou une étiquette, précédé du '@'.

Si vous êtes sans tête et que vous n'êtes pas l'ancêtre d'une branche ou d'un tag, vous obtenez simplement le court 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
}

Vous pouvez supprimer le bit if we_are_in_git_work_tree si vous le souhaitez. Je viens de l'utiliser dans une autre fonction de ma PS1 que vous pouvez visualiser en entier ici: Ligne PS1 avec branche et couleurs git actuelles

2
polypus74

Si vous utilisez l'ancienne ligne de commande NT, vous pouvez utiliser les éléments suivants:

@for /f "usebackq" %i in (`git symbolic-ref -q HEAD`) do @echo %~ni

Pour utiliser un fichier de commandes, vous devrez doubler les%:

@for /f "usebackq" %%i in (`git symbolic-ref -q HEAD`) do @echo %%~ni
2
Peter Hart

Utiliser --porcelain donne une sortie rétro-compatible facile à analyser:

git status --branch --porcelain | grep '##' | cut -c 4-

De la documentation:

Le format de la porcelaine est similaire au format court, mais il est garanti qu'il ne changera pas de manière incompatible avec les versions antérieures entre les versions de Git ou basé sur une configuration utilisateur. Cela le rend idéal pour l'analyse par des scripts. 

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

2
Tony Baguette

Quelqu'un a mentionné le faire à bash avec moins de trois tâches ... que diriez-vous d'un flux de contrôle désordonné comme celui-ci:

branch_name="$(b=$(git symbolic-ref -q HEAD); { [ -n "$b" ] && echo ${b##refs/heads/}; } || echo HEAD)"
2
qneill

Si vous utilisez Gradle,

`` `

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

Si vous êtes sur une tête isolée (c’est-à-dire que vous avez extrait une version) et que vous obtenez une sortie de git status 

HEAD detached at v1.7.3.1

Et vous voulez la version finale, nous utilisons la commande suivante ...

git status --branch | head -n1 | tr -d 'A-Za-z: '

Cela retourne 1.7.3.1, que nous remplaçons dans notre parameters.yml (Symfony) avec 

# 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

J'espère que cela vous aidera :) Évidemment, si le nom de votre branche contient des éléments non numériques, vous devrez modifier les arguments de la commande tr.

0
Steve Childs

J'ai trouvé que l'appel de git est plutôt lent (n'importe laquelle des sous-commandes), , En particulier pour la mise à jour de l'invite. Le temps varie entre 0,1 et 0,2 seconde dans le répertoire racine d'un référentiel et plus de 0,2 seconde en dehors d'un référentiel sur une machine de premier ordre (RAID 1, 8 Go de RAM, 8 threads matériels). Cogwin fonctionne cependant.

J'ai donc écrit ce script pour la rapidité:

#!/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;
                        s@ref: refs/heads/@@;
                        print $_;
                };
                exit;
        };

        $cwd=~s@/[^/]*$@@;
}

Peut-être besoin de quelques ajustements.

0
Kenney

Même résultat que la réponse acceptée dans une affectation de variable d'une ligne:

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

C'est une solution. Si vous l'ajoutez à votre fichier .bashrc, la branche actuelle sera affichée dans la console.

# git branch
parse_git_branch() {
    git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/(\1) /'
}
$PS1="\$(parse_git_branch)$PS1"

Cependant c'est assez limité. Mais il existe un grand projet appelé git sh , qui fait exactement cela (et bien plus encore).

0
Damien MATHIEU