object.title
Git expliqué avec mes mots

Par J.Pisi - TheExpert Développeur chez SQUAD

C’est simple . D’abord, tu pull le master. Puis tu stage, commit et push tes changements en précisant si c’est une feature, une fix ou une hot-fix. Puis tu fais ta merge request.

Git expliqué avec mes mots

Au sortir de ma formation, j’ai constaté que Git était très souvent mentionné dans les offres. Désireux d’ajouter une ligne à mon CV, j’ai fondu sur le tuto de Grafikart pour tenter de connaître un peu mieux cet outil. L’objectif : ne pas être complètement largué le jour de mon intégration. Je vous propose quelques explications simples et une compilation des certaines commandes que l’on peut rencontrer dans la jungle parfois hostile des outils de dev et de l’organisation.

Qu’est-ce que git ?

Oui, on commence facile. C’est un outil de « versioning ». Il permet d’enregistrer différentes versions de notre code. En gros et basiquement, c’est comme faire une sauvegarde dans un jeu de vidéo, sans écraser systématiquement la dernière, de sorte que toute la progression soit conservée. Ainsi, si on désire rejouer un tronçon, on peut le faire grâce à l’historique. Git vous permettra de visualiser cet historique avec précision (pour une meilleure lisibilité, soyez précis et synthétique lorsque vous nommez une version).

C’est la même chose… Avec un peu d’imagination.
C’est la même chose… Avec un peu d’imagination.

Comment faire une sauvegarde ?

Il y a plusieurs façons : avec une interface graphique via Github, ou en ligne de commande via un terminal *éclair zébrant le ciel*. On n’a pas peur, on prend la deuxième option ! Ho et à propos, puisqu’on est sur la console, git help, git commit -help, git (action) -help seront vos amis !

Ce qui nous donne :

  1. Après avoir ouvert mon terminal, Je me place sur le bon dossier avec la commande « cd » (ex: cd documents/programmation/mon-projet).
  2. Si ça n’a jamais été fait, je fais un coup de « git init » pour dire à Git qu’il doit surveiller ce dossier (il va se créer un répertoire).
  3. J’utilise « git add -all » pour dire à Git de « préparer »(stage) tous les dossiers à être sauvegardés.
  4.  On y est presque : « git commit -m » pour enregistrer une version du projet à cet instant. Ici, « -m » permet d’écrire un commentaire sur l’avancement du projet. Exemple : git commit -m « Ajout de la newsletter ».
  5. « git status » m’informe si tout va bien (à utiliser très souvent donc).
  6.  « git log –oneline » me permet de contempler tout le chemin parcouru en me listant tous les commits effectués (cf image plus haut).

Voyager dans le temps !

TUTO GIT
TUTO GIT

Grâce à la commande « checkout », on peut en quelque sorte aller dans le passé. L’idée est la suivante : on demande à Git de nous montrer comment était le code à la version -n. Si vous ouvrez votre répertoire et votre éditeur de texte après cette commande, tout sera revenu en l’état, mais votre travail ne sera pas perdu.

Comment faire :

  1.  Préparation : « git status » me dit que tout va bien et « git log –oneline » m’affiche l’ensemble de commits.
  2. J’utilise « git checkout » + « code » fourni par le git log. Il s’agit d’une série de chiffres et de lettres nommant les versions et précédant vos commentaires. Exemple : « git checkout 42e9cf6 ». On peut aussi faire « git checkout 42e9cf6 index.php » pour ne voir qu’un fichier.
  3. Le « HEAD » est maintenant positionné sur le commit souhaité. Qu’est ce que le HEAD ? Il matérialise l’endroit où vous êtes. Si je file la comparaison avec le voyage dans le temps, c’est le moment où vous avez posé votre DeLorean.
  4.  Pour revenir à la version la plus récente, « git checkout » + « code » ou « git checkout master » (on reviendra sur cette syntaxe plus tard, avec les branches).

Ce mode ne vous permet pas de modifier l’historique. Si vous faîtes malgré tout des changements, Git ne saura pas quoi en faire et ils ne seront rattachés à aucune branches.

Modifier l’histoire

Alors à partir de maintenant, prudence. Git nous offre la possibilité de modifier l’historique des commits. Avant plus de détails, gardez bien en tête que cela ne se fait qu’en local ! On peut modifier l’historique pour plusieurs raisons :

  • simplement pour le nettoyer et le rendre plus lisible.
  • revenir à une version qui fonctionnait (cas de la tristesse).

