Versionner ? Pourquoi et comment avec Git !

Baptiste Lecocq
Dec 13, 2016 · 7 min read

Git est un VCS (Version Control System). Il s’agit d’un outil vous permettant la gestion et le suivi du code. En effet, le versionning de vos fichiers (pouvoir suivre l’avancement d’un fichier dans le temps) et le travail en équipe, peut être parfois assez laborieux. Git vous simplifiera la vie.

Comprendre Git

Git possède une architecture et une organisation spéciale, en comparaison aux autres VCS (SVN, Mercurial, etc…).

Concernant l’architecture, trois zones (trees) de base sont à votre disposition : Working Directory, Index, HEAD. La première représente votre dossier courant. La seconde, la zone de staging (un fichier retenu dans un état). Le dernier représente la validation (le commit), c’est à dire une version à l’instant t de vos fichiers.

Démarrer un projet Git

git init

Lors de la création de votre projet git, aucun des fichiers n’est versionné. On dit que les fichiers sont “untracked”.

Puis vient l’état “unmodified” qui représente un fichier placé sous versionning mais non modifié (le fichier possède au moins un commit). Pour arriver à cette étape de fichier versionné, il suffit de lancer la commande git add filename (on peut remplacer le nom du fichier par . ce qui les représente tous), puis git commit -m "Some text".

Dès les premières modifications, Git saura qu’il y a eu une évolution et le fichier sera considéré comme “modified”. Il ne vous restera plus qu’à le “stage” (passer du Working directory à la zone d’Index), puis de le commit, ce qui le fera retourner dans un état “unmodified”.

Vous l’aurez compris, Git ne se limite pas qu’à cela, il s’agit d’un exemple très banal et surtout, local.

Les commandes de base

git add .

Ajoute les fichiers modifiés (du Working directory) dans la zone d’index (le stage)


git commit -m "A brief message regarding the present commit"

Valide les modifications des fichiers (présent dans la zone d’index)


git log

Permet de voir tous les commit effectués (complété avec --pretty et --graph, vous aurez un beau visuel)


git status

Affiche l’état actuel des fichiers


git rm filename

Supprime un fichier du repo git

Supprimer un fichier à la main ne le supprimera pas pour les futurs commit. C’est pour cela qu’avant de faire un git commit, il est préférable de regarder si le fichier est bien supprimé. Remarque : le fichier sera toujours disponible pour les commit antérieurs.


git diff

Affiche les modifications effectuées mais pas encore “on stage”. L’ajout de l’option --cached vous montrera les différences entre les fichiers "on stage" et le dernier commit.

Les branches

git branch branchname

Crée une branche.


git checkout -b branchname

Crée une branche et vous y positionne.


Je vous ai parlé de “trees” tout à l’heure ? Voyons donc les “branch”.

Une branche est utilisée pour pouvoir travailler sur différentes partie du code (différentes features). Celles-ci sont simples d’utilisation car (contrairement à d’autres VCS), elles ne copient pas tous le code. Une branche est juste un pointeur qui se déplace sur vos commit.

Prenons un cas concret d’utilisation de branche : vous devez créer un site pour un magasin de cosmétiques. Tout s’est bien déroulé et vous allez passer à la création du livre d’or en codant à de multiples endroits. Malheureusement, il n’est d’aucune utilité et il faut le supprimer. Si vous n’avez pas pensé aux branches… bon courage. Sinon, une suppression de la branche vous fera passer à l’instantané souhaité (le pointeur de la branche sera juste supprimé).

L’homme descend du singe

En effet, vous pouvez sauter de branche en branche afin d’améliorer certaines features pour ensuite les rassembler sur vos branches.

Le merging

git merge branchname

Fusionne la branchname sur la branche courante


git pull origin branchname

Fusionne la branchname sur la branche courante, en récuperant le code distant au préalable nous verrons les dépots distants plus bas.


