git in a nutshell Part 2

Comme je l’avais promis dans mon court billet de dimanche dernier, mon ami Grégory nous offre le deuxième volet du tutoriel consacré à Git.
Dans le cas où vous auriez malencontreusement loupé la première partie consacrée à l’utilisation générale de Git, ou que vous souhaitiez tout simplement le relire pour le plaisir: http://www.pierreschambacher.com/blog/git-in-a-nutshell/

Relire le premier billet ne serait d’ailleurs pas idiot puisqu’il y a eu quelques ajouts dans le tutoriel précédents (stashs, hooks, alias).

Système de version décentralisé vs centralisé ?

La puissance d’un modèle décentralisé à la git c’est justement qu’il n’est pas figé. En effet il peut aussi bien être utilisé avec un dépôt local unique, avec une multitude de dépôts locaux, ainsi qu’avec un dépôt central… ou la combinaison de tous ces modes, tandis qu’avec un dépôt central unique on ne peut changer de modèle. Si on rajoute la facilité d’utilisation et la rapidité des opérations, il n’y a plus de raisons d’aller voir ailleurs ! Bien sûr on pourra toujours critiquer les aspects de configurations à mettre en place pour un mode centralisé, mais quand on achète une Ferrari il faut aussi apprendre à la conduire.

Commandes de base

L’utilisation en mode centralisé est aussi simple, côté client, que l’utilisation générale de Git. Pour ainsi dire il n’y a que 4 commandes importantes :

  • clone
  • remote
  • pull
  • push

clone

git clone dépôt_distant [dossier]

Permet de récupérer un dépôt distant dans dossier. Les protocoles supportés sont : rsync, http, https, git, ssh, file. Les fichiers étant compressés et empaquetés un checkout est donc très rapide comparé à un svn qui va tout télécharger unitairement !
Par défaut la référence au projet distant sera « origin » (voir remote).

Remote

Cette commande permet de gérer les dépôts distants :

Lister les références aux dépôts distants :

git remote [-v]

Ajouter la référence nom à un dépôt distant. Dans le cas de clone, origin référencera le dépôt distant :

git remote add nom dépôt_distant

Supprimer une référence

git remote rm reference

Renommer une référence :

git remote rename ancienne_ref nouvelle_ref

Modifier une référence

git remote set-url reference nouvelle_adresse

Afficher les informations d’une référence

git show reference

pull

git pull [--rebase] reference branche

Cette commande est équivalent à un checkout de svn. On va récupérer l’état actuel de la branche distante. Le paramètre ‘reference’ est la référence que nous avons manipulé avec la commande remote. Par défaut on utilise origin. Après le pull il y a un merge automatique, sauf avec l’option –rebase qui permet de revenir à la version exacte du serveur (équivalent à un reset –hard de la version sur le serveur).

push

git push reference branch

git push –tags dépôt

Cette Commande est l’inverse de pull, elle permet d’envoyer ses modifications sur le serveur. C’est l’équivalent d’un checkin de svn.
L’option –tags permet d’envoyer la liste de tous tags locaux. Pour n’envoyer qu’un seul tag on procède comme suit :

git push reference tag NomDuTag

Cycle de vie des commandes

Un petit exemple vaut mieux qu’un long discours :

Initialisation

git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git linux

ou

git init linux
cd linux
git remote add origin git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
git pull origin master

Ensuite on fait des modifications comme vu dans le tutoriel précédent avec la puissance d’un gestionnaire de version décentralisé.

Pour se resynchroniser avec le serveur :

git commit -a
git pull origin master

Puis on pousse nos modifications sur le serveur :

git push origin master

Simple non ?

On est mal barrés !

Les dépôts distants sont généralement crées avec l’option –bare et se terminent par .git

git init –bare dossier.git

Un dépôt de type « bare » est en fait un dépôt sans espace de travail (working directory), ainsi il n’y a pas directement les fichiers sources mais uniquement le contenu du dossier .git. Cela empêche l’utilisation de certaines commandes (git add, git rm, git commit …).

Supprimer une référence distante

Il peut être utile de supprimer à distance une branche ou un tag. Pour se faire il suffit d’ajouter « : » avant la référence à supprimer. En théorie lors de la spécification d’une référence on devrait la noter +ref_locale:ref_distante, donc si on omet la référence locale il y aura suppression. La syntaxe de git permet de se passer du « + » et du « : » comme dans l’exemple.

Supprimer un tag distant :

