đŸȘƒ Git#

../_images/git.png

Note

Nous allons nous intĂ©resser Ă  l’aspect gestion de versions de Git: Comment enregistrer l’historique des modifications apportĂ©es Ă  un projet.

Le problĂšme#

Le code est plus souvent lu qu’écrit

—Guido van Rossum

La dĂ©marche naturelle quand on commence Ă  travailler longuement sur un projet pour lequel on veut Ă©viter d’effacer et/ou de perdre son code Ă  cause d’une erreur humaine est de dupliquer les fichiers et de crĂ©er des versions multiples d’un mĂȘme fichier qui sont des instantanĂ©s Ă  un moment donnĂ©e:

- rapport.doc
- rapport_v1.1.doc
- rapport_v1.doc
- rapport_v2.doc
- rapport_v2_beta.doc
- rapport_vfinale.doc

Il s’agit d’une maniĂšre trĂšs artisanale de procĂ©der et qui est susceptible d’ĂȘtre Ă  la merci d’une erreur humaine.

La version la plus Ă  jour est-elle rapport.doc ou rapport_vfinale.doc ? Et si on avait un fichier rapport_vfinale2.doc ?

La gestion des versions est un travail fastidieux et méthodique, spoiler, les humains ne sont pas doués pour les travaux fastidieux et méthodique.

Laissons cela Ă  la machine et concentrons-nous sur la partie du travail oĂč nous sommes meilleurs que la machine.

Version Control System#

Initialement il s’agit d’une famille de logiciels dĂ©diĂ©s Ă  la gestion de code source pour les projets logiciels et Ă©galement Ă  la documentation, site web, etc.

Leur objectif est de faciliter le travail collaboratif en simplifiant la facilitĂ© d’échange des fichiers et de leurs versions, la traçabilitĂ© des modifications et la gestion des conflits.

Il existe deux grandes familles de VCS:

  • SystĂšmes centralisĂ©s:
    • CVS (Concurrent Versioning System) vieillissant

    • SVN (Subversion) populaire il y a quelques temps dĂ©jĂ 

  • SystĂšmes dĂ©centralisĂ©s:
    • Git

    • Mercurial (Hg)

    • Bazaar (bzr)

Ces derniers présentent de nombreux avantages:

  • Une sauvegarde (modulo la synchronisation avec un serveur distant)

  • La conservation de l’historique (nominatif) des fichiers « Qui a fait quoi en somme »

  • La possibilitĂ© de retour en arriĂšre

  • La fusion des modifications lors du travail collaboratif

  • La visualisation des changements au cours du temps

Git#

Il s’agit d’un logiciel de gestion de versions dĂ©centralisĂ©, créé par Linus Torvalds (auteur du noyau Linux), sa popularitĂ© s’explique par sa rapiditĂ© (mise en oeuvre et exĂ©cution), le travail par branches possible.

Celui-ci est assez complexe Ă  utiliser, comme tout les CVS, toutefois quelques commandes suffisent pour une utilisation quotidienne.

Initialement il s’agit d’un logiciel pour Linux, il existe maintenant une version pour Windows.

Attention

L’utitilisation de Git nĂ©cessite certaines notions prĂ©alables:

  • Fonctionnement d’un filesystem

  • Connaissance basique du terminal Linux

  • Potentiellement, un grand nombre de commandes

Indication

GIT est conçu pour les fichiers de type texte, toutefois il fonctionne aussi bien avec des fichiers binaires (images, bureautique, etc.).

Notion de base#

DépÎt - repository

Le rĂ©pertoire cachĂ© .git est nommĂ© dĂ©pĂŽt (repository), il contient toutes les donnĂ©es dont Git a besoin pour gĂ©rer l’historique, seul les commandes Git peuvent modifier son contenu.

Commit

L’historique d’un projet est une sĂ©quence de snapshot contenant l’état de tous les fichiers du projet. Il s’agit des commits qui possĂšdent: - une date - un auteur - une description textuelle

