📚 Série · Gérer un projet de développement
Git et GitHub : comprendre les grands principes
Quand on débute en développement, on entend très vite parler de Git et de GitHub, souvent comme s’il s’agissait de la même chose. Ce n’est pas le cas, et comprendre la distinction est la première étape pour vraiment saisir comment fonctionne le travail collaboratif sur le code aujourd’hui.
Git est un outil : un logiciel de gestion de versions, installé localement sur ta machine, qui garde la trace de l’évolution d’un projet au fil du temps. GitHub, de son côté, est un service en ligne qui héberge des dépôts Git et ajoute par dessus toute une couche de collaboration : revue de code, discussions, automatisation, gestion de tâches. Git est le moteur, et GitHub une des plateformes qui le fait tourner en public (GitLab et Bitbucket jouent un rôle similaire).
Cet article part des bases pour construire progressivement une compréhension plus fine du fonctionnement interne de Git, avant de terminer sur ce que GitHub ajoute par dessus.
Le problème que Git est venu résoudre
Avant les outils de gestion de versions modernes, la pratique courante consistait à dupliquer des fichiers pour garder des versions successives : projet_v1.zip, projet_v2.zip, projet_v2_corrige.zip, projet_final_vraiment_final.zip. Cette approche pose plusieurs problèmes : impossible de savoir précisément ce qui a changé entre deux versions, aucun moyen simple de revenir en arrière sur un point précis, et surtout un vrai casse-tête dès que plusieurs personnes travaillent sur les mêmes fichiers en parallèle.
Un système de gestion de versions résout ces problèmes en gardant un historique complet et structuré de chaque modification, en permettant de revenir à n’importe quel état passé du projet, et en offrant des mécanismes pour que plusieurs personnes puissent travailler simultanément sans s’écraser mutuellement le travail.
Git, créé en 2005 par Linus Torvalds pour les besoins du noyau Linux, est devenu depuis le standard de fait dans l’industrie. Sa particularité par rapport aux systèmes plus anciens (comme SVN ou CVS) : il est décentralisé. Chaque personne qui clone un projet récupère une copie complète de tout l’historique, pas seulement un accès à un serveur central.
Les trois zones de Git
Pour comprendre Git, il faut d’abord visualiser les trois zones dans lesquelles tes fichiers peuvent se trouver :
Répertoire de travail --git add--> Zone de staging --git commit--> Dépôt (historique)
(working directory) (index) (.git)
Le répertoire de travail, c’est simplement les fichiers tels que tu les vois et les modifies sur ton disque. La zone de staging (ou “index”) est une étape intermédiaire : c’est là que tu prépares ce qui va faire partie du prochain commit, en sélectionnant précisément quels fichiers, ou même quelles lignes, doivent y entrer. Le dépôt, enfin, contient l’historique complet : chaque commit validé, de façon permanente et immuable.
Cette séparation en trois zones peut sembler être une complexité superflue au début (pourquoi ne pas juste enregistrer tout ce qui a changé ?), mais elle permet une chose précieuse : construire des commits propres et intentionnels, qui ne mélangent pas plusieurs changements sans rapport entre eux.
En pratique, cela donne :
git add fichier.txt # déplace fichier.txt vers la zone de staging
git commit -m "message" # crée un commit avec ce qui est en staging
Ce qu’est réellement un commit
C’est ici que la compréhension devient plus technique, et c’est un point souvent mal compris : un commit Git n’est pas un simple “diff” (une liste de lignes ajoutées ou supprimées) comme dans d’anciens systèmes. C’est un instantané complet (un “snapshot”) de l’état de tous les fichiers du projet à un instant donné. Pour optimiser l’espace, Git ne duplique pas les fichiers inchangés : il pointe simplement vers la version précédente si rien n’a changé.
Chaque commit contient également une référence vers son ou ses commits parents. En reliant ainsi chaque commit à celui qui le précède, Git construit un graphe orienté acyclique, souvent abrégé DAG (pour “Directed Acyclic Graph”). C’est cette structure de graphe qui rend possible tout ce qui suit : les branches, les fusions, le retour en arrière.
Chaque commit est identifié par un hash, une empreinte calculée à partir de son contenu (les fichiers, le message, le parent, l’auteur, la date). Le moindre changement, même une seule lettre, produit un hash totalement différent. Cette propriété garantit l’intégrité de l’historique : il est impossible de modifier discrètement un commit passé sans que cela se voie immédiatement, puisque son identifiant changerait.
Les branches : le vrai pouvoir de Git
Les branches sont sans doute le concept qui a le plus démocratisé Git par rapport à ses prédécesseurs. Une branche n’est rien de plus qu’un pointeur léger vers un commit précis, concrètement un petit fichier texte contenant un hash. Créer une branche ne duplique aucun fichier, ne copie aucune donnée : c’est une opération quasi instantanée, peu importe la taille du projet.
Cette légèreté change fondamentalement la façon de travailler. Sur d’anciens systèmes, créer une branche était une opération lourde, souvent découragée. Avec Git, on peut créer une branche pour chaque fonctionnalité, chaque correctif, chaque expérimentation, sans coût.
git branch nouvelle-fonctionnalite # crée une branche
git switch nouvelle-fonctionnalite # bascule dessus
Quand tu fais des commits sur une branche, seul le pointeur de cette branche avance. La branche principale (souvent appelée main) reste inchangée pendant ce temps, ce qui permet de développer une fonctionnalité en isolation, sans perturber le reste du projet.
Fusionner : merge et rebase
Une fois le travail terminé sur une branche, il faut le réintégrer. Deux approches principales existent, et le choix entre les deux est une des premières décisions un peu plus avancées que l’on rencontre en pratique.
Le merge crée un commit spécial, dit “commit de fusion”, qui a deux parents : le dernier commit de chaque branche fusionnée. L’historique garde ainsi la trace exacte de ce qui s’est réellement passé, y compris les moments où le travail a divergé puis a été recombiné.
git merge nouvelle-fonctionnalite
Le rebase, à l’inverse, rejoue les commits d’une branche un par un sur une nouvelle base, comme si le travail avait été fait directement à partir du dernier état de la branche principale. Le résultat est un historique linéaire, plus lisible, mais qui ne reflète plus l’ordre chronologique réel des événements.
git rebase main
Il n’y a pas de réponse universelle sur lequel utiliser : le merge préserve la vérité historique et convient bien au travail d’équipe partagé, tandis que le rebase produit un historique plus propre, souvent préféré pour du travail individuel avant de partager une branche.
Travailler avec un dépôt distant
Jusqu’ici, tout se passe en local. Git étant décentralisé, chaque copie du projet (chaque “clone”) contient l’intégralité de l’historique, pas seulement un accès à distance. Un “remote” est simplement une référence vers un autre dépôt, généralement hébergé sur un service comme GitHub.
git clone <url> # récupère une copie complète du dépôt distant
git fetch # récupère les nouveaux commits du remote, sans les fusionner
git pull # équivalent à un fetch suivi d'un merge (ou rebase, selon la config)
git push # envoie les commits locaux vers le remote
La distinction entre fetch et pull mérite d’être soulignée : fetch se contente de rapatrier les données sans toucher à ton travail en cours, ce qui permet de regarder ce qui a changé avant de décider quoi en faire. pull, plus direct, tente immédiatement d’intégrer ces changements dans ta branche courante.
Où GitHub entre en jeu
Tout ce qui précède décrit Git seul, utilisable entièrement en local, sans connexion internet. GitHub n’est pas Git : c’est un service qui héberge des dépôts Git sur ses serveurs et ajoute une couche de collaboration construite autour.
La contribution la plus structurante de GitHub est la pull request (ou “PR”). Une pull request est une proposition de fusion : “voici les commits de ma branche, je souhaite les intégrer à la branche principale”. Elle ouvre un espace de discussion autour du changement, permet une revue de code ligne par ligne, et sert de point de passage obligé avant qu’un changement n’entre officiellement dans le projet.
Au-delà des pull requests, GitHub ajoute des issues (pour suivre des tâches, bugs, demandes), des GitHub Actions (pour automatiser des tests, des déploiements, toute forme d’intégration continue), et une dimension sociale : forks (copier un projet pour le faire évoluer de son côté), stars, visibilité publique des contributions. GitHub est aussi devenu une plateforme d’agents : si le sujet t’intéresse, j’ai détaillé le fonctionnement de GitHub Copilot : de l’autocomplétion à l’agent qui code pour toi dans un autre article.
Un workflow d’équipe typique
En pratique, la combinaison de ces éléments donne un workflow assez standard dans la plupart des équipes : la branche principale est protégée (on ne peut pas y pousser directement), chaque nouveau développement se fait sur une branche dédiée, une pull request est ouverte dès que le travail est prêt à être discuté, une ou plusieurs personnes relisent le code et proposent des ajustements, et la fusion ne se fait qu’une fois la revue validée, souvent après que les tests automatiques (via CI) soient passés au vert.
Ce modèle, parfois appelé “feature branch workflow”, est devenu la norme parce qu’il concilie deux besoins a priori contradictoires : permettre à chacun de travailler en parallèle sans se gêner, tout en gardant un contrôle qualité avant que quoi que ce soit n’entre dans la version de référence du projet.
Pour aller plus loin
Cet article s’arrête volontairement à un niveau de compréhension générale, mais Git recèle encore beaucoup de mécanismes plus avancés qui méritent des articles à part entière : le rebase interactif pour réécrire précisément un historique de commits, le cherry-pick pour récupérer un commit isolé d’une autre branche, le bisect pour retrouver automatiquement le commit responsable d’une régression, ou encore git worktree, qui permet de travailler sur plusieurs branches en parallèle dans des répertoires séparés. C’est un mécanisme particulièrement pertinent dès qu’on orchestre plusieurs sessions de travail simultanées sur un même projet, par exemple avec plusieurs instances de Claude Code : coder et automatiser avec un agent tournant en parallèle.
Comprendre ces grands principes, la structure en trois zones, le commit comme instantané, la branche comme simple pointeur, suffit déjà pour utiliser Git efficacement au quotidien. Le reste vient avec la pratique.