git push –tags origin :TagASupprimer

Supprimer une branche distante :

git push origin :MaBranche

Pour lister les références distantes, on utilise la commande :

git ls-remote [--heads] [--tags] reference

Exporter un dépôt sur le réseau

Le site http://www.jedi.be/blog/2009/05/06/8-ways-to-share-your-git-repository (in English, sorry) liste les différentes façons d’exporter les dépôts git.
La version maison est un démon intégré à git qui écoute sur le port 9418 par défaut, il va scanner les dossiers de sa liste blanche et s’il détecte le fichier « git-daemon-export-ok » dans le .git du dépôt, alors celui-ci sera exporté.

git daemon [--export-all] [--base-path=path][--user-path] [--reuseaddr] [directory…]

    –export-all exporte tous les dépôts que le fichier « git-daemon-export-ok » soit présent ou non
    –base-path permet d’indiquer le répertoire de base des dépôts
    –user_path permet d’utiliser la notation ~user dans l’adresse de git clone
    –reuseaddr permet de pouvoir se lier au port même s’il est déjà utilisé (après un crash en général)

On peut spécifier ensuite les répertoires de la liste blanche (en plus de –base-path). On peut utiliser un démarrage manuel ou un service comme inetd.

Contrôle d’accès au dépôt

Et bien c’est simple, git n’intègre pas de mécanisme de contrôle d’accès aux dépôts ! C’est un gestionnaire de version, il laisse donc ce travail à d’autres couches systèmes spécialisées. Mais ceci vient aussi du fait que le mode décentralisé est celui par défaut, donc si quelqu’un a fait une modification dans le code de Linux, il va demander à Linus de faire un pull de ses modifications. Dans ce schéma il n’y a pas besoin d’intégrer des mécanismes de sécurité divers et variés.
Néanmoins il existe des solutions.

  • Pour http(s), on peut utiliser l’authentification intégrée (voir liée à un LDAP)
  • Pour un système de fichier on a toute la gestion des droits intégrée au système (un peu lourd à mettre en place)
  • Idem pour ssh, mais cela nécessite en plus de créer des comptes ssh sur le serveur

Néanmoins la solution la plus pratique est Gitosis. Avec Gitosis il n’est nécessaire de créer qu’un seul compte sur la machine « git », chaque utilisateur est authentifié par sa clé ssh (clé unique, authentification forte) et les dépôts peuvent avoir un accès lecture seule ou lecture/écriture.
Pour modifier la configuration de Gitosis, on fait un pull du projet gitosis-admin, on obtient l’arborescence suivante :

  • keydir dossier qui contient les fichiers de clés ssh publiques (.pub) de tous les utilisateurs
  • gitosis.conf fichier qui contient la configuration des dépôts

Ensuite modifications, commit, push comme vu plus haut.
Les dépôts contrôlés par Gitosis sont situés dans /home/git/repositories, mais rien n’empêche de faire des liens symbolique pour les stocker ailleurs.
Exemple de fichier de configuration :

[gitosis]
## Autoriser gitweb à montrer tous les dépôts
gitweb = no

## Autoriser git-daemon à publier tous les dépôts
daemon = no

[group quux]
members = jdoe wsmith @anothergroup
writable = repo1 repo2
readonly = repo3

[group anothergroup]
members = alice bill

[repo foo]
## Configuration par dépôt au lieu de la configuration globale pour gitweb (idem pour git daemon)
gitweb = yes

On définit des groupes avec des membres et les dépôts auxquels ils peuvent accéder en lecture seule ou lecture/écriture. La syntaxe de contrôle est inversée par rapport à ce qu’on a l’habitude de voir : un dépôt ne définit pas ses permissions, c’est un groupe qui définit ses accès.
Le seul défaut de Gitosis est que la granularité des accès se font au niveau du dépôt complet (y compris pour les tags). Pour avoir un contrôle plus fin on sera obligé de passer par des hooks (le hook update en l’occurrence) ou de se tourner vers Gitolite qui a un comportement identique avec la possibilité de définir précisément les droits d’accès.

Pour accéder à un dépôt on procède de la manière suivante :

git clone git@serveur:repo1

Creative Commons License
Tutoriel GIT by Grégory Soutadé est mis à disposition selon les termes de la licence Creative Commons Paternité-Partage des Conditions Initiales à l’Identique 2.0 France.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

*

Vous pouvez utiliser ces balises et attributs HTML : <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>