Comment puis-je parcourir toutes les branches locales de mon référentiel en utilisant le script bash. Je dois itérer et vérifier s'il y a une différence entre la branche et certaines branches distantes. Ex
for branch in $(git branch);
do
git log --oneline $branch ^remotes/origin/master;
done
Je dois faire quelque chose comme indiqué ci-dessus, mais le problème auquel je suis confronté est que $ (git branch) me donne les dossiers à l'intérieur du dossier du référentiel avec les branches présentes dans le référentiel.
Est-ce la bonne façon de résoudre ce problème? Ou y a-t-il une autre façon de le faire?
Je vous remercie
for b in "$(git branch)"; do git branch -D $b; done
Réponses:
Vous ne devez pas utiliser git branch lors de l'écriture de scripts. Git fournit une interface de «plomberie» qui est explicitement conçue pour être utilisée dans les scripts (de nombreuses implémentations actuelles et historiques des commandes Git normales (ajout, extraction, fusion, etc.) utilisent cette même interface).
La commande de plomberie que vous voulez est git for-each-ref :
Remarque: Vous n'avez pas besoin du
remotes/
préfixe sur la référence distante, sauf si vous avez d'autres références qui fontorigin/master
correspondre plusieurs endroits dans le chemin de recherche du nom de référence (voir «Un nom de référence symbolique.…» Dans la section Spécification des révisions de git-rev-parse (1) ). Si vous essayez d'éviter l' ambiguïté explictly, puis aller avec le nom complet ref:refs/remotes/origin/master
.Vous obtiendrez une sortie comme celle-ci:
Vous pouvez diriger cette sortie dans sh .
Si vous n'aimez pas l'idée de générer le code shell, vous pouvez renoncer un peu à la robustesse * et faire ceci:
* Les noms de référence doivent être protégés du fractionnement des mots du shell (voir git-check-ref-format (1) ). Personnellement, je m'en tiendrai à l'ancienne version (code shell généré); Je suis plus convaincu que rien d'inapproprié ne peut en résulter.
Puisque vous avez spécifié bash et qu'il prend en charge les tableaux, vous pouvez maintenir la sécurité tout en évitant de générer les tripes de votre boucle:
Vous pouvez faire quelque chose de similaire avec
$@
si vous n'utilisez pas de shell prenant en charge les tableaux (set --
pour initialiser etset -- "$@" %(refname)
ajouter des éléments).la source
--merged
, devrais-je dupliquer la logique dans git branch? Il doit y avoir une meilleure façon de faire cela.git for-each-ref refs/heads | cut -d/ -f3-
git for-each-ref refs/heads --format='%(refname)'
for-each-ref
prend désormais en charge tous les sélecteurs de branche comme--merged
etgit branch
etgit tag
sont maintenant réellement implémentés engit for-each-ref
soi, au moins pour les cas de liste existants. (La création de nouvelles branches et balises ne fait pas et ne devrait pas faire partie defor-each-ref
.)C'est parce que
git branch
marque la branche actuelle avec un astérisque, par exemple:donc se
$(git branch)
développe par exemple* master mybranch
, puis le se*
développe à la liste des fichiers dans le répertoire courant.Je ne vois pas d'option évidente pour ne pas imprimer l'astérisque en premier lieu; mais vous pouvez le couper:
la source
$(git branch | sed -e s/\\*//g)
.3-
solution.$(git branch | sed 's/^..//')
$(git branch | tr -d " *")
Le bash builtin``
mapfile
est construit pour celatoutes les branches git:
git branch --all --format='%(refname:short)'
toutes les branches git locales:
git branch --format='%(refname:short)'
toutes les branches git distantes:
git branch --remotes --format='%(refname:short)'
itérer à travers toutes les branches git:
mapfile -t -C my_callback -c 1 < <( get_branches )
exemple:
pour la situation spécifique du PO:
source: liste toutes les branches git locales sans astérisque
la source
J'itère comme ça par exemple:
la source
Je suggérerais
$(git branch|grep -o "[0-9A-Za-z]\+")
que vos succursales locales soient nommées uniquement par des chiffres, des az et / ou des lettres AZla source
La réponse acceptée est correcte et devrait vraiment être l'approche utilisée, mais résoudre le problème dans bash est un excellent exercice pour comprendre le fonctionnement des coquilles. L'astuce pour faire cela en utilisant bash sans effectuer de manipulation de texte supplémentaire, est de s'assurer que la sortie de la branche git ne soit jamais développée dans le cadre d'une commande à exécuter par le shell. Cela empêche l'astérisque de s'étendre dans l'expansion du nom de fichier (étape 8) de l'expansion du shell (voir http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_03_04.html )
Utilisez la construction bash while avec une commande read pour découper la sortie de la branche git en lignes. Le '*' sera lu comme un caractère littéral. Utilisez une instruction case pour la faire correspondre, en accordant une attention particulière aux modèles correspondants.
Les astérisques dans la construction de cas bash et dans la substitution de paramètre doivent être échappés avec des barres obliques inverses pour empêcher le shell de les interpréter comme des caractères de correspondance de modèle. Les espaces sont également échappés (pour empêcher la tokenisation) car vous correspondez littéralement à «*».
la source
Option la plus facile à retenir à mon avis:
git branch | grep "[^* ]+" -Eo
Production:
L'option -o de Grep (--only-matching) limite la sortie aux seules parties correspondantes de l'entrée.
Étant donné que ni l'espace ni * ne sont valides dans les noms de branches Git, cela renvoie la liste des branches sans les caractères supplémentaires.
Edit: Si vous êtes dans l'état `` tête détachée '' , vous devrez filtrer l'entrée actuelle:
git branch --list | grep -v "HEAD detached" | grep "[^* ]+" -oE
la source
Ce que j'ai fini par faire, appliqué à votre question (et inspiré par ccpizza mentionnant
tr
):git branch | tr -d ' *' | while IFS='' read -r line; do git log --oneline "$line" ^remotes/origin/master; done
(J'utilise beaucoup les boucles while. Alors que pour des choses particulières, vous voudriez certainement utiliser un nom de variable pointé ["branche", par exemple], la plupart du temps, je ne me préoccupe que de faire quelque chose avec chaque ligne d'entrée. 'line' ici au lieu de 'branch' est un clin d'œil à la réutilisabilité / à la mémoire musculaire / à l'efficacité.)
la source
Dans le prolongement de la réponse de @ finn (merci!), Ce qui suit vous permettra de parcourir les branches sans créer de script shell intervenant. C'est assez robuste, tant qu'il n'y a pas de nouvelle ligne dans le nom de la branche :)
La boucle while s'exécute dans un sous-shell, ce qui est généralement bien, sauf si vous définissez des variables de shell auxquelles vous souhaitez accéder dans le shell actuel. Dans ce cas, vous utilisez la substitution de processus pour inverser le tuyau:
la source
Si vous êtes dans cet état:
Et vous exécutez ce code:
Vous obtiendrez ce résultat:
la source
for b in "$(git branch)"; do git branch -D $b; done
Rester simple
Le moyen simple d'obtenir le nom de la branche en boucle à l'aide du script bash.
Production:
la source
La réponse de Googlian, mais sans utiliser pour
la source
Cela utilise la plomberie git commandes de , qui sont conçues pour les scripts. C'est aussi simple et standard.
Référence: Achèvement de Git's Bash
la source