A)Fusionner les commits

Si j’ai trop de commits et que ceux-ci ne sont pas pertinents, je peux choisir d’en fusionner certains grâce au rebase.

  1. J’identifie combien de commits sont concernés (git log –oneline).
  2. Je me place sur le commit le plus récent. (git checkout + code).
  3. « git rebase HEAD~n » (où n représente le nombre de commits précédents ciblés) ou « git rebase HEAD^ » (où chaque accent représente un commit précédent). Exemple : HEAD~3 === HEAD^^^.
  4.  En l’état, et si vous êtes sur Linux, le terminal passe en mode « nano » (*éclair zébrant le ciel, encore*). On lit tout ! Beaucoup d’options sont proposés mais c’est « squash » qui nous intéresse. On ne va donc écrire « squash » à la place de « pick » que sur les commit qu’on souhaite intégrer au principal. Un coup de |ctrl| + |x| et nano nous demande quelle message garder. Effacer, réécrivez, comme vous voulez, et à nouveau |ctrl| + |x|.
  5. Tout s’est bien passé, vous êtes revenu sur le terminal et git vous informe dans sa prose toute poétique ce qu’il a fait.
  6.  Il y a eu un problème… Git parlera de conflit entre les versions (souvent des doublons). Il faudra ouvrir votre éditeur de texte : git à le bon goût de mettre en valeur les zone de conflit. Effacez simplement le contenu qui vous gêne, sauvegardez, refaites un coup de git commit puis finissez le processus avec un « git rebase –continue ».
  7.  Tout va bien! « git log –oneline » pour voir avec nos yeux ébahis que tout s’est bien passé.
  8. \Alerte/ Je suis perdu ! « git rebase –abort » pour annuler tout ça.

B) Revert : Défaire un commit

Cette fonction permet d’annuler un commit, et cette annulation fera l’objet d’un nouveau commit… Autrement dit, défaire un commit est une action qui impacte le projet et à ce titre, elle figure dans l’historique.

  1. « git log –oneline » (El Famoso).
  2. « git revert » + « code ».
  3. Nano vous propose de modifier le message, |ctrl|+|x| pour valider.
  4. Retour sur le terminal, « git log » pour vérifier et c’est réglé.

C) Le RESET

Là, on commence à jouer avec le feu dans la mesure où les actions faites seront définitives. Concentration, sérénité et réflexion sont de mises. Ce mode va vous permettre de nettoyer votre historique pour le rendre plus lisible ou de revenir à une version antérieure. La différence avec revert ? Ces modifications ne feront pas l’objet d’un commit vous expliquant qu’une suppression a été faite.

  • « git reset » : permet d’annuler le dernier « git add ». Pour l’instant ça reste gentil.
  • « git reset –soft »+ « code » : le HEAD revient à ce commit, efface tous les suivants mais garde en « stage » les modifications présentent dans votre éditeur de texte, comme si vous avez fait un « git add ».
  • « git reset –mixed » + « code » : mode par défaut. Fonctionne comme le soft sauf que c’est à vous de faire le « git add »
  • « git reset –hard » + « code » : comme le précédant mais supprime en plus toutes les modifications que vous avez faites dans votre éditeur. Vous voyagez dans le temps pour vous retrouver à 15 ans et patatra ! Vous avez 15 ans et tout oublié de ce que vous avez vécu par la suite ! Autrement dit, vous avez « game over » et vous revenez à votre dernière sauvegarde. Faut pas rigoler avec un truc qui a hard dans son nom !

Voila voila, on a fait le tour des commandes principales à l’exception d’une seule. Celle qui va donner une autre dimension à votre organisation ! Enfin, dimensionS serait plus juste.

« Branch »

Jusqu’à présent, on n’a utilisé qu’une seule « branch », elle s’appelle « master ». On pourrait s’en contenter si on est seul mais le problème, c’est qu’on va être très vite saturé de commits. Git nous permet de créer des « branch » pour donner plus de clarté à notre travail.

Qu’est-ce qu’une « branch » ? On peut le traduire par succursale ou branche, comme celle d’un arbre, mais je trouve que l’image n’est pas idéale. En effet, un fois que le travail est terminé sur une « branche », on va le ramener sur la principale et supprimer celle qui ne sert plus. Voici une jolie illustration.

