138 votes

Comment parcourir toutes les branches de git en utilisant le script bash

Comment puis-je parcourir toutes les branches locales dans mon référentiel à l'aide de scripts bash. J'ai besoin pour faire évoluer et vérifier quelle est la différence entre la direction générale et de certaines branches distantes. Ex

for branch in $(git branch); 
do
    git log --oneline $branch ^remotes/origin/master;
done

J'ai besoin de faire quelque chose comme donné ci-dessus, mais la question que je me pose est de $(git branch) me donne les dossiers à l'intérieur du dépôt du dossier avec les branches présentes dans le référentiel.

Est-ce la bonne façon de résoudre ce problème? Ou est-il un autre moyen de le faire?

Merci

196voto

Chris Johnsen Points 50064

Vous ne devez pas utiliser git branch lors de l'écriture de scripts. Git fournit un "plomberie" de l'interface qui est explicitement conçu pour une utilisation dans des scripts (de nombreux courants et historiques des implémentations de la normale commandes Git (ajouter, de caisse, de fusion, etc.) utilisez cette même interface).

La plomberie de commande que vous voulez est de git pour-chaque-ref:

git for-each-ref --shell \
  --format='git log --oneline %(refname) ^origin/master' \
  refs/heads/

Remarque: Vous n'avez pas besoin de l' remotes/ préfixe sur la télécommande réf sauf si vous avez d'autres refs qui causent origin/master pour correspondre à de multiples endroits dans le ref de recherche de nom de chemin d'accès (voir "symbolique ref nom. ..." dans la Spécification des Révisions de la section de git-rev-parse(1)). Si vous essayez de explicitement éviter toute ambiguïté, puis aller avec la pleine ref name: refs/remotes/origin/master.

Vous obtenez un résultat comme ceci:

git log --oneline 'refs/heads/master' ^origin/master
git log --oneline 'refs/heads/other' ^origin/master
git log --oneline 'refs/heads/pu' ^origin/master

Vous pouvez rediriger cette sortie en sh.

Si vous n'aimez pas l'idée de produire de la coquille de code, vous pouvez donner un peu de robustesse* et de faire cela:

for branch in $(git for-each-ref --format='%(refname)' refs/heads/); do
    git log --oneline "$branch" ^origin/master
done

* Ref noms devraient être à l'abri de l'environnement, de couper un mot (voir git-check-ref-format(1)). Personnellement je m'en tiendrais à l'ancienne version (généré shell code); je suis plus confiant que rien ne inapproprié peut arriver avec elle.

Depuis que vous avez spécifié bash et qu'il supporte les tableaux, vous pouvez maintenir la sécurité et encore éviter de générer les entrailles de votre boucle:

branches=()
eval "$(git for-each-ref --shell --format='branches+=(%(refname))' refs/heads/)"
for branch in "${branches[@]}"; do
    # …
done

Vous pourriez faire quelque chose de similaire avec $@ si vous n'êtes pas en utilisant un shell qui prend en charge les tableaux (set -- d'initialiser et d' set -- "$@" %(refname) d'ajouter des éléments).

58voto

Matthew Slattery Points 21628

En effet, git branch marque la branche actuelle d’un astérisque, par exemple:

 $ git branch
* master
  mybranch
$ 
 

so $(git branch) développe, par exemple * master mybranch , puis les * développent vers la liste des fichiers du répertoire en cours.

Je ne vois pas d'option évidente pour ne pas imprimer l'astérisque en premier lieu; mais vous pouvez le couper:

 $(git branch | cut -c 3-)
 

3voto

Xin Guo Points 515

Je suggérerais $(git branch|grep -o "[0-9A-Za-z]\+") si vos succursales locales sont nommées avec des chiffres, des lettres az et / ou des lettres AZ uniquement

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