Note

En pratique GIT ne stocke pas la totalitĂ© des fichiers pour chaque commit mais seulement les diffĂ©rences par rapport Ă  l’état suivant. Ceci a pour avantage d’ĂȘtre moins coĂ»teux en stockage.

Copie de travail

Working copy, il s’agit des fichiers prĂ©sents dans le rĂ©pertoire gĂ©rĂ© par Git, leur Ă©tat peut ĂȘtre diffĂ©rent du dernier commit de l’historique.

Index

Il s’agit d’un espace temporaire contenant les modifications prĂȘtes Ă  ĂȘtre « commitĂ©es ». Ces modifications peuvent ĂȘtre une crĂ©ation de fichier, une modification de fichier ou encore une suppression de fichier.

Utilisation de la commande git#

Initialisation d’un dĂ©pĂŽt git dans le rĂ©pertoire courant#
$ git init

Note

Initialise la gestion de version dans un répertoire (le répertoire courant) en créant le sous-répertoire .git

Obtenir des informations sur le statut du dépÎt#
$ git status
Obtenir les détails des changements sur les fichiers du dépÎt#
$ git diff
Ajouter un fichier dans l’index#
$ git add <filename>
Retirer un fichier dans l’index#
$ git reset <filename>
CrĂ©er un commit Ă  partir des modifications ajouter dans l’index, en commentant celui-ci#
$ git commit -m "Ceci est un commentaire pertinent"

Attention

Avant toute utilisation de la commande commit, il convient d’ajouter des Ă©lĂ©ments Ă  l’index via la commande add

Commande git

Visualisation dans l’historique

git commit -m "Initial commit"

../_images/git01.png

git commit -m "Add app.py"

../_images/git02.png

git commit -m "Fix issue on int"

../_images/git03.png
Consulter l’historique#
$ git log
Afficher le dĂ©tail d’un commit particulier#
$ git show <commit-id>
Cycle de vie git

Cycle de vie des commandes git en local#

DépÎt distant#

Un Remote repository est un dépÎt GIT tout à fait similaire à un dépÎt local mais accessible via une URL.

Indication

Un dĂ©pĂŽt local peut ĂȘtre liĂ© Ă  un dĂ©pĂŽt distant

L’utilisation d’un remote repository prĂ©sente l’intĂ©rĂȘt

  • d’une sauvegarde Ă  distance du projet,

  • d’un travail sur plusieurs machines

  • d’un projet accessible facilement

  • et d’une collaboration Ă  plusieurs sur un projet

Cycle de vie git remote

Cycle de vie des commandes git via un dépÎt distant#

Sa mise en oeuvre passe par plusieurs étapes:

  1. Créer un dépÎt sur un serveur (gitlab.com, framagit.org, github.com, etc.)

  2. Cloner un dépÎt distant

  3. Publier des commits

  4. Récupérer les commits

Cloner un dépÎt distant#
$ git clone <repository-url>
Publier des commits#
$ git push <repository-name> <branch-name>

Note

  • repository-name: par dĂ©faut origin

  • branch-name: par dĂ©faut master

Désynchronisation

Le push n’est possible que si la branche locale contient tous les commits de la branche distante.

Si la branche distante contient des commits inconnus en local, il faudra au préalable les récupérer.

Récupérer des commits#
$ git pull

Important

Cette opération copie dans le dépÎt local les commits distants et met à jour la copie de travail.

Pour éviter les problÚmes avec Git#

Quand réaliser un commit ?
  • DĂšs qu’il y a une avancĂ©e du programme qui fonctionne.

  • Ne pas commiter du code qui ne fonctionne pas.

  • Le concepteur de Git, Linus Torvalds, prĂ©conise de commiter le plus souvent possible.

