Git 🌙
Chapters â–Ÿ 2nd Edition

10.5 Les tripes de Git - La refspec

La refspec

Tout au long de ce livre, nous avons utilisĂ© des associations simples entre les branches distantes et les rĂ©fĂ©rences locales. Elles peuvent ĂȘtre plus complexes. Supposons que vous ajoutiez un dĂ©pĂŽt distant comme ceci :

$ git remote add origin https://github.com/schacon/simplegit-progit

Cela ajoute une section au fichier .git/config, contenant le nom du dĂ©pĂŽt distant (origin), l’URL de ce dĂ©pĂŽt et la refspec pour la rĂ©cupĂ©ration :

[remote "origin"]
	url = https://github.com/schacon/simplegit-progit
	fetch = +refs/heads/*:refs/remotes/origin/*

Le format de la refspec est un + facultatif, suivi de <src>:<dst>, oĂč <src> est le motif des rĂ©fĂ©rences du cĂŽtĂ© distant et <dst> est l’emplacement local oĂč les rĂ©fĂ©rences seront enregistrĂ©es. Le + prĂ©cise Ă  Git de mettre Ă  jour la rĂ©fĂ©rence mĂȘme si ce n’est pas une avance rapide.

Dans le cas par dĂ©faut, qui est celui d’un enregistrement automatique par la commande git remote add origin, Git rĂ©cupĂšre toutes les rĂ©fĂ©rences de refs/heads/ sur le serveur et les enregistre localement dans refs/remotes/origin/. Ainsi, s’il y a une branche master sur le serveur, vous pouvez accĂ©der localement Ă  l’historique de cette branche via :

$ git log origin/master
$ git log remotes/origin/master
$ git log refs/remotes/origin/master

Ces syntaxes sont toutes équivalentes, car Git les développe en refs/remotes/origin/master.

Si vous préférez que Git récupÚre seulement la branche master et non chacune des branches du serveur distant, vous pouvez remplacer la ligne fetch par :

fetch = +refs/heads/master:refs/remotes/origin/master

C’est la refspec par dĂ©faut de git fetch pour ce dĂ©pĂŽt distant. Si l’on veut effectuer une action particuliĂšre une seule fois, la refspec peut aussi ĂȘtre prĂ©cisĂ©e en ligne de commande. Pour tirer la branche master du dĂ©pĂŽt distant vers la branche locale origin/mymaster, vous pouvez exĂ©cuter :

$ git fetch origin master:refs/remotes/origin/mymaster

Vous pouvez indiquer plusieurs refspecs. En ligne de commande, vous pouvez tirer plusieurs branches de cette façon :

$ git fetch origin master:refs/remotes/origin/mymaster \
	 topic:refs/remotes/origin/topic
From git@github.com:schacon/simplegit
 ! [rejected]        master     -> origin/mymaster  (non fast forward)
 * [new branch]      topic      -> origin/topic

Dans ce cas, la rĂ©cupĂ©ration (pull) de la branche master a Ă©tĂ© refusĂ©e car ce n’était pas une avance rapide. On peut surcharger ce comportement en prĂ©cisant un + devant la refspec.

On peut aussi indiquer plusieurs refspecs pour la récupération, dans le fichier de configuration. Si vous voulez toujours récupérer les branches master et experiment, ajoutez ces deux lignes :

[remote "origin"]
	url = https://github.com/schacon/simplegit-progit
	fetch = +refs/heads/master:refs/remotes/origin/master
	fetch = +refs/heads/experiment:refs/remotes/origin/experiment

Vous ne pouvez pas utiliser des jokers partiels, ce qui suit est donc invalide :

fetch = +refs/heads/qa*:refs/remotes/origin/qa*

On peut toutefois utiliser des espaces de noms (namespaces) ou des rĂ©pertoires pour accomplir cela. S’il existe une Ă©quipe qualitĂ© (QA) qui publie une sĂ©rie de branches et que l’on veut la branche master, les branches de l’équipe qualitĂ© et rien d’autre, on peut utiliser la configuration suivante :

[remote "origin"]
	url = https://github.com/schacon/simplegit-progit
	fetch = +refs/heads/master:refs/remotes/origin/master
	fetch = +refs/heads/qa/*:refs/remotes/origin/qa/*

Si vous utilisez des processus complexes impliquant une équipe qualité, des développeurs et des intégrateurs qui publient des branches et qui collaborent sur des branches distantes, vous pouvez facilement utiliser des espaces de noms de cette façon.

Pousser des refspecs

Il est pratique de pouvoir rĂ©cupĂ©rer des rĂ©fĂ©rences issues d’espace de nom de cette façon, mais comment l’équipe qualitĂ© insĂšre-t-elle ces branches dans l’espace de nom qa/ en premier lieu ? On peut accomplir cela en utilisant les spĂ©cifications de rĂ©fĂ©rences pour la publication.

Si l’équipe qualitĂ© veut publier sa branche master vers qa/master sur le serveur distant, elle peut exĂ©cuter :

$ git push origin master:refs/heads/qa/master

Si elle veut que Git le fasse automatiquement à chaque exécution de git push origin, elle peut ajouter une entrée push au fichier de configuration :

[remote "origin"]
	url = https://github.com/schacon/simplegit-progit
	fetch = +refs/heads/*:refs/remotes/origin/*
	push = refs/heads/master:refs/heads/qa/master

De mĂȘme, cela fera que, par dĂ©faut, git push origin publiera la branche locale master sur la branche distante qa/master.

Note

Vous ne pouvez pas utiliser la refspec pour récupérer les modifications depuis un dépÎt et pousser sur un autre. Pour voir un exemple de comment faire cela, référez-vous à Garder votre dépÎt GitHub public à jour.

Supprimer des références

Vous pouvez aussi utiliser les refspecs pour supprimer des références sur le serveur distant en exécutant une commande comme :

$ git push origin :topic

La refspec ressemble à <src>:<dst>, mais en laissant vide la partie <src>, cela signifie une création de la branche à partir de rien et donc sa suppression.

Ou vous pouvez utiliser la nouvelle syntaxe (disponible depuis Git v1.7.0) :

$ git push origin --delete topic
scroll-to-top