Git, les mains dans le cambouis
Signature : | Mis en ligne le : 17/02/2009
Catégorie(s) :
  • GNU/Linux Magazine
  • | Domaine :
    Commentez creative commons

     Retrouvez cet article dans : Linux Magazine 103

    1. Préambule

    1.1 Rappel des faits, synopsis de l’épisode

    Vous avez donc vu (malgré quelques soucis de mise en page) dans le numéro 101 que Git n’est pas si difficile que ça à prendre en mains et à utiliser. Dans le précédent épisode, Max avait donc découvert (pêle-mêle) :
    • les commandes liées aux commits : git add, git status, git diff, git commit, git revert ;
    • les commandes liées aux branches : git branch branch, git checkout branch, git merge branch ;
    • les commandes liées à la création d’un dépôt public en utilisant un serveur HTTP : git clone -bare depot depot.git, git push ;
    • les commandes pour suivre un dépôt distant : git clone depot, git branch -a, git remote depot url, git fetch, git pull.
    Dans celui-ci, nous verrons :
    • la création d’un dépôt public avec git-daemon ;
    • comment trouver un mauvais commit avec git bisect ;
    • la résolution de conflits ;
    • des exemples réels d’utilisation.
    Il s’agit là de sujets un peu plus poussés que les précédents et d’approfondissements demandés par des lutins. À nouveau, rien de bien sorcier. Je n’ai fait que lire, tester et utiliser ce qui se trouve dans les man pages et la documentation de Git (http://www.kernel.org/pub/software/scm/git/docs/user-manual.html).

    2. Acte 1 : git-daemon

    Un dépôt sur un serveur HTTP est relativement simple à mettre en place et probablement plus pratique. Cependant, le protocole git est conçu de manière à être plus efficace en termes de performances et de fiabilité. De plus, il permet de faire un serveur de dépôts plus souple qu’avec un serveur HTTP, pratique dans le cas d’un serveur dédié à ça (enfin, à mon humble avis).

    2.1 Préparation des ingrédients

    Pour mettre en place ce serveur, il vous faut :
    • 2 œufs ;
    • 100 grammes de farine ;
    • Git installé sur le serveur ;
    • sshd fonctionnel sur le serveur ;
    • Git installé sur le client (si, si, je vous assure).
    Comme pour le dépôt sur HTTPd, il vous faut préparer le sachet prêt à l’emploi : Remarquez la création (via touch) du fichier git-daemon-export-ok, fichier qui, par sa présence, indique à git-daemon qu’il peut effectivement rendre accessible ce dépôt. Ce répertoire obtenu, il vous faut le copier sur votre serveur dans le répertoire qui va accueillir tous les dépôts, servir de root pour votre git-daemon.

    2.2 Serveur basique

    Des fois, on a envie de tester rapidement un truc, faire quelque chose en 5 minutes sur un coin de table (chacun son truc) et, pour ça, il faut pouvoir mettre rapidement en place certaines choses. Dans ces cas-là donc, on ne veut pas s’embarrasser d’un régiment d’options, juste ce qu’il faut pour que ça marche. Du coup, sur le client : C’est tout. Par défaut, git-daemon utilise le port 9148, et écoute sur localhost. Notez que si vous avez un support IPv6 actif, il peut refuser la connexion sur 127.0.0.1, mais l’accepter sur ::1 (allez savoir…). Notez aussi l’utilisation de git:// et non http:// lors du clonage depuis le client. L’option —base-path permet de simplifier le chemin passé dans l’URL de clonage : les clients n’ont pas à taper le chemin entier depuis la racine de votre serveur, mais simplement le chemin vers le dépôt dans votre root git-daemon. L’option —listen permet de définir une IP sur laquelle le serveur va écouter. Vous avez donc de quoi mettre un dépôt public en deux minutes.

    2.3 Quelques options

    2.3.1 Changement de port

    L’option —port=?? permet d’indiquer un port différent : cette option n’est pas compatible avec l’option —inetd.

    2.3.2 Logs

    L’option —verbose rendra le serveur plus verbeux dans ses logs qu’ils soient sur stderr ou, avec l’utilisation de l’option —syslog, dans syslog.

    2.3.3 En background

    L’option —detach indique à git-daemon de passer en background une fois lancé : cela implique l’option —syslog.

    2.3.4 Sans stress

    Si vous voulez aller plus vite et zapper l’étape de création du fichier git-daemon-export-ok dans vos dépôts, il vous suffit d’utiliser l’option —export-all pour ne plus y penser. Git-daemon exportera tout ce qui ressemble à un dépôt.

    2.3.5 Utilisateur et groupe

    Si vous voulez que git-daemon fonctionne sous un utilisateur et un groupe particulier, il suffit d’utiliser les options —user=user et —group=group.

    2.4 Hôtes virtuels

    Si vous aimez les hôtes virtuels pour les serveurs http, vous apprécierez peut être que git-daemon sache aussi faire ça. L’option —interpolated-path=pathtemplate permet cela via une syntaxe, comment dire… simple ? Oui sûrement. Disons donc que nous avons deux hôtes virtuels à servir : git.jardin.ca et git.librium.org. On crée donc un répertoire /var/depots, dans celui-ci un répertoire par hôte et dans ceux-ci un répertoire projets (histoire de) : Reste le plus dur, la commande avec les options au poil. Reprenons la base précédente : git-daemon —base-path=/var/depots —listen=vo.tr.e.ip mais sans —base-path désormais inutile. On va y rajouter une dose d’armagnWW de magie avec l’option —interpolated-path. Celle-ci utilise une syntaxe charmante avec des % partout :
    • %H pour le hostname ;
    • %CH pour canonical hostname ;
    • %IP pour l’IP (on aurait donc pu utiliser des IP en lieu et place des noms d’hôtes dans l’étape précédente) ;
    • %P pour le port ;
    • %D pour le chemin vers les dépôts.
    Comme disait un de mes profs d’élec’, " un schéma vaut mieux que des longs discours " : N’oubliez pas de spécifier le path absolu avant %H et %D, sinon vous risquez de patauger un peu avant de faire marcher la chose. Vos clients n’ont alors qu’à cloner comme ils le font d’habitude. Par exemple, pour les projets projet_A, et froggy, situés respectivement sur git.jardin.ca et git.librium.org :

    2.5 Inetdisation ?

    Oui, les agités du fond de la salle qui veulent savoir si on peut utiliser git-daemon avec inetd peuvent se rassurer, c’est possible. On peut utiliser quasiment toutes les options précédemment vues : il suffit de mettre la commande suivante dans  /etc/inetd, le tout sur une seule ligne :

    2.6 Oui enfin, cloner, cloner…

    Oui, cloner ne fait pas tout et il faut effectivement pouvoir pousser vers le serveur pour que ce soit efficace. Mais git-daemon ne gère pas l’écriture, seulement la lecture : il vous faut donc utiliser un autre accès au serveur pour ça (ssh par exemple comme vu dans le numéro 101) :

    2.7 Résumé de l’acte

    Cet acte se finit donc avec de quoi faire un serveur relativement robuste pour publier vos projets et ceux de vos amis. Rappelons rapidement les commandes importantes.
    • un serveur de base : git-daemon —base-path=/var/depots —listen=vo.tr.e.ip ;
    • un serveur avec support d’hôtes virtuels : git-daemon —listen=vo.tr.e.ip —verbose —interpolated-path=/var/depots/%H%D /var/depots/git.jardin.ca/projets /var/depots/git.librium.org/projets.

    3. Acte 2 : conflits

    Sujet qui m’a été demandé et qui, il est vrai, fut bien succinctement traité dans le précédent article. En effet, un des " soucis " que l’on peut avoir, lorsqu’on utilise des branches et des branches pour tester des choses (vous savez, une veille de partiels, quand vous vous dites que vous recoderiez bien la moitié d’une bibl…), c’est que lorsqu’on réintègre ça dans la branche master, ça risque de coincer. Alors évidemment, on n’appelle surtout pas un détachement de la Légion pour supprimer les conflits qui sont apparus, on va y aller doucement avec nos deux seuls alliés : Git et votre éditeur favori. Commençons donc par pondre une tartine de code pas très jolie : on va faire ça en Perl parce que c’est un langage que j’aime bien et qu’il est relativement répandu. Le script en lui-même n’a que peu d’importance, mais, pour vous aider à suivre si vous ne lisez par le Perl couramment, il s’agit d’un script qui lit le /etc/passwd et affiche son contenu. Tout d’abord, voici la version dans la branche master : Et voici la version de la branche monoline (on se souvient que la commande git checkout branche permet de passer d’une branche à une autre) : Lorsqu’on effectue le merge de la branche monoline dans la branche master, voici ce qui se passe : On a donc tout cassé. Regardons plus attentivement : On voit ici que git a mergé ce qu’il pouvait (la fonction affichage), mais qu’il a ensuite buté sur le conflit auquel on s’attendait. Nous retrouvons donc les lignes qui posent problème, avec la version de chaque branche séparée de l’autre. La première correspond à la version de la branche master (HEAD) dans laquelle nous avons essayé de merger la deuxième version de la branche monoline. Il faut alors résoudre à la main : Il ne reste plus qu’à commiter :

    3.1 Résumé de l’acte

    D’une manière générale, git sait gérer et merger tout seul pas mal de choses. Cependant, il vous faut parfois (quand c’est vraiment conflictuel) ouvrir la trappe et aller régler les comptes à la main. Pas besoin de se demander s’il faut passer un flag à git avant de commiter les fichiers résolus, un commit suffit.

    4. Acte 3 : la mort du colonel

    L’autre outil super utile est la commande bisect. Elle permet de trouver quel commit a tout pété dans votre projet. En clair : quel patch (et donc qui) a mis le souk (ou qui a tué le colonel Moutarde) ?. Quoi que vous fassiez, votre code ne passe plus, et vous ne trouvez pas non plus qui a rajouté le chandelier sur la table. Pas de souci : commencez par regarder les logs (0, un peu raccourcis), puis il vous suffit d’isoler la scène du crime (1), de vous rappeler quand le chandelier n’était pas sur la table (2), et enfin de constater la mort du colonel (3). La commande git bisect good peut prendre un tag ou un hash de commit comme argument. Si vous faites un git branch, vous verrez que git a créé une branche bisect pour réaliser ces tests. J’ai pris ici l’identifiant du premier commit que j’ai réalisé sur mon projet (au moins, je suis sûr que c’était bon). Cet identifiant est en fait un hash sha1 (donc unique). Lorsqu’on donne master comme référence mauvaise, git revient à un commit précédent, accessible depuis master, mais pas depuis mon premier commit. Il attend alors de savoir s’il est remonté suffisamment dans le passé pour retrouver un état ok de votre code ou pas. Comme ce n’est pas le cas, on va l’en informer grâce à la commande bisect bad : Il remonte alors de nouveau dans le passé. Disons que celui ci est bon : Au fur et à mesure des good et bad, vous devriez arriver au coupable. Ici, git a proposé le commit resolution du conflit, puis, comme il était mauvais, il est allé deux commits plus loin. Comme nous avons désigné ce commit là comme bon, le coupable ne pouvait qu’être celui qui est entre eux deux. Une fois ceci fait, vous pouvez retourner à votre environnement de travail initial via la commande :

    4.1 Résumé de l’acte

    Git bisect est donc un outil des plus utiles quand vous voulez traquer certains problèmes le long de vos commits. Il est fort appréciable notamment quand vous utilisez un script pour faire le test (si le script retourne 0, git considère que le code est bon ; s’il retourne entre 1 et 127, il considère qu’il n’est pas bon).
    • démarrage d’une session bisect : git bisect start ;
    • désignation du commit en bonne santé : git bisect good <rev> ;
    • désignation du commit en mauvaise santé connu : git bisect bad <red> ;
    • innocenter un commit : git bisect good ;
    • accabler un commit : git bisect bad ;
    • revenir dans un état normal : git bisect reset.

    5. Rideau

    Voilà, un deuxième volet de fini, il reste encore bien des choses à apprendre : les tags, des cas d’utilisation réelle, etc. Cette fois-ci, vous êtes prêt à tout ou presque, la documentation vous en dira évidemment plus si vous avez encore faim. À nouveau, je tiens à remercier lutins et barbus, surtout Don Lefinnois pour sa patience et son accueil, ainsi que son équipe (silencieuse)

     Retrouvez cet article dans : Linux Magazine 103

    Vous souhaitez commenter cet article ?
    Brèves Flux RSS
    Édito : GNU/Linux Magazine 149
    Édito : GNU/Linux Magazine HS N°60
    Édito : Misc 61
    Édito : Linux Pratique 71
    Édito : Linux Essentiel N°25
    Communication RSS Com. RSS Presse
    Lancement de la plateforme de vente en ligne de PDF des Éditions Diamond ! Un...
    Misc N°61 – Communiqué de presse
    GNU/Linux Magazine N°149 – Communiqué de presse
    GNU/Linux Magazine HS N°60 – Communiqué de presse
    Linux Pratique N°71 – Communiqué de presse
    prochainement moteur de recherches des articles
     
    :
    :
    Jours heures minutes secondes
    En kiosque Flux RSS

    Le tout nouveau GNU/Linux Magazine est disponible dès maintenant chez votre marchand de journaux et sur notre site marchand.

    Découvrez le sommaire de ce numéro et un aperçu de ce magazine...

    Lire la suite...

    Le tout nouveau Misc est disponible dès maintenant chez votre marchand de journaux et sur notre site marchand.

    Découvrez le sommaire de ce numéro et un aperçu de ce magazine...

    Lire la suite...

    Le tout nouveau Linux Pratique est disponible dès maintenant chez votre marchand de journaux et sur notre site marchand.

    Découvrez le sommaire de ce numéro et un aperçu de ce magazine...

    Lire la suite...

    Le tout nouveau GNU/Linux Magazine HS est disponible dès maintenant chez votre marchand de journaux et sur notre site marchand.

    Découvrez le sommaire de ce numéro et un aperçu de ce magazine...

    Lire la suite...

    Le tout nouveau Linux Essentiel est disponible dès maintenant chez votre marchand de journaux et sur notre site marchand.

    Découvrez le sommaire de ce numéro et un aperçu de ce magazine...

    Lire la suite...

    Le tout nouveau Misc HS est disponible dès maintenant chez votre marchand de journaux et sur notre site marchand.

    Découvrez le sommaire de ce numéro et un aperçu de ce magazine...

    Lire la suite...