Quand réaliser un push ?
  • DĂšs que des fonctionnalitĂ©s deviennent intĂ©ressante pour les autres membres de l’équipe.

  • Afin de pas perturber les autres membres de l’équipe, il faut Ă©viter de rĂ©aliser des pushs Ă  rĂ©pĂ©tition.

  • Il est possible d’éditer un commit avant qu’il ne soit publiĂ©.

  • Une fois qu’un commit est publiĂ© : il ne peut plus ĂȘtre modifiĂ©.

Ne pas versionner les fichiers inutiles

Tous les fichiers ne doivent pas ĂȘtre soumis au gestionnaire de versions (les fichiers temporaire, le .exe gĂ©nĂ©rĂ© par Visual Studio, etc.)

L’utilisation du fichier .gitignore est plus que recommandĂ© notamment par l’utilisation du site gitignore.io pour gĂ©nĂ©rer un fichier .gitignore de base.

Les branches#

Lors du dĂ©veloppement d’un logiciel, il est primordial d’introduire une nouvelle fonctionnalitĂ© sans « casser » le projet.

On souhaite basculer instantanément de la version stable à la version en développement.

C’est ce que nous permettent de faire les branches.

Note

La branche par dĂ©faut master, l’idĂ©ale serait de ne jamais commiter dans master.

Il convient de créer des branches feature_{x} lorsque une fonctionnalité est développée (dans la réalité, il y a autant de branche feature que de fonctionnalité à developper).

Pour les corrections urgentes, l’utilisation des branches hotfix_{x} est recommandĂ©e.

Ainsi la branche master ne contient que du code propre. Si un utilisateur fait une erreur, il n’impact que sa propre branche : il ne pollue pas l’ensemble du dĂ©pĂŽt.

Création de branche#

$ git branch <NOM>

Depuis la branche parente, souvent master

CrĂ©er une nouvelle branche et passer dessus pour l’utiliser#
$ git checkout -b feature_x
Pour retourner sur master#
$ git checkout master

Fusion de branches#

Le sprint a Ă©tĂ© lancĂ©. Une fonctionnalitĂ© Ă  Ă©tĂ© dĂ©veloppĂ©e, elle est terminĂ©e : il faut donc l’intĂ©grer Ă  la branche master.

Avertissement

La fusion se fait sur la branche courante, pensez Ă  changer de branche avant de fusionner !

Se placer dans la branche réceptrice master#
$ git checkout master
Merger la branche#
$ git merge feature_x

Note

  • Si la branche feature_x n’a pas Ă©tĂ© modifiĂ©e depuis le dĂ©but du dĂ©veloppement de la fonctionnalitĂ© alors Git intĂ©gre les commits de feature_x Ă  master. Il s’agit du merge fast-forward. La branche master et feature_x sont dĂ©sormais Ă©quivalentes, il convient de supprimer feature_x.

  • Si la branche feature_x avait Ă©voluĂ© avant la fin du dĂ©veloppement de la fonctionnalitĂ©. Le merge fast-forward n’aurait pas Ă©tĂ© possible !Un nouveau commit aurait Ă©tĂ© créé par Git pour fusionner les deux branches.

Important

Si on souhaite conserver la branche feature_x distincte de master

$ git merge --no-ff feature_x

Un commit de fusion des deux branches sera créé, l’historique est prĂ©servĂ©.

Branches de développement#

Pour corriger un bug numéroté 1138, nous devons entreprendre les actions suivantes:

  1. CrĂ©ation d’une branche bugfix_1138 Ă  partir de la branche stable (master)

  2. Bascule sur la branche bugfix_1138

  3. Correction du bug (commit/push)

  4. Fusion de la branche bugfix_1138 avec la master via la commande merge

Commande git

Historique git

$ git commit -m "Initial commit"
$ git commit -m "Add app.py"
../_images/git_merge00.png
$ git branch bugfix_1138
$ git checkout bugfix_1138
../_images/git_merge01.png
$ git commit -m 'Fix issue on int'
../_images/git_merge02.png
$ git checkout master
$ git merge bugfix_1138
../_images/git_merge03.png

