Git s’impose comme une très bonne solution de gestion du travail collaboratif autour de projets de développement informatique.
Ce mémo introduira les idées de base du fonctionnement du logiciel.
En développement actif, Git propose des fonctionnalités étendues sans cesse et qui peuvent convenir à un grand nombre de schémas de collaboration.
Soit trois collaborateurs partageant un même dépôt. Chacun a sur sa station une copie du projet.
git clone adresse_du_depot nom_local
Les changements qu’apporte le premier collaborateur à sa copie du
projet peuvent être envoyés sur le dépôt. On parle d’un push
.
Le push
aura pour effet de changer l’état du dépôt. Les autres
collaborateurs peuvent toutefois continuer à travailler sur leurs
copies mais leurs push
seront refusés car ils se basent sur un
version dépassée du dépôt.
Git propose plusieurs manières de résoudre cette situation. Nous allons en examiner une.
Par défaut, Git crée un branche master
et offre la possibilité d’en
créer d’autres.
Travailler sur un branche n’affecte pas le master. Chaque collaborateur peut par exemple en créer une à son nom et développer dessus sans être affecté par les ajouts de ses collaborateurs qui auront lieu sur d’autres branches réservées.
Si on étend le schéma des branches, on peut se retrouver avec un petit
tronc master
à partir duquel partent dans tous les sens des branches
plus ou moins longues.
A C _/ D \_ _/ \_ \_ M _/ \_ \_/ \_ _ \_ _ _
Formaliser le fonctionnement d’une équipe de collaborateurs travaillant sur un projet de développement.
Ci-dessous le scénario type d’un développeur sur une journée de travail. Ce déroulé sera expliqué en détail à la fin de ce document.
$ git fetch $ git merge origin/master # résolution des conflits $ git add . $ git commit -m "Etat du jour 1" # développement - ajouts - modification $ git add . $ git commit -m "Etat du jour 2" # développement - ajouts - modification $ git add . $ git commit -m "Etat du jour 3" # dernière vérification avant l'envoi $ git fetch $ git merge origin/master # résolution des conflits $ git add . $ git commit -m "Etat de fin de journée de travail" $ git push
Une dépôt Git
centralise le travail de plusieurs intervenants sur un
projet de développement.
La prise en main de ce logiciel n’est pas intuitive. La mise en place d’un schéma de fonctionnement de base permettra de l’exploiter avant de le maîtriser.
Chaque collaborateur commence par héberger sur son ordinateur une copie du dépôt central.
git clone adresse_du_depot nom_local
À chaque fois qu’il l’estime nécessaire, un collaborateur met à jour le dépôt central en envoyant l’état d’avancement de son travail.
git add .
git commit -m "Message descriptif des ajouts"
git push
Si un autre collaborateur souhaite à son tour envoyer l’avancement de son travail, l’état du dépôt central aura changé.
Le push
échouera alors, avec un message d’erreur semblable au suivant :
$ git push ! [rejected] master -> master (fetch first) error: impossible de pousser des références vers 'adresse_du_depot' astuce: Les mises à jour ont été rejetées car la branche distante contient du travail que astuce: vous n'avez pas en local. Ceci est généralement causé par un autre dépôt poussé astuce: vers la même référence. Vous pourriez intégrer d'abord les changements distants astuce: (par exemple 'git pull ...') avant de pousser à nouveau. astuce: Voir la 'Note à propos des avances rapides' dans 'git push --help' pour plus d'information. $
Git
offre différentes possibilités pour résoudre cette
situation. Celle présentée ci-dessous offre l’avantage de nous
familiariser avec le logiciel.
La commande git fetch
permet de récupérer le nouvel état
d’avancement du dépôt et le mettre dans un emplacement virtuel
origin/master
sans écraser le travail effectué par le collaborateur.
$ git fetch
remote: Counting objects: 5, donne.
remote: Compressing objects: 100% (2/2), donne.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), donne.
Depuis adresse_du_depot
7f934c9..a25526d master -> origin/master
$
La commande git merge origin/master
rassemblera la version du
serveur avec le travail déjà effectué par le collaborateur en faisant
ressortir les conflits qu’il pourra résoudre à son aise.
$ git merge origin/master
Fusion automatique de README.md
CONFLIT (contenu) : Conflit de fusion dans README.md
La fusion automatique a échoué ; réglez les conflits et validez le résultat.
$
Les conflits, ici contenus dans le fichier README.md
pour l’exemple,
seront clairement délimités par Git
grâce à des marqueurs clairs.
<<<<<<< HEAD La version locale ======= La version du dépôt central >>>>>>> origin/master
Le collaborateur n’aura qu’à choisir quelle portion du code garder et
celle qu’il désactivera en la commentant avant d’envoyer sur le dépôt
central. Il devra avant cela également enlever les marqueurs
introduits par Git
pour indiquer les conflits :
<<<<<<< HEAD ======= >>>>>>> origin/master
$ git commit -m "Merge de conflits avec la version du dépôt central"
$ git push
Git
était au départ un système de fichier optimisé qui a évolué vers
un système de gestion de version centralisé. Cette aspect de sa
conception lui donne une grande flexibilité.
La gestion des conflits comme nous avons vu précédemment peut être conduite selon plusieurs stratégies. À la rebase par exemple.
Il existe néanmoins une autre stratégie qui est considéré aujourd’hui
comme une spécificité grâce à laquelle Git
surpasse ses concurrents
dans le domaine de la gestion centralisée du travail collaboratif, les
branches
.
C’est cette spécificité que nous souhaitons exploiter de manière plus poussée et qui donnera lieu à de nouveaux documents dans le cadre de ce projet de formalisation d’un workflow.
La première action du développeur au début de sa journée et avant de toucher à son code est de tirer à lui la version du dépôt afin de s’assurer que ses ajouts se feront à partir de la version la plus à jour.
$ git fetch # ....
La sortie de git fetch
indiquera clairement si de nouvelles
modifications ont été apportées au dépôt central
$ git fetch git@localhost's password: remote: Counting objects: 6, donne. remote: Compressing objects: 100% (3/3), donne. remote: Total 3 (delta 1), reused 0 (delta 0) Unpacking objects: 100% (3/3), donne. Depuis localhost:~/project 07d5585..0ba7c21 master -> origin/master
Si la commande git fetch
ne renvoie pas de sortie cela signifie que
l’espace de travail du développeur est à jour avec celui du dépôt
central. En d’autres termes, le dernier commit envoyé au dépôt central
a été le sien.
Si de nouveaux commits ont été ajouté au dépôt central, la commande
git fetch
en rend compte. Il faudra alors au développeur examiner
les conflits et les inclure avec son travail avant d’enregistrer le
nouvel état obtenu dans un nouveau commit.
$ git merge origin/master # résolution des conflits $ git add . $ git commit -m "Merge du dernier état du dépôt"
La journée de travail sera une succession d’ajouts et de commits que le développeur excutera dans son espace de travail, sur son ordinateur.
# développement - ajouts - modification $ git add . $ git commit -m "Etat du jour 2" # développement - ajouts - modification $ git add . $ git commit -m "Etat du jour 3"
À la fin de journée de travail le développeur devra avoir envoyé l’état d’avancement de son travail du jour vers le dépôt central.
L’étape est tout aussi critique qu’en première phase car il se peut que l’état du dépôt central ait changé grâce au travail d’autres collaborateurs du projet.
Si la commande git push
échoue, il faudra au développeur tirer à lui
la version du dépôt central, soigner les conflits, créer un nouveau
commit de réconciliation, avant de renvoyer son travail au serveur.
# dernière vérification avant l'envoi $ git fetch $ git merge origin/master # résolution des conflits $ git add . $ git commit -m "Etat de fin de journée de travail" $ git push
- http://documentup.com/skwp/git-workflows-book
- http://scottchacon.com/2011/08/31/github-flow.html
- https://guides.github.com/introduction/flow/index.html
- http://www.toptal.com/git/git-workflows-for-pros-a-good-git-guide
- https://sandofsky.com/blog/git-workflow.html
- https://git-scm.com/book/en/v2/Git-Branching-Branching-Workflows
- http://nvie.com/posts/a-successful-git-branching-model/
Illustrations tirées depuis ce site