121 votes

Comment obtenir le nom de la branche git actuelle dans une variable d'un shell script ?

Je suis novice en matière de scripts shell et je n'arrive pas à comprendre ce qui se passe. Si vous n'êtes pas familier, la commande git branch retourne quelque chose comme

* develop
  master

où l'astérisque indique la branche actuellement extraite. Lorsque j'exécute la commande suivante dans le terminal :

git branch | grep "*"

Je reçois :

* develop

comme prévu.

Cependant, lorsque j'exécute

test=$(git branch | grep "*")

ou

test=`git branch | grep "*"`

Et puis

echo $test

le résultat n'est qu'une liste de fichiers dans le répertoire. Comment définir la valeur de test="* develop" ?

L'étape suivante (une fois que nous avons obtenu "* develop" dans une variable appelée test) consiste à obtenir la sous-chaîne. Est-ce que ce serait simplement ce qui suit ?

currentBranch=${test:2} 

J'ai joué avec cette fonction substring et j'ai eu beaucoup d'erreurs de "mauvaise substitution" et je ne sais pas pourquoi.

132voto

joemaller Points 2349

Élargir le champ d'action Réponse de Noufal Ibrahim , utiliser le --short drapeau avec git-symbolic-ref pas besoin de se préoccuper de sed .

J'ai utilisé quelque chose de ce genre dans les crochets et cela fonctionne bien :

#!/bin/bash

branch=$(git symbolic-ref --short HEAD)

echo
echo "**** Running post-commit hook from branch $branch"
echo

Cela donne "**** Running post-commit hook from branch master"

Il convient de noter que git-symbolic-ref ne fonctionne que si vous êtes dans un référentiel. Heureusement .git/HEAD La version anglaise de Git, vestige des premiers jours de Git, contient la même réf. symbolique. Si vous voulez obtenir la branche active de plusieurs dépôts git, sans avoir à parcourir les répertoires, vous pouvez utiliser une ligne de commande bash comme celle-ci :

for repo in */.git; do branch=$(cat $repo/HEAD); echo ${repo%/.git} :  ${branch##*/}; done

Ce qui donne quelque chose comme :

repo1 : master  
repo2 : dev  
repo3 : issue12

Si vous voulez aller plus loin, la référence complète contenue dans .git/HEAD est également un chemin relatif vers un fichier contenant le hachage SHA-1 du dernier commit de la branche.

130voto

wich Points 7276

Le * est développé, ce que vous pouvez faire est d'utiliser sed au lieu de grep et d'obtenir le nom de la branche immédiatement :

branch=$(git branch | sed -n -e 's/^\* \(.*\)/\1/p')

Et une version utilisant git symbolic-ref, comme suggéré par Noufal Ibrahim

branch=$(git symbolic-ref HEAD | sed -e 's,.*/\(.*\),\1,')

Pour élaborer sur l'expansion, (comme marco l'a déjà fait), l'expansion se produit dans l'écho, lorsque vous faites echo $test con $test contenant * master puis le * est développée selon les règles normales d'expansion. Pour supprimer cela, il faudrait citer la variable, comme l'a montré marco : echo "$test" . Alternativement, si vous vous débarrassez de l'astérisque avant de faire l'écho, tout ira bien, par exemple echo ${test:2} se contentera d'afficher master . Vous pouvez également l'attribuer à nouveau, comme vous l'avez déjà proposé :

branch=${test:2}
echo $branch

L'écho sera le suivant master comme vous le souhaitiez.

38voto

Noufal Ibrahim Points 32200

J'utiliserais le git-symbolic-ref dans le noyau git. Si vous dites git-symbolic-ref HEAD vous obtiendrez le nom de la branche en cours.

23voto

NullVoxPopuli Points 7081

J'utilise ceci git describe --contains --all HEAD dans mon aide git scripts.

exemple :

#!/bin/bash
branchname=$(git describe --contains --all HEAD)
git pull --rebase origin $branchname

Je l'ai placé dans un fichier appelé gpull en ~/scripts

Editer :

pour beaucoup d'environnements de CI, ils vérifieront votre code dans un état de "tête détachée", alors j'utiliserai :

BRANCH=$(\
  git for-each-ref \
  --format='%(objectname) %(refname:short)' refs/heads \
  | awk "/^$(git rev-parse HEAD)/ {print \$2}"\
)

7voto

marco Points 1678

Le problème repose sur :

echo $test

En fait, la variable test contient un joker qui est développé par l'interpréteur de commandes. Pour éviter cela, il suffit de protéger $test par des guillemets doubles :

echo "$test"

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X