grimboite/articles/dev/2014-08-02-workflow-git.md

6.4 KiB

Title Date Status Tags
Git 2014-08-02 draft git, vcs

Au plus j'utilise Git, au moins je peux m'en passer. J'ai commencé à utiliser un outil de contrôle de sources pendant un travail de groupe. Le but était de développer une petite application Web en SmallTalk, sous VisualWorks. Les assistants avaient déployé un service SVN, sur lequel on pouvait se connecter et déployer notre code source. Plus tard, durant mon parcours pro, on a également déployé un serveur SVN. On l'utilisait finalement de manière trèèès basique: quelques hooks, un serveur Trac, les commits de manière centralisée (et se gueuler dessus parce que quelqu'un avait foiré sa partie) et quelques tags. Par facilité, tous nos projets se trouvaient dans le même repository: plus besoin de jouer sur les dépendances, tout était au même endroit. Et puisqu'on jouait très peu avec les branches, forcément, ça clashait régulièrement.

Plus tard, je suis passé avec un collègue sur Git. On bossait chacun sur des projets différents, mais on avait quand même sérieusement besoin de pouvoir centraliser le code source. Finalement, c'est moins le côté partage de sources et plus le côté "ça m'a permis de gagner du temps" qui aura été bénéfique sur le long terme. Aujourd'hui encore, je bosse pratiquement uniquement avec Git. Mes textes sont sur Git, mes sources aussi. J'ai un compte Github (que j'utilise trop peu), un serveur perso, ... Et je jongle de plus en plus avec les branches, et bénis la facilité avec laquelle l'appli permet leur gestion.

Je vous épargnerai la création d'un nouveau repository... quoique... Bon allez, on recommence à zéro.

Pour initialiser un dépôt, il suffit de taper un petit git init dans le répertoire souhaité. Cela créera un répertoire .git, contenant toutes les informations nécessaires, notamment la configuration (dans le fichier .git/config).

une fois que c'est fait, tout reste en local. Aucun serveur distant n'est configuré. Pour y remédier, on va ajouter un git remote add origin <url du serveur>. Ceci permettra de synchroniser avec le serveur distant: il est dès lors très facile de définir plusieurs hôtes, de synchroniser des branches et fichiers depuis l'une de ces sources, et de les amener vers une autre. C'est notamment comme cela que fonctionne les pull requests sur Github:

  1. une personne (A) crée un repository;
  2. une deuxième (B) le clone et crée un deuxième repository basé sur le premier.
  3. A ce stade, les deux sont décorellés. Par contre, si B ajoute le premier repository comme hôte distant, il lui sera possible de se synchroniser sur le "maître".

Par exemple, je clone le repository orf/simple. Ceci crée un nouveau repository sous mon compte, baptisé de la même manière (grimbox/simple). Pour commencer à travailler sur ce code source, je vais le rappatrier en local :

git clone https://github.com/grimbox/simple.git

Par défaut, la fonction clone ajoute l'hôte sous la dénomination origin. Pour garder la synchronisation avec le repertoire maitre, je vais également l'ajouter sous la dénomination upstream (mais on pourrait l'appeler patate que ce serait pareil. C'est juste une convention).

git remote add upstream https://github.com/orf/simple.git

Ensuite, je vais créer une nouvelle branche dans mon code source, y travailler, et soumettre une pull request.

	git checkout -b new_branch
	...
	git add .
	git commit -m "new functionality"
	git push origin new_branch

En résumé:

  • On part d'un repertoire existant
  • On le clone
  • On conserve le lien vers le répertoire originel
  • On bosse comme un acharné pour sortir une nouvelle fonctionnalité indispensable qui révolutionnera le monde
  • On add/commit/push cette nouvelle fonctionnalité, et on soumet une pull request (ou pas, si on préfère garder le fork tel quel).

Si on souhaite récupérer le contenu du répertoire maître, on va commencer par en récupérer le contenu grâce à un fetch upstream, puis on va merger ce contenu dans notre branche master à nous.

	git fetch upstream
	git checkout master
	git merge upstream/master

Ca a peut-être l'air un chouia indigeste pour une première fois, mais on s'y adapte parfaitement. Les branches permettent réellement de faire tout et n'importe quoi, de garder une branche stable, une branche de développement, de partir sur de nouvelles branches pour de nouvelles fonctionnalités, puis de tout fusionner par la suite.

Des exemples pratiques, j'en ai quelques uns: j'ai dernièrement dû travailler sur plusieurs fonctionnalités simultanément. Plutôt que de travailler uniquement sur la branche maître, j'ai créé une première branche development, qui sert de base (et de réceptacle) pour toute nouvelle fonctionnalité. J'ai donc commencé à travailler sur un nouveau module d'import pour une application. Cela a mené à la branche dev-ug, dans laquelle je fusionne régulièrement la branche de développement principale, pour récupérer les derniers hotfixes par exemple. J'ai également dû travailler sur une nouvelle fonctionnalité pour la création de comptes dans l'Active Directory: une nouvelle branche dev-ad. Et vu que la validation de mes modifications aura presque pris un mois, cela m'aura permis de continuer à travailler sur d'autres points, de faire évoluer mon code, sans dépendre du bon vouloir (et des vacances) de mes collègues adorés. Une fois ma validation en poche, je suis revenu sur la branche development, sur laquelle j'ai fusionné la branche dev-ad, après quoi j'ai fusionné ces modifications dans la branche maître.

De nouveau, cela permet de conserver une "porte de sortie", un endroit d'où on peut sortir un patch de derrière les fagots si l'on se rend compte qu'un bug a été trouvé: on revient sur la branche maître, on crée une branche hotfix, on développe le sparadrap et on le ramène dans la branche maître. L'idéal est évidemment de rapatrier également ce patch vers les autres branches... Mais vu que la finalité est de tout ramener à la branche maître, le patch finira bien par être présent partout. Attention à la présence de la branche development, qui permet quand même de faire un gros test de non-régression avant de passer en production.

Voir aussi :