Il est très facile d’utiliser les branches… Mais comment les rassembler ? L’idée est de se positionner sur la branche sur laquelle vous souhaitez fusionner : git checkout branchname (checkout sert à se déplacer — ajoutez l'option -b et git vous créera une branche), puis de merger.

Un peu plus sur le merging

Si vous vous sentez confiant, lisez ceci.

Le merging est plus complexe que précédemment cité. En effet, de base, git se repère grâce à trois choses : l’ancêtre commun et les deux derniers commit des branches à merger.

Lors de votre merge, git regarde si l’ancêtre du commit de la branche à fusionner est direct en comparaison au commit de votre branche attendant la fusion.

  • Si le commit est direct, il utilisera l’avance rapide (fast-forward). Prenons l’exemple du schéma en faisant abstraction du C5. Le fast-forward décalera le pointeur situé sur C2, vers C4. C4 possédera donc les changements de C3.
  • Si non, git créera un commit de fusion entre C4 et C5 (en reprenant le schema au complet).

Remarque : l’utilisation d’un git merge --no-ff oblige git à créer un commit de fusion. Cette option est très intéressante car nous pouvons toujours avoir un visuel des branches fusionnées. Avec fast-forward, ceci est plus délicat.

Suivre le Gitflow

Gitflow

Gitflow est une architecture de branches, qui est fortement conseillée lors de la création/gestion de projet.

D’un aspect synthétique, la branche master n’est utilisée que pour les releases de production (les versions majeures). Develop pour les releases mineures. Et chacune des fonctionnalité développée sera sur une “feature branch” (ex : feature/contact_form).

D’un point de vue technique, develop sera fusionnée sur master à chaque version majeure. De plus, chaque feature sera créée à partir de develop et fusionnée sur cette dernière. Quand une feature est terminée, il est conseillé de supprimer cette branche.

Les tags

Des troncs, des branches… voici les feuilles… (?)

Les tags représentent des annotations concernant les versions de votre projet.

git tag v0.1

Crée un tag sur le commit actuel


git tag v0.1 e285d87

Crée un tag sur le commit de SHA e285d87


git show v0.1

Donne les informations du commit sur lequel le tag v0.1 se trouve

La gestion d’erreurs

Eh oui, le monde git n’est pas sans petits accros. Nous allons voir brièvement quelques aides.

Une fusion avec conflit

Rien de grave, git a prévu des sections dans les fichiers à conflits.

<<<<<<< HEAD:index.html
Voici du contenu
=======
Here is some content
>>>>>>> feature/english:index.html

La première partie représente la branche sur laquelle vous êtes positionné, la deuxième est la branche à fusionner. Il ne reste qu’à enlever les sections, de faire un choix et de git add index.html pour marquer le fichier résolu. Une fois tous les conflits résolus, un git commit fera l'affaire.

Réinitialiser un fichier modifié

git checkout -- filename

Réinitialiser un fichier modifié en phase d’indexation (stage)

git reset HEAD filename

Un commit trop rapide

git commit --amend

Il est conseillé de commit correctement et proprement. Pas besoin d’un commit à chaque ligne de code. Par soucis de perfection, vous serez peut être amenés à ajouter quelques modifications de dernière minute à un commit déjà effectué. Il est possible de le faire, sur le dernier commit réalisé.

Les remotes

Travailler seul c’est bien. A plusieurs c’est mieux.

Du local vers la remote

git add remote origin url

Créé la remote de nom “origin” et d’url “url”


git push origin master

Pousse les modifications de la branche master vers la branche master de la remote origin


En effet, il existe une étape par rapport au local, le push. Celui-ci sert à envoyer les données vers le serveur. Admettons la création d’un repository vide Github. Il vous suffira d’ajouter la remote avec la bonne url, et de push. Les modifications s’y situeront.

Du remote vers le local

git clone url

Clone le repository (si vous n’avez pas encore récupéré les fichiers de la remote)


git fetch

Amène les commit de toutes les remote sur votre local


git pull
# = git fetch + git merge

La distinction entre ces deux dernières commandes n’est pas toujours évidente. Fetch ne fera que “tirer” les modifications sur votre local alors que pull les mergera sur vos branches. Remarque : il est préférable d’utiliser un git pull --rebase qui vous évitera une salve de possibles conflits.

Les commandes de base

git remote -v

Affiche le nom et l’url de votre remote


git remote show origin

Affiche les informations de la remote origin

Don’t try this

Une fois le code poussé sur le serveur, deux méthodes sont à proscrire sous peine de… conflits techniques et sociaux. Ne jamais rebase et commit --amend un code utilisé en remote. En effet, les commit sont tous reliés à leurs parents grâce au SHA (l'identifiant du commit). Effectuer l'une de ces deux commandes change le SHA du commit et donc, même si tout vas bien sur votre local, s'en est tout autre pour vos collègues.

Liens utiles : Git book, Pro Git, Gitflow

Baptiste Lecocq

Written by

Software engineer in Lille & guitar player

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade