Je suis nouveau dans les scripts Shell et je ne peux pas comprendre cela. Si vous n'êtes pas familier, la commande git branch retourne quelque chose comme
* develop
master
, où l'astérisque marque la branche actuellement extraite. Lorsque j'exécute ce qui suit dans le terminal:
git branch | grep "*"
Je reçois:
* develop
comme prévu.
Cependant, quand je cours
test=$(git branch | grep "*")
ou
test=`git branch | grep "*"`
Puis
echo $test
, le résultat est juste une liste de fichiers dans le répertoire. Comment faire pour que la valeur de test = "* se développe"?
Ensuite, l'étape suivante (une fois que nous obtenons "* develop" en une variable appelée test), est d'obtenir la sous-chaîne. Serait-ce simplement le suivant?
currentBranch=${test:2}
Je jouais avec cette fonction de sous-chaîne et j'ai souvent eu des erreurs de "mauvaise substitution" et je ne sais pas pourquoi.
Le * est développé, ce que vous pouvez faire est d'utiliser sed au lieu de grep et d'obtenir immédiatement le nom de la branche:
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
avec $ test contenant "* master" puis le * est développé selon les règles d'expansion normales. Pour supprimer cela, il faudrait citer la variable, comme le montre marco: echo "$test"
. Alternativement, si vous vous débarrassez de l'astérisque avant de l'écho, tout ira bien, par exemple echo ${test:2}
fera simplement écho à "master". Vous pouvez également l'attribuer à nouveau comme vous l'avez déjà proposé:
branch=${test:2}
echo $branch
Cela fera écho à "master", comme vous le vouliez.
Développer sur réponse de Noufal Ibrahim , utilisez le --short
drapeau avec git-symbolic-ref
, pas besoin de s'occuper de sed
.
J'ai utilisé quelque chose comme ça 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 génère "**** Exécution du hook post-commit du maître de branche"
Notez que git-symbolic-ref
ne fonctionne que si vous êtes dans un référentiel. Heureusement .git/HEAD
, comme un reste des premiers jours de Git, contient la même référence symbolique. Si vous voulez obtenir la branche active de plusieurs référentiels git, sans parcourir les répertoires, vous pouvez utiliser un bash one-liner comme ceci:
for repo in */.git; do branch=$(cat $repo/HEAD); echo ${repo%/.git} : ${branch##*/}; done
Qui produit 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.
J'utiliserais le git-symbolic-ref
commande dans le noyau git. Si tu le dis git-symbolic-ref HEAD
, vous obtiendrez le nom de la branche actuelle.
J'utilise ce git describe --contains --all HEAD
dans mes scripts d'aide git
exemple:
#!/bin/bash
branchname=$(git describe --contains --all HEAD)
git pull --rebase Origin $branchname
Je l'ai dans un fichier appelé gpull
dans ~/scripts
pour de nombreux environnements CI, ils vérifieront votre code dans un état "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}"\
)
Le problème repose sur:
echo $test
En fait, le test de variable contient un caractère générique qui est développé par le Shell. Pour éviter cela, protégez simplement $ test avec des guillemets doubles:
echo "$test"
désactiver l'expansion de glob de subshell,
test=$(set -f; git branch)