Table des matières

Partie 1 - Premier pas avec Git

1. Qu’est ce que versionner son code

Dans ce cours, vous allez prendre en main Git, un outil qui va vous permettre de versionner votre code, c’est-à-dire gérer les versions de votre code au fur et à mesure que vous le modifiez.

Pourquoi versionner votre code ?

Lorsque vous travaillez sur un projet de code, vous allez régulièrement y apporter des modifications, et par moments ces modifications vont provoquer des bugs. Lorsque vous revenez sur votre projet après quelques jours ou même quelques heures, il peut être difficile de vous souvenir des dernières modifications que vous avez effectuées et de retrouver vos repères dans votre code.

Avec un logiciel de versioning comme Git, vous pouvez garder la trace de toutes les modifications faites sur votre code pour pouvoir vous y retrouver à tout moment. À chaque fois que vous faites une série de modifications (créer un fichier, supprimer un fichier, modifier un texte dans un fichier, etc.), vous allez pouvoir enregistrer ces modifs dans un commit.

Par exemple, si vous travaillez sur un formulaire de newsletter en ligne :

Un commit correspond donc à une version de votre code à un instant t. La somme de tous les commits constitue l’historique de votre projet. Et l’intérêt d’un logiciel de versioning comme Git, c’est que vous pouvez vous placer à n’importe quel endroit de cet historique. En cas de bug par exemple, ou lorsque vous êtes plusieurs à travailler sur un même projet, revenir en arrière sur une précédente version du code peut s’avérer bien utile… tellement utile qu’utiliser un logiciel de versioning est considéré comme une habitude indispensable pour tout développeur digne de ce nom !

Comme dit Jeff Atwood, un développeur très actif qui a notamment créé Stack Overflow, un forum d’entraide pour les développeurs que vous serez souvent amenés à utiliser lorsque vous vous poserez des questions dans vos projets de code : Si le code n’est pas enregistré dans un logiciel de gestion de version, il n’existe pas.

2. Git par rapport aux autres solutions de versioning

Il existe de nombreux logiciels de gestion de version, qui peuvent être basés sur différents modèles :

Moins de risques de perdre son code puisqu’il est accessible par plusieurs sources. On peut travailler plus rapidement et sans être connecté à Internet puisqu’il n’y a pas besoin de se connecter à un serveur central. En plus des avantages du modèle distribué, Git a un autre atout : une grande communauté ! Cela facilite la collaboration et les échanges fructueux entre développeurs.

3. Faites votre premier commit

Pour commencer, créez un nouveau dossier et positionnez vous dedans avec la console. Vous ne voulez pas versionner l’intégralité de votre ordinateur en lançant git init dans un dossier comme “Mes Documents” ou “Applications” !

Une fois que vous vous êtes placés dans votre nouveau dossier grâce à la commandec cd de votre Terminal, créez un nouveau dossier “monPremierRepo” en lançant la commande suivante :

mkdir monPremierRepo

Ce dossier est souvent appeler le “repository”, c’est-à-dire le répertoire de travail géré par Git. Voici un petit résumé des étapes à suivre :

git add checklist-vacances.md

*Pour gagner du temps, vous pouvez ajouter tous les fichiers dans le répertoire courant en tapant

git add . 

dans la console. Évidemment, faites bien attention quand vous utilisez ce raccourci à ne pas rajouter trop de fichiers à l’index.*

git commit -m "Ajouté ma checklist-vacances.md"

Bravo, vous avez effectué votre premier commit ! Voyons ce qui se passe lorsque vous en aurez fait plein et que vous aurez besoin de remonter dans le temps…

4. isez l’historique

Vous savez enregistrer les modifications de votre repository avec la commande git commit. Au cours d’un projet, vous allez être amenés à faire beaucoup de modifications.

Comment vous y retrouver dans l’historique de vos commits ? Grâce à la commande git log qui vous affiche la liste de tous les commits que vous avez réalisés !

Dans la liste de cet historique, chaque commit est répertorié avec :

Petite astuce

Jusqu’ici, lorsque vous mettez à jour un fichier dans votre repository, vous devez procéder en deux étapes :

Ajouter votre fichier à l’index avec la commande git add, git add checklist-vacances.md Faire un commit qui décrit la mise à jour de votre fichier avec la commande git commit. git commit -m "Ajouté itinéraire dans checklist-vacances.md" Et bien, si vous ne faites que mettre à jour un fichier que vous aviez déjà ajouté à l’index, vous pouvez condenser ces deux étapes de la façon suivante :

git commit -a -m "Ajouté itinéraire dans checklist-vacances.md"

L’option -a demande à Git de mettre à jour les fichiers déjà existants dans son index