Une petite mise en jambe avec Git#

Pour obtenir un dépÎt Git sur lequel travailler, deux options sont possibles:

  • CrĂ©ation d’un dĂ©pĂŽt vide,

  • Copie (clone dans le langage Git) d’un dĂ©pĂŽt existant pour travailler sur une copie de travail.

Nous nous intĂ©resserons Ă  la deuxiĂšme option qui fait partie de la vie courante d’un dĂ©veloppeur.

Git a plusieurs interfaces utilisateur, la plus complĂšte Ă©tant l’interface en ligne de commande (CLI) nous nous servirons de celle-ci.

À faire

  • Tout d’abord il convient de crĂ©er un compte sur une forge git comme Gitlab.

  • CrĂ©er un premier repository HelloWorld via l’interface en ligne de Gitlab

  • Cloner ce repository sur votre ordinateur via la commande clone

  • Quel commande utiliser pour afficher le statut de ce dĂ©pĂŽt ?

Attention

Attention Ă  partir de maintenant nous n’utiliserons l’interface web de gitlab uniquement pour constater les changements de donnĂ©es sur notre dĂ©pot distant. Lorsqu’il vous est demandĂ© de crĂ©er des fichiers, il convient de le faire sur votre machine via un Ă©diteur de code.

Astuce

Un fichier readme (en français, lisezmoi) est un fichier contenant des informations sur les autres fichiers du mĂȘme rĂ©pertoire. L’extension .md indique qu’il s’agit d’un fichier formatĂ© en Markdown.

À faire

  • CrĂ©er le fichier README.md

  • Ajouter Ă  ce fichier le contenu suivant:

# HelloWorld

## About

A simple repo for learning git

## Author

Insert your name here

Pour intĂ©grĂ©e dans l’historique des rĂ©visions du dĂ©pĂŽt (pour ĂȘtre « committĂ©e »), chaque modification doit suivre le workflow suivant:

Note

  1. La modification est d’abord effectuĂ©e sur la copie de travail;

  2. Elle est ensuite mémorisée dans une aire temporaire nommée index avec la commande git add;

  3. Enfin ce qui a Ă©tĂ© placĂ© dans l’index peut ĂȘtre « committé » avec la commande git commit

https://www.plantuml.com/plantuml/svg/JSyn2y8m40NWFR_YqRqEWej3AGYYYuEByvcS9JJ9bUGA-kzDjKF7U-zxm_L5AUiSWocM0cE_EvWo-ZHHfeWdsN78CYTd9KY6PagbLfnqeno_Q0vwbgGtYenBNHa3e7b8hch0IQPF0ofOW-L6sm7NvFXznE0LvDoo-ILeQxcnVv6vi6vCXpjFKhnANeML6BsQdfEhBtq1

Diagramme UML du Workflow d’une modification avec Git#

VĂ©rifiez avec git status l’état dans lequel se trouve votre dĂ©pĂŽt. Vos modifications (l’ajout du fichier README.md) devraient ĂȘtre prĂ©sentes seulement dans la copie de travail.

À faire

  • PrĂ©parez README.md pour le commit avec git add README.md.

  • Utilisez git status Ă  nouveau pour vĂ©rifier que les modifications ont bien Ă©tĂ© placĂ©es dans l’index.

  • Commitez votre modification avec git commit -m "<votre_message_de_commit>". Le message entre double quotes dĂ©crira la nature de votre modification (gĂ©nĂ©ralement infĂ©rieur Ă  65 caractĂšres).

  • ExĂ©cutez Ă  nouveau:code:git status, pour vĂ©rifier que vos modifications ont bien Ă©tĂ© commitĂ©s.

  • Essayez Ă  prĂ©sent la commande git log pour afficher la liste des changements effectuĂ©s dans ce dĂ©pĂŽt ; combien y en a-t-il ? Quel est le numĂ©ro (un hash cryptographique en format SHA1) du dernier commit effectuĂ© ?

