Pourquoi un dépôt central / distant ?
Jusqu’à présent, nous nous sommes toujours placés du point de vue d’un développeur individuel. Nous étions sur une machine avec 1 ou plusieurs dépôts locaux. Cependant ces dépôts ne répondent pas à toutes les questions, notamment les questions suivantes:
- Comment je travaille en équipe, avec d’autres développeurs ? Collaboration
- Comment je partage mon code, avec ma communauté ? Partage / Publication
La réponse à ces deux questions ne peut, en effet, pas être donnée par des dépôts locaux. Il faut un point de référence commun aux différents développeurs. C’est donc le rôle des dépôts distants. Avoir un dépôt distant permet, en outre, de disposer d’une sauvegarde de notre code.
Il faut bien différencier deux notions
- Le serveur GIT proprement dit (git server), qui est une application s’exécutant sur un serveur, et capable de dialoguer avec les git clients,
- Les services git (git server as a service), qui sont des plateformes internet, implémentant la fonction git serveur, en lui ajoutant des fonctionnalités complémentaires, comme la gestion des tickets, la gestion de projets, de tableaux de bord Kanban, etc.
Un git server
peut s’installer n’importe où, y compris sur notre propre machine si nous le souhaitons. Si vous disposez d’un NAS Synology, git server
fait partie des composants installables.
Certaines enterprises installent leur propre serveur GIT, pour héberger du code « sensible ».
Mais un serveur GIT n’offre pas rien de plus que ce que nous avons sur notre machine, et l’ergonomie est la même. Les services GIT, quand à eux, apportent les fonctionnalités d’un serveur GIT, en y ajouant des outils complémentaires :
- une interface ergonomique (en principe),
- un gestionnaire de ticket,
- une gestione de flux d’approbation de code,
- … …
Lorsque l’on parle GitHub, ou Gitlab nous parlons de service GIT. Il existe de multiples plateformes similaires sur internet, comme SourceForge, Framagit, et plus d’une trentaine d’autres 1
Dans la suite de l’épisode, nous parlerons de service GIT, et les exemples seront basés sur GitHub (parce que c’est celui que j’utilise)
Créer le lien local / distant
Commençons par le plus simple, avec la commande git remote
.
Si nous voulons voir les dépôts distants liés à nos dépôts locaux:
$ git remote [-v]
Si nous voulons relier un dépôt local à un dépôt distant (existant)
$ git remote add <nom court> <url vers le dépôt distant>
$
$ git remote add blog https://github.com/egeorjon/EG-Blog.git
Vérifions ce que cela donne
$ git remote
blog
$ git remote -v
blog https://github.com/egeorjon/EG-Blog (fetch)
blog https://github.com/egeorjon/EG-Blog (push)
Le résultat de la seconde commande montre les deux flux que GIT met en place lorsque l’on ajoute un dépôt distant
- Le flux descendant (du distant vers le local): fetch
- Le flux montant (du local vers le distant): push
Comme je l’ai expliqué dans le second épisode, créer un dépôt localement, puis le relier à un dépôt distant, n’est pas une méthode conseillée. La méthode généralement décrite est
- Je crée un dépôt sur un outil comme GitHub ou Gitlab. Je choisis différentes options comme la licence,
- Je crée mon dépôt local à partir du dépôt distant, avec la commande
git clone
.
$ git clone <url vers le dépôt distant> [<nom court>]
$
$ git clone https://github.com/egeorjon/EG-Blog.git blog
Si le nom court n’est pas spécifié, le nom court par défaut sera origin
. L’avantage de cette méthode est que vous êtes sûre que vous démarrez avec des dépôts qui sont complètement alignés.
Le lien local / distant peut être modifié / supprimé
$ git remote rename <ancien nom court> <nouveau nom court> # Changer le nom court du dépôt distant
$
$ git remote rm <nom court> # Supprime le lien vers le dépôt distant.
Push / fetch / pull
Les dépôts centraux ajoutent 3 commandes principales:
La commande push
Cette opération consiste à pousser (upload) les commits d’une branche vers une branche distante, ou plus exactement, elle permet de mettre à jour les branches distantes.
Partons de la situation de la figure 7
La commande accepte de multiples paramètres:
$ git push # est équivalent à git push origin <branche courante>
$ git push <dépôt distant> <branche> # Pousse la branche spécifiée
$ git push <dépôt distant> --all # pousse toutes les branches
La notion de fast-forward (avance rapide)
Certains d’entre vous pensent probablement que git push
est finalement un git merge
vers une branche distante. C’est tout à fait vrai, avec une restriction cependant: git push
n’effectue que des fast-foward.
Comme expliqué dans le chapitre 3, lorsqu’une opération conduit à déplacer le pointeur d’un commit A, vers un autre commit B, cette opération est appelée avance rapide (fast-forward), si et seulement si B est un descendant de A.
Dans le cas de la figure 9, John ne peut pas faire de push
car C dépend de B, et non de D. Dans ce cas, John a deux solutions:
- Forcer le push, et écraser le dépôt central,
- Ou utiliser la commande
fetch / merge
oupull
, pour ré-aligner son dépôt local avec le dépôt distant, avant de faire de nouveau lepush
(voir paragraphe suivant).
Forcer le push s’effectue avec la commande git push --force
. Cette méthode n’est pas conseillée: si elle résoud le problème du point de vue de John, elle ne fait que reporter le problème sur Annabelle, et elle peut engendrer des pertes de code.
La commande fetch
La commande git fetch
va récupérer l’ensemble des modifications correspondant à une branche ou un tag d’un dépôt distant, ne figurant pas dans le dépôt local. Une fois la commande passée, le dépôt local contiendra les références du dépôt distant, nous permettant ainsi de pouvoir réaliser des fusions.
La syntaxe est la suivante:
$ git fetch <nom court du dépôt distant> <référence> # la référence peut être une branche, ou un tag.
$ git fetch <nom court du dépôt distant> # récupère l'intégralité du dépôt distant
La commande fetch
ne modifie pas le dépôt local, elle
- Télécharge les branches ou les références distantes,
- Indique les différences détectées (entre les branches locales, et les branches téléchargées).
Les modifications des branches ou références distantes sont stockées dans le dépôt local, et sont accessibles via le nom <nom court du dépôt distant>/<nom de la branche>
(par exemple origin\devA).
Pour réellement incorporer les modifications, il faut utiliser la commande git merge
$ git checkout ...
$ git merge ...
Si l’on reprend le cas de John, la façon « propre » de résoudre son problème sera donc la suivante:.
D’une manière générale, une session de travail devrait toujours commencé par un fetch, et se terminer par un push
La commande pull
Globalement la commande pull
est une combinaison des deux commandes fetch
et merge
.
$ git pull <nom court du dépôt distant> [--verbose]
$
$ # this command is equivalent to
$ git fetch <nom court du dépôt distant>
$ git merge origin/<branche active>
Au premier abord git pull
semble être une commande efficace, mais comparée à git fetch
, elle est un plus risquée.
git fetch
se contente de télécharger les branches distantes, et de signaler les différences avec les branches locales.git pull
agit sur le dépôt local, en effectuant une fusion. Il y a donc des risques de conflits.
Une histoire de processus
Nous venons de parcourir les quelques commandes nécessaires à la synchronisation d’un dépôt local, avec un dépot distant. Pour terminer cet article, je vais laisser de côté les aspects techniques, et parler « méthodologie ».
Pour moi, travailler avec GIT nécessite de répondre à une contradiction
- D’un côté nous avons la flexibilité de l’outil lui-même, grâce au très grand nombre de ces fonctionnalités,
- D’un autre côté, l’outil aussi souple qu’il soit, nécessite une certaine rigueur de travail, rigueur sans laquelle, nous pourrions perdre du code, ou passer notre temps à corriger les erreurs d’aiguillage, et cette rigueur peut passer pour une contrainte, et un manque de flexibilité.
La façon de résoudre ces contractions est de définir le flow de développement, surtout si vous travaillez à plusieurs sur le même projet. Ce flux de développement doit décrire le mode de fonctionement entre les développeurs, et avec les conséquences sur le processus de travail de chaque développeur.
J’illustre ce que je viens de dire avec le cas de ce blog
- Le blog prend la forme d’un ensemble de fichiers Markdown, et d’un thème.
- Le tout est géré dans une dépôt sur mon PC. Le dépôt distant se trouve sur GitHub,
- Quand je fais un
pull request
, la plateforme Netlify génère le site en mode « preview », - Quand je fais un
merge
(sous-entendu d’une branche avec la branchemain
), la plateforme Netlify génère le site en mode « production »
Je précise que je connaissais GitHub avant de démarrer, mais sans le pratiquer quotidiennement.
A partir de là, il serait trop long de lister toutes les problèmes que j’ai rencontré au début. En voici, malgré tout, quelques-uns:
- Commits effectués sur la mauvaise branche,
- Ne me demandez pas pourquoi, mais je faisais certains développements directement dans
main
(commme le thème par exemple), et d’autres dans des branches, - Donc cela veut dire que je faisais un
push
de la branchemain
, donc Netlify me générait directement la version de production, qui plantait parfois, - Ajout d’articles ou modification d’articles, dans GitHub (le dépôt distant), puis en local, générant des conflits lors d’un
push
. - … …
Le point commun à tous ces problèmes: Je n’avais pas réfléchi précisement à la façon d’utiliser l’outil.
- Est-ce que je rédige depuis un point unique ou non ?
- Quelle doit-être ma structure de branches ?
- Quelle méthode dois-je employer pour les modifications structurelles du site ?
Je vous recommande de lire l’article Contribution à un projet du livre en ligne Pro GIT. Vous verrez apparaître, au fil des lignes, des processus / rituels du type
- Début de session,
- fetch
- diff
- merge
- edit / commit
- edit / commit
- … …
- edit / commit
- push
- Fin de session (et on recommence).
C’est ce type de schéma-là qu’il faut avoir en tête, autant que la syntaxe des commandes git
.
Je pense que cela peut paraître évident à tous ceux qui pratiquent GIT
depuis leur début de développeurs, mais ça l’est beaucoup moins pour les autres …
Comparison of source-code-hosting facilities. Wikipedia, The Free Encyclopedia. April 14, 2021, 19:10 UTC. Available at: https://en.wikipedia.org/w/index.php?title=Comparison_of_source-code-hosting_facilities&oldid=1017817240. Accessed April 21, 2021. ↩︎
Commentaires