5. Positionnez-vous sur un commit donné

Lorsque vous effectuez une série de commits sur un projet, il peut vous arriver de vouloir remonter dans le temps à la recherche d’erreurs éventuelles par exemple. Pour vous positionner sur un commit donné de votre historique, il vous suffit d’utiliser la commande git checkout de la façon suivante :

git checkout SHADuCommit

Pour revenir à votre derniere version de votre projety (au commit le plus récent), on utilise la même commande :

git checkout master

Astuce

On ne peut pas vraiment “supprimer” un commit, mais on a plusieurs options pour l’annuler. Cependant, ces options ont des limites et sont à utiliser avec prudence et parcimonie !

Voici une de ces options : vous pouvez “revert” un commit, c’est-à-dire créer un nouveau commit qui fait l’inverse du précédent, avec la commande suivante :

git revert SHADuCommit

Sinon, si vous voulez simplement modifier le message de votre dernier commit, vous pouvez utiliser la commande suivante :

git commit --amend -m "Votre nouveau message"

Enfin, si vous voulez annuler tous les changements que vous avez fait et que vous n’avez pas encore commités. c’est possible avec un reset.

git reset --hard

Partie 2 - Prenez Gihub en main

1. Découvrez les remotes

Lorsque vous travaillez sur un projet sur votre machine, il est important d’avoir un backup de votre code sur une autre machine, au cas où la vôtre tombe en panne par exemple. Une fois que vous avez travaillé sur votre code et effectué vos commits, vous allez donc les envoyer sur un remote, c’est-à-dire une autre machine qui peut être :

2. GitHub, qu’est-ce que c’est ?

Comme nous l’avons vu dans le chapitre précédent, GitHub est un service en ligne qui permet d’héberger ses repositories de code. GitHub est un outil gratuit pour héberger du code open source, et propose également des plans payants pour les projets de code privés. C’est le numéro 1 mondial et il héberge plus d’une dizaine de millions de repositories !

Pour créer votre compte GitHub, rendez-vous sur sa page d’accueil où vous pourrez entrer un nom d’utilisateur, un mot de passe, etc. Une fois votre compte créé, vous aurez accès à votre dashboard et découvrirez toutes les fonctionnalités de GitHub. Vous allez pouvoir notamment :

3. Récupérez du code d’un autre repository

À partir de GitHub, vous pouvez copier un repository sur votre machine. Pour cela, il vous suffit de rechercher le repository qui vous intéresse sur GitHub, de vous y placer, puis d’utiliser l’option “clone URL” en bas à droite de l’écran.

Cette option vous propose un lien SSH, HTTPS ou Subversion. Ici, nous allons choisir un lien HTTPS, le copier, puis coller ce lien en utilisant la commande git clone dans le dossier que vous aurez choisi sur votre machine :

git clone lienFourniParGitHub 

Par example, vous pouvez cloner le repo de la librairie Chart.js, une librairie permettant d’afficher des graphiques en JavaScript. Effectuez alors la commande suivante

git clone https://github.com/chartjs/Chart.js.git

4. Créez votre premier repository

Vous avez vu comment récupérer un repository partagé sur GitHub. À votre tour de partager vos projets sur GitHub ! Vous allez voir ici comment créer un repository sur votre compte GitHub.

C’est parti pour créer votre premier repository open-source . Tout d’abord, si ce n’est pas déjà fait, connectez-vous à votre compte GitHub. Cliquez sur le bouton “Create new” symbolisé par un signe “+” en haut à droite de votre écran, puis “New repository”.

GitHub vous demandera alors de préciser quelques détails sur votre repository:

Vous avez également une option “Initialise with a README”, qui vous permet de cloner votre repository sur votre machine. Cette option est à cocher uniquement dans le cas où vous n’avez pas encore créé le repository en question sur votre machine (ce qui est bien notre cas ici, cohcez cette case).

Et voilà, vous avez créé votre premier repository sur GitHub ! Vous pouvez maintenant :

5. Envoyez votre code sur GitHub

Vous avez clôné votre repo GitHub sur votre machine. Comment faire pour synchroniser les modifications que vous faites dans votre repo sur votre machine avec votre repo sur GitHub ?

git push origin master

Cette commande demande à Git : “Envoie mes modifs dans la branche master de mon remote origin.”

Une fois que vous avez “pushé” votre code en ligne, vous pouvez aller consulter votre repo sur GitHub. Vous y retrouverez les derniers commits effectués en cliquant sur l’option “Commits” dans votre repo :

Vous pouvez voir l’historique de vos commits, comme la commande git log, mais dans une interface graphique plus agréable qui vous permet de cliquer sur chaque commit et de voir les modifications associées dans chaque fichier.