Vos modifications sont prises en compte dans votre dĂ©pĂŽt local, toutefois via la commande git status vous pouvez remarquer que le commit n’est pas publiĂ© sur le dĂ©pĂŽt distant.

https://www.plantuml.com/plantuml/svg/JP2x3i8m34NtV8NLlGn8B0nL9IG42qCNPjEOKhM9ezYHuEz97uXwoxddMbPgKOoQt6YanP5WlpiO6NeVCAA31xP35pbvs_B84JIYbnoHrurbwObfr3DxlQ4ZkEIMCP2dk7FCMWSd3fy2K605qnlA2k3gBRsFqFKAQErScX6KETt8Yn99IBTI1Gq5bbuvhahBplMByuyciMZ8iLBUyQFpGGkTrAKVahoCgSdR_2bV

Diagramme UML du Workflow d’une modification avec Git#

À faire

  1. Publiez votre commit avec git push origin master. Que signifie origin et master ?

  2. Exécutez à nouveau git status, pour vérifier que votre commit a bien été publié.

Une histoire de Burger

Dans note repository nous allons créer un répertoire sandwich qui contiendra le fichier burger.txt.

Le fichier burger.txt contient la liste des ingrĂ©dients d’un burger, un ingrĂ©dient par ligne.

steak
salade
tomate
cornichon
fromage

À faire

  • Comment vĂ©rifier que ce fichier n’est pas versionnĂ© ?

  • Comment l’ajouter Ă  l’index ?

  • Comment le « committer » ?

  • Comment publier ce commit ?

À faire

Créez quelques autres sandwichs hot_dog.txt, jambon_beurre.txt et modifiez les compositions déjà créés, en committant chaque modification séparément.

Chaque commit doit contenir une et une seule création ou modification de fichier. Effectuez au moins 5 modifications différentes (et donc 5 commits différents).

À chaque Ă©tape essayez les commandes suivantes :

  • git diff avant git add pour observer ce que vous allez ajouter Ă  l’index;

  • git diff --cached aprĂšs git add pour observer ce que vous allez committer.

Regardez maintenant l’historique des modifications avec git log et vĂ©rifiez avec git status que vous avez tout commitĂ©.

Voyage dans le temps

Vous voulez changer d’avis entre les diffĂ©rents Ă©tats de la Figure sur l’état des modifications ? Faites une modification d’un ou plusieurs sandwichs, ajoutez-la Ă  l’index avec git add (vĂ©rifiez cet ajout avec git status ), mais ne la commitez pas. ExĂ©cutez git rest sur le nom de fichier (ou les noms de fichiers) que vous avez prĂ©parĂ©s pour le commit ; vĂ©rifiez avec git status le rĂ©sultat.

À faire

  • Votre modification a Ă©tĂ© « retirĂ©e » de l’index.
    • Vous pouvez maintenant la jeter Ă  la poubelle avec la commande git checkout sur le ou les noms des fichiers modifiĂ©s, qui rĂ©cupĂšre dans l’historique leurs versions correspondant au tout dernier commit.

    • Essayez cette commande, et vĂ©rifiez avec git status qu’il n’y a maintenant plus aucune modification Ă  commiter.

  • Regardez l’historique de votre dĂ©pĂŽt avec git log ;
    • choisissez dans la liste un commit (autre que le dernier).

    • ExĂ©cutez git checkout COMMITID oĂč COMMITID est le numĂ©ro de commit que vous avez choisi.

    • VĂ©rifiez que l’état de vos sandwichs est maintenant revenu en arriĂšre, au moment du commit choisi.

    • Que dit maintenant git status ?

  • Vous pouvez retourner Ă  la version plus rĂ©cente de votre dĂ©pĂŽt avec git checkout master.

  • VĂ©rifiez que cela est bien le cas. Que dit maintenant git status ?