Avec cette image, je ne vois pas vraiment un arbre, à la limite deux voies ferrées qui se séparent et se rejoignent. Mais la meilleure comparaison est une chaîne d’assemblage d’usine de voiture.

Ainsi, une « branch » sert à développer une fonctionnalité particulière avant d’être effacée, la branche master n’accueillant des commits que lorsqu’ils correspondent à un certain avancement du projet.

Ce qui nous donne en code :

  1. « git branch » me permet de lister les « branch ».
  2. « git branch » + « nom » pour en créer une nouvelle. Exemple : « git branch roues » (sur laquelle je vais trouver des commits gente ou pneu par exemple..
  3. « git checkout » + « nom de la branche » pour déplacer le HEAD.
  4. Utiliser toutes les fonctions qu’on a vu plus haut ..

Et pour ramener le travail sur master, on va utiliser la commande « merge » :

  1. « git checkout master » pour se placer sur la principale.
  2. « git merge » + « nom de la branche » (roues dans notre exemple).
  3. « git branch roue -d », on travaille proprement et on efface ce qui n’est plus utile.

Dépôt à distance (remote)

On a travaillé en local jusqu’à présent. Git nous permet aussi d’utiliser un dépôt distant : un remote (littéralement « à distance »). C’est un dossier de partage sur lequel tout le monde va envoyer son travail (et récupérer celui des autres). Ca peut être une clé usb, une dropbox, un autre fichier sur le même ordi, etc. On peut aussi utiliser des services tels que Github ou Bitbucket.

Comment ça marche :

0/ Si vous n’utilisez pas de service tiers, il faudra passer par « git init –bare » à faire sur le dossier qui servira de dépôt distant.

1/ »git init remote add » + « nom du remote » + « chemin ». Pour initialiser le dépôt distant. Par convention, il s’appelle origin. Exemple : git init remote add origin url.

2/ « git remote -v » me permet de lister les dépôts et « git branch -r » les branches distantes.

3/Admettons que je rejoins un projet en cours, je fais « git clone » + « chemin » + « nom du dossier dans lequel il doit cloner » pour récupérer l’ensemble du projet. Si je n’en veux qu’un morceau, je rajoute « –depth n » (où n est le nombre de commit que je veux récupérer en partant du plus récent). Exemple : git clone url site-de-golf –depth 4

4/ »git push » + « remote » + « branch » me permet d’envoyer mon travail. Ex: git push origin master.

« remote contains work that you don’t have locally », Caramba ! Quelqu’un a fait un push avant moi ! Il suffit de me mettre à jour avec un petit :

4b/ « git pull –rebase origin master ». Notez la présence du rebase : il sert à fusionner proprement. C’est à dire que l’annotation « merge of » n’apparaîtra dans la dénomination du commit : on y gagne en lisibilité. Il ne me reste plus qu’à refaire mon push du 4/.

5/ »git push origin –delete branch » me permet de supprimer la branche distante une fois la fonctionnalité développée.

FIOUF !!!

Vous êtes toujours là ? Bien joué ! Ce n’est pas évident de lire tout ça d’une traite. En espérant que ça vous aura été utile. On a fait le tour des basiques en lignes de commandes. Au-delà de « simples » considérations techniques, Git est un outil de gestion et d’organisation qui peut s’utiliser de plusieurs manières. L’une d’elle est Git Flow. Je comptais en parlais mais …

Je ne suis pas prêt…

Voili voilou. Un dernier mot sur Github. Il offre la possibilité de faire ces commits par glisser-déposer. Surtout, il propose un système de :

  • Issues : pour la notification des problèmes.
  • Fork permet de cloner le travail de quelqu’un, d’y travailler dessus en se créant une nouvelle branche #bonnesPratiques.
  •  Pull Request pour soumettre la branche qu’on vient de créer au détenteur du projet.

Dans ma prod, on utilise gitKraken qui offre une interface graphique avec de jolies couleurs pour représenter les différentes branches. Cela dit, avoir quelques bases en ligne de commande, au moins pour mettre un nom derrière les actions, a été bien utile.

Happy coding \o/

Le tuto de grafikart :

crédits image @deviantart:

Pepe-silvia redraw by Cicadaqueen

Doc Emmett Brown by ambellinaleander

Goten&Trunks  by Vegetaslittlelover