6. Récupérez des modifications

vous avez vu comment envoyer vos modifications locales vers votre repo GitHub avec git push. Mais si vous modifiez votre repo GitHub en ligne, ou si vous travaillez avec d’autres personnes dessus et qu’elles envoient leurs modifications locales sur le repo en ligne, votre code local ne sera plus à jour.

Pour récupérer en local les dernières modifications du repo GitHub, il vous faut utiliser la commande git pull :

Vous reconnaissez la même syntaxe que pour la commande git push, qui demande ici à GitHub : “Envoie dans mon répertoire local les dernières modifications de la branche master située sur mon remote origin (qui correspond ici à GitHub).”

Pensez à synchroniser régulièrement votre code local avec vos repos en ligne à l’aide des commandes git push et git pull. C’est particulièrement important lorsque vous travaillez à plusieurs sur un projet, pour que tout le monde avance sur la même base !

7. Resolvez des conflits

Lorsque plusieurs utilisateurs souhaitent modifier un même fichier, des conflits peuvent apparaitre. Il arrive très souvent qu’il y aie des conflits, qui empêchent de fusionner les modifications effectuées sur un fichier, par exemple lorsque plusieurs personnes travaillent en même temps sur un même fichier.

Exemple : Votre repo contient un fichier Hello.md avec une ligne de texte : “Hello les amis !”. Un collègue A remplace le contenu du Hello.md par la ligne de texte “Hello tout le monde !”, effectue un git commit et un git push, tandis que le collègue B remplace le contenu du Hello.md par la ligne de texte : “Hello!”. AU moment ou le collègue B va vouloir pusher ses modifications, il va y avoir un conflit de version de document.

Git va reconnaître qu’il existe un conflit entre les fichiers. Vous allez alors avoir deux possiblités pour résoudre ce conflit:

Auto-merging hello.md
CONFLICT (content): Merge conflict in hello.md
Automatic merge failed; fix conflicts and then commit the result.

Vous allez donc devoir ouvrir le fichier hello.md dans votre éditeur de texte. Vous pouvez le faire à partir du terminal avec la commande : nano hello.md

Vous allez alors voir les différences de contenu du fichier hello.md entre les dexu versions, et vous pouvez choisir quel contenu garder. Par exemple, vous pouvez garder “Hello les amis”, sauvegarder le fichier et revenir dans la console.

Maintenant que vous avez résolu le conflit, il vous reste à le dire à Git ! Car pour l’instant, si vous faites un git status, git vous dira que vous avez des fichiers modifiés (“unmerged paths”). Pour cela, faites un commit sans message :

git commit

Git va détecter que vous avez résolu le conflit et vous proposer un message de commit par défaut que vous pourrez modifier si necessaire.

Une fois le message enregistré, git va alors vous confirmer que votre push est effectif, et si vous consulter l’historique des commits avec git log, vous verrez apparaître le dernier commit.

8. Un petit exercice

Cet exercice a pour objectif de mettre en pratique les notions que vous avez acquises sur Git et Github.

Vous devez créer un repository Git simple contenant :

Partie 3 - Collaborez et maitrisez votre historique

1. Créez des branches

Un élément que vous allez être souvent amenés à utiliser lorsque vous travaillez sur un repo, ce sont les branches. Les branches permettent de travailler sur des versions de code qui divergent de la branche principale contenant votre code courant.

À quoi ça sert de créer des variations de la branche principale ? Travailler sur plusieurs branches est très utile lorsque vous souhaitez tester un expérimentation sur votre projet, ou encore pour vous concentrer sur le développement d’une fonctionnalité spécifique.

Voyons les commandes Git qui vous permettent de manipuler les branche.

git branch new-branch

Pour vous placer dans une autre branche à l’intérieur de votre repo, vous allez avoir besoin d’un nouveau mot-clé : checkout

git checkout new-branch

Astuce

Petite astuce pour manipuler vos branches : vous pouvez utiliser la commande git checkout -b pour créer une branche et vous y positionner. Ainsi, au lieu de taper la commande suivante pour créer votre branche :

git branch my-branch

, puis une deuxième commande pour vous y positionner :

git checkout my-branch

, vous pouvez regrouper ces deux opérations en une seule commande :

git checkout -b my-branch

2. Fusionnez des branches

Lorsque vous travaillez sur plusieurs branches, il va souvent vous arriver de vouloir ajouter dans une branche A les mises à jour que vous avez faites dans une autre branche B. Pour cela, on se place dans la branche A :

git checkout brancheA

Puis on utilise la commande git merge :

git merge brancheB

Fusionner des branches est une pratique courante lorsque vous travaillez sur un projet : vous devez toujours chercher à remettre les modifications faites sur vos différentes branches dans la branche principale master.

3. Résolvez un conflit

Vous avez vu dans le chapitre précédent comment fusionner des branches. Nous avons utilisé un exemple assez simple où tout s’est bien passé. Mais il arrive très souvent qu’il y aie des conflits entre les deux branches qui empêchent de les fusionner, par exemple lorsque plusieurs personnes travaillent en même temps sur un même fichier.

Exemple : votre branche master contient un fichier Hello.md avec une ligne de texte : “Hello les amis !”. Votre branche universal contient un fichier Hello.md avec une ligne de texte : “Hello tout le monde !”.

Si vous tentez de fusionner la branche universal dans la branche master :

git checkout master
git merge universal

Git va reconnaître qu’il existe un conflit entre les deux branches car la 1re ligne du fichier Hello est différente dans chacune des branches et afficher le message suivant :

Auto-merging hello.md
CONFLICT (content): Merge conflict in hello.md
Automatic merge failed; fix conflicts and then commit the result.

Vous allez donc devoir ouvrir le fichier hello.md dans votre éditeur de texte. Vous pouvez le faire à partir du terminal avec la commande : nano hello.md

Vous allez alors voir les différences de contenu du fichier hello.md entre les deux branches, et vous pouvez choisir quel contenu garder pour la branche master dans laquelle vous faites le merge. Par exemple, vous pouvez garder “Hello les amis”, sauvegarder le fichier et revenir dans la console.

Maintenant que vous avez résolu le conflit, il vous reste à le dire à Git ! Car pour l’instant, si vous faites un git status, git vous dira que vous avez des branches non fusionnées (“unmerged paths”). Pour cela, faites un commit sans message :

git commit

Git va détecter que vous avez résolu le conflit et vous proposer un message de commit par défaut que vous pourrez modifier si necessaire.

Une fois le message enregistré, git va alors vous confirmer que vos branches ont été fusionnées, et si vous consulter l’historique des commits avec git log, vous verrez apparaître le dernier commit de résolution du conflit avec le message :

*Merge branch ‘universal’ Conflicts: hello.md *

4. Retrouvez qui a fait une modification

our retrouver qui a modifié une ligne précise de code dans un projet, faire une recherche avec git log peut s’avérer compliqué, surtout si le projet contient beaucoup de commits. Il existe un autre moyen plus direct de retrouver qui a fait une modification particulière dans un fichier : la commande git blame.

git blame nomdufichier.extension

Cette commande liste toutes les modifications qui ont été faites sur le fichier ligne par ligne. À chaque modification est associé le début du sha du commit correspondant. Par exemple :

^05b1233 (Marc Gauthier 2014-08-08 00:31:02 1) # Une liste

Pour retrouver pourquoi cette modification a été faite, vous avez deux possibilités :

git show 05b1233

5. Évitez des commits superflus

Imaginez le scénario suivant : vous êtes en train de travailler sur une fonction, lorsque tout à coup une urgence survient et un collègue vous demande de résoudre un bug dans un autre fichier et/ou une autre branche.

Si vous faites un commit des modifications sur votre fonction à ce stade, cela va alourdir votre historique car vous n’avez pas terminé votre tâche.

Comment faire pour ne pas perdre vos modifications en cours avant de passer à l’urgence à traiter ? Et bien vous pouvez mettre de côté vos modifications en cours avec la commande :

git stash

Vous pouvez alors vous rendre dans la branche/le fichier que vous devez traiter à l’instant, finir et committer vos modifs. Une fois que vous avez réglé cette urgence, revenez sur la branche sur laquelle vous étiez en train de travailler, et récupérez les modifications que vous aviez mises de côté avec la commande :

git stash pop

Attention, pop vide votre stash des modifications que vous aviez rangées dedans. Donc une fois que vous avez récupéré ces modifications dans votre branche, il vous faut finir votre tâche et les committer ! (ou bien les remettre de côté en exécutant à nouveau la commande git stash).

Si vous voulez garder les modifications dans votre stash, vous pouvez utiliser apply à la place de pop :

git stash appply

Mini projet

Appeler votre professeur pour passer au miniprojet

IF110 - project

IF110 - tree

Pour pouvoir avoir les droits de publications (push) sur le projet tree vous devez demander à votre enseignant de vous ajouter dans les contributeurs du projet. Envoyez votre identifiant GitHub avec votre demande. Si vous ne recevez pas le mail d’invitation une fois inscrit, vous pouvez cliquer sur le lien suivant.

https://github.com/EnseirbTelecom/IF110-project/invitations

Pour les plus avancé(e)s

Maitrisez le systeme de branching de git avec le jeu interactif en ligne.