Dans ce premier article d’une petite série “Apprendre Git”, on va parler … de Git. Git est un outil très populaire qui est devenu pratiquement indispensable dans tout workflow moderne de développement. Git est un outil puissant mais qui peut être intimidant pour le non-initié.
Dans cet introduction, on va faire de vous des initiés ! On va ensemble créer notre premier dépôt local, et faire connaissance avec cet outil pour le comprendre et le démystifier un peu.
Qu’est-ce que Git ? A quoi ça sert ?
Dans le monde des développeurs, tout le monde parle de Git, et connaitre Git est effectivement un pré-requis pour travailler efficacement avec la grande majorité des équipes de développement.
Git est un logiciel de contrôle de version. Le but est de pouvoir tracker et valider ou non chaque modification que vous allez effectuer à votre projet, et de conserver un historique des modifications, dans le but de contrôler au maximum sa qualité et de pouvoir développer pas à pas dans un environnement de développement plus sécurisé. En cas de souci, on peut restaurer un projet à un état antérieur beaucoup plus facilement.
Dans son utilisation la plus basique (celle qu’on va étudier aujourd’hui), Git permet de voir les changements effectués dans un dossier et de les valider ou non avant de passer au développement de la fonctionnalité suivante. En cas de pépin, vous pourrez simplement revenir à une version antérieure sans vos changements qui ont tout cassé et repartir sur une base saine.
Installer Git
Dans cet article, on va utiliser Git en ligne de commande. On ne va pas télécharger de GUI (Graphical User Interface ou interface graphique). Juste la ligne de commande. Pas de panique, ce n’est pas si compliqué.
Pour installer Git, rendez-vous sur https://git-scm.com/ et téléchargez simplement le package correspondant à votre OS. Par exemple, je suis sur Linux, donc en me rendant sur https://git-scm.com/download/linux, je peux voir que je peux installer le package Git avec une seule commande : sudo apt-get install git
.
Une fois le package installé, la commande git
devrait être disponible dans votre terminal.
Il existe des GUIs pour Git, mais honnêtement, je pense que dans un premier temps, c’est beaucoup mieux de passer par la ligne de commande. Les GUIS sont des outils qui vont abstraire les choses et donc cacher le fonctionnement interne de l’outil. Si vous voulez vraiment comprendre comment ça marche, le mieux est d’éviter les GUIs.
On va donc ouvrir un terminal et tester. N’importe quel terminal fera l’affaire.
git --version
Si l’installation s’est bien déroulée, vous devriez avoir le numéro de la version installée, comme ci-dessous :
Si vous avez besoin d’aide générale ou sur une commande particulière, utilisez git --help
ou git --help [COMMANDE]
. Par exemple, git help commit
permet de lire la documentation de la commande commit
, et donne ceci :
Notre projet fictif
Git est installé, on est prêt à l’utiliser. Pour cet exemple, on va travailler sur un projet fictif, qui est un micro-site constitué simplement d’une seule page HTML.
Pour le moment, notre unique fichier index.html
contient ce qui suit :
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Apprendre Git</title>
</head>
<body>
<main>
<div class="wrapper">
<h1>Apprendre Git</h1>
</div>
</main>
</body>
</html>
En gros, on a juste un titre pour le moment. Rien de bien compliqué.
Utiliser Git
Initialiser le dépôt
Pour mettre en place notre contrôle de version, il faut initialiser un dépôt. Un dépôt est simplement un dossier, qui sera sous contrôle. Une fois le dépôt initialisé, Git est prêt et va détecter les modifications et ajouts de fichiers dans ce dépôt. Ensuite vous pourrez valider ou non les changements et commencer à tracker les différentes versions et l’historique de votre projet.
Pour initialiser un dépôt, on utilise la commande git init
. Dans notre terminal, on se place donc dans le dossier que l’on souhaite placer sous contrôle de version avec cd
et on utilise git init
pour préparer le dépôt.
cd /Projects/"intro to git"/example
git init
La console nous dit qu’on peut changer le nom de la branche par défaut avec git config
. On parlera des branches dans la partie 2 de cette introduction.
Pour le moment, retenez qu’une branche est simplement une version de notre projet. On peut créer plusieurs branches qui vont plus ou moins diverger de la branche principale master
, qui est censée contenir le code le plus récent. Quand les fonctionnalités développées dans nos branches sont prêtes, on les fusionne avec la branche principale. Pas de panique, on verra ça plus tard.
La commande git init
crée simplement un dossier caché .git
qui contient les informations dont Git a besoin pour travailler.
Configurer Git
git config
permet de configurer votre utilisation de Git, en spécifiant votre nom d’utilisateur et votre email, et tout un tas d’autres réglages.
Aussi, vous pouvez disposer de réglages globaux (applicables à tous vos projets) ou locaux (spécifiques au dépôt courant).
git config --global user.name "Vincent Dubroeucq"
git config --global user.email "vincent@vincentdubroeucq.com
Ces commandes permettent de spécifier votre nom et votre email, à utiliser de manière globale. Quand, plus tard, vous partagerez votre dépôt avec vos collaborateurs, ces informations apparaîtront sur vos commits.
Pour le moment, cela suffit. Votre configuration est sauvegardée dans un fichier .gitconfig
qui sera placé soit parmi vos fichiers système ou dans votre dossier .git
, si les réglages sont locaux.
Vérifier l’état du dépôt avec git status
La commande git status
est une commande très utile que vous allez utiliser tout le temps. Elle permet d’obtenir des informations sur l’état actuel du dépôt.
Dans mon terminal, si j’entre la commande git status
, j’obtiens ce qui suit :
La commande me dit :
- que je travaille actuellement sur la branche
master
- que j’ai des fichiers non-suivis (qui ne sont pas encore placés sous contrôle)
- qu’aucun fichier n’est ajouté à la validation
Git me suggère même d’ajouter les fichiers non-suivis à l’aide de git add
. On en parlera dans un instant.
Pour le moment, index.html
n’est pas encore tracké par Git. Il a juste détecté qu’il y avait un fichier, et que ce fichier ne faisait pas partie des fichiers qu’il est censé tracker.
Notre premier commit: git add
et git commit
Pour valider nos changements, on va créer un commit. Un commit est simplement une référence pointant vers une version de notre projet.
A chaque fois que vous allez ajouter de nouvelles fonctionnalités ou corriger un bug, vous allez créer un commit pour valider vos changements, et pour que vous ou vos collaborateurs puissiez avoir une vision claire de l’historique des modifications du projet.
Avant de créer notre premier commit, il faut dire à Git quels fichiers et modifications prendre en compte pour ce commit. Pour le moment, Git a détecté un fichier non-suivi. Il faut dire à Git “oui, je veux que tu suives ce fichier et ses modifications futures“.
Pour cela, on utilise la commande git add [NOM DU FICHIER]
git add index.html
Si tout se passe bien, vous n’aurez aucun feedback. Et ce n’est pas nécessaire en fait. Maintenant, si on entre de nouveau git status
, l’état du dépôt a changé.
Nous sommes toujours sur la banche master
, sans aucun commit pour le moment. Par contre, le fichier index.html
est maintenant suivi par Git et prêt à être validé.
Notre fichier est en staging-area, ou staging. C’est-à-dire qu’il est prêt à être validé.
Vous remarquerez que Git nous indique comment ne plus indexer un fichier si un fichier a été ajouté par erreur, en utilisant git rm
(pour remove).
On va créer notre premier commit avec :
git commit --message "Initial commit"
L’option --message
, suivi d’un message clair, permet à votre futur vous ou vos collaborateurs de décrire brièvement les changements effectués dans ce commit.
Vous pouvez raccourcir la commande en utilisant -m
au lieu de --message
.
git commit -m "Initial commit"
est équivalent.
Nos changements sont validés ! Maintenant on a un commit enregistré, et on peut en cas de souci restaurer notre projet dans l’état où il était à ce commit !
Techniquement, git add
permet d’ajouter des fichiers à un index utilisé pour créer un snapshot de l’état de votre projet et git commit
permet de créer une référence vers cet index à cet instant.
Pour simplifier, retenez que git add
permet d’ajouter des fichiers en staging, et que git commit
crée un commit pour valider les changements mis en staging.
git status
nous informe que désormais, nous n’avons aucun changement à valider et que notre copie de travail est propre.
Maintenant, nous sommes prêts à ajouter nos premières modifications.
Nos premières modifications
On va simplement ajouter une feuille de style à notre document HTML.
On ajoute un fichier style.css
avec ce contenu à la racine du projet :
/* style.css */
h1 {
text-align: center
}
Et dans index.html
, on va ajouter la balise <link>
pour charger cette feuille de styles.
<!-- index.html -->
<!DOCTYPE html>
<html lang="fr">
<head>
...
<link rel="stylesheet" href="style.css">
</head>
<body>
...
</body>
</html>
Dans notre terminal, si on entre git status
, on a ceci :
Git a bien détecté qu’un des fichiers déjà suivis (index.html
) a été modifié et a trouvé un fichier non-suivi (style.css
), mais aucune modification n’est prête à être validée (rien en staging).
Consulter les différences avec git diff
Pour consulter les différences entre les fichiers, on peut utiliser git diff
. C’est une commande très utile qui permet de visualiser vos changements et comparer plusieurs commits.
Sans paramètre, git diff
compare votre copie de travail actuelle avec le dernier commit.
Git nous indique la nouvelle ligne dans index.html
, mais ne nous indique pas qu’il y a un nouveau fichier. C’est simplement parce que ce fichier n’a pas encore été ajouté avec git add
, et donc il est pour le moment ignoré.
Pour ajouter nos deux fichiers en staging, on peut soit les ajouter individuellement avec deux commandes git add
ou alors utiliser git add --all
.
On peut aussi utiliser git add .
, ou le “.” représente le dossier courant. Si dans notre terminal on est situé à la racine de notre projet, on va donc ajouter tout notre projet. C’est juste un moyen rapide d’ajouter d’un coup tous nos fichiers en staging.
git add .
git status
Vous remarquerez qu’à chaque git status
, Git nous aiguille en nous fournissant la commande à utiliser pour retirer un fichier de la zone de staging.
Maintenant, on peut valider nos changements avec git commit -m "Added stylesheet"
.
Annuler des changements avant un commit avec git restore
Imaginons que vous ayez ajouté plusieurs dizaines de lignes dans index.html
et dans style.css
pour tester une navigation, mais qu’au final, vous abandonniez cette navigation pour essayer autre chose.
Vous avez besoin d’abandonner vos changements et de restaurer vos fichiers dans l’état où ils étaient au dernier commit.
git status
nous indique que nos fichiers ont été modifiés et git diff
va nous dire ce qui a changé précisément.
Pour restaurer un fichier à son état au dernier commit, utilisez git restore [NOM DU FICHIER OU DOSSIER]
git restore index.html
git restore style.css
Mais si vous avez modifié des dizaines de fichiers, et que vous souhaitez tous les restaurer, utilisez git restore .
pour restaurer tous les fichiers du dossier courant.
git restore .
Après cette commande, toutes nos modifications ont été annulées !
Si vous avez déjà ajouté vos changements en staging, vous pouvez les enlever du staging en ajoutant le flag --staged
, comme ceci : git restore --staged [NOM DU FICHIER OU DOSSIER]
git restore --staged index.html
git restore --staged style.css
Par contre, les enlever du staging n’annule pas vos modifications. Vous pouvez donc utiliser de nouveau git restore
, ou alors pour enlever des fichiers du staging ET annuler vos changements, vous pouvez utiliser git restore --staged --worktree [NOM DU FICHIER OU DOSSIER]
git restore --staged --worktree .
Cette commande annule tout : mise en staging ET modifications.
Annuler un commit
Imaginons que vous venez juste de faire un commit, mais vous vous rendez compte que vous avez fait une erreur, et vous aimeriez restaurer le projet à un état antérieur.
La situation est un peu plus compliquée ici. Trois commandes peuvent être utilisées :
git revert
permet de créer un nouveau commit, qui va annuler les changements d’un autre commit.git restore
, qu’on a déjà utilisé, permet de restaurer des fichiers du dernier commit, mais on peut prendre aussi ces fichiers de n’importe quel commit. Ce qui signifie qu’on peut aller récupérer un fichier plus ancien pour le remettre dans la copie de travail actuelle.git reset
peut être utilisé pour annuler des commits. Mais cette commande modifie l’historique de vos commits, alors quegit revert
ajoute un commit etgit restore
manipule uniquement les fichiers, sans créer de commit.
On va considérer que votre copie de travail est propre (vous n’avez aucune modification non-validée).
Le plus simple est d’utiliser git revert
, qui va créer un nouveau commit de correction. Mais il faut savoir quel commit annuler.
En utilisant git log
, vous pouvez voir la liste de vos commits :
Il y a plusieurs façons de faire référence à des commits, mais le plus simple est de copier l’identifiant du commit. Dans notre exemple, on veut annuler le commit 5dabd208308d9a5a5136fa2ac3e99f016b5a9e15
.
Je peux annuler ce commit de ces deux façons :
git revert --no-commit 5dabd208308d9a5a5136fa2ac3e99f016b5a9e15
git revert 5dabd208308d9a5a5136fa2ac3e99f016b5a9e15
En utilisant le flag no-commit
, le nouveau commit de correction n’est pas validé. Votre copie de travail est restaurée avant le commit à annuler et les changements sont automatiquement mis en staging.
Vous pouvez le voir en utilisant git status
Vous pouvez soit valider le commit, soit annuler la procédure avec git revert --abort
.
Comme vous pouvez le voir, Git nous aide beaucoup, en nous suggérant toutes les commandes pertinentes.
Il se peut que Git ne sache pas décider quelle version de votre code est celle qu’il doit garder. On parle de “conflit”. S’il y a un conflit, vous devrez choisir le code à garder avant de poursuivre. On parlera plus des conflits dans la prochaine partie de cette introduction, dans un autre article.
Pour le moment, je n’ai pas de conflit, donc je peux valider mon commit avec git commit -m "Revert navigation"
.
Et voilà !
Une autre façon de faire est en utilisant git restore --source=[ID DU COMMIT]
pour restaurer les fichiers de votre copie de travail local à un commit antérieur.
Annuler un commit, mais en gardant ses modifications
Pour simplifier, on a considéré que votre copie de travail était propre et ne contenait aucune modifications.
Si ce n’était pas le cas et que vous aviez déjà des modifications, restaurer un ancien commit va supprimer vos modifications actuelles.
Pour éviter de les perdre, vous pouvez les mettre de côté avec git stash
, faire votre git revert
pour revenir à un commit antérieur, et faire git stash pop
pour récupérer ce que vous aviez mis de côté.
git stash
git revert 5dabd208308d9a5a5136fa2ac3e99f016b5a9e15
git stash pop
C’est une pirouette un peu plus complexe, mais si vous devez travailler sur une copie de travail propre, git stash
est un bon moyen de mettre des modifications de côté.
Ignorer des fichiers avec .gitignore
Si votre projet contient des fichiers que vous ne voulez pas suivre dans votre dépôt, autrement dit que vous voulez toujours ignorer, vous pouvez ajouter un fichier .gitignore
à la racine de votre dépôt.
Ce fichier est un simple fichier texte automatiquement reconnu par Git, et va permettre lister les fichiers et dossiers que vous ne souhaitez jamais suivre dans votre dépôt.
Imaginons que vous utilisiez la bibliothèque JS terser
pour minifier les fichiers JavaScript de votre projet. Cette bibliothèque s’installe avec npm
et l’installer va créer un fichier package.json
listant les dépendances JavaScript de votre projet ainsi qu’un dossier node_modules/
contenant toutes les dépendances de terser
à la racine de votre projet.
Mais vous n’avez pas besoin (ni envie, vu la taille du dossier) d’inclure toutes ces dépendances. package.json
suffit car il contient une référence à terser
. Vous pourrez donc le réinstaller rapidement si besoin.
On va donc dire à Git d’ignorer complètement ce dossier node_modules/
en créant un fichier .gitignore
(n’oubliez pas le point !), en y ajoutant simplement la ligne node_modules/
.
Le fichier contient donc une seule ligne pour le moment. Mais au fur et à mesure que vous avancez dans votre projet, vous allez surement petit à petit y ajouter des éléments à ignorer.
Un workflow simple
Avec ce que contient cet article vous avez déjà de quoi utiliser Git au quotidien.
Quand vous travaillez sur un projet, 99% de votre workflow sera celui-ci :
- Initialiser le dépôt Git (une seule fois en début de projet)
- Créer un fichier `.gitignore` si besoin.
- Développez votre fonctionnalité
- Surveillez votre dépôt avec
git status
- Ajoutez vos fichiers avec
git add
- Validez avec
git commit
git status
, git add .
et git commit -m "Super message"
représente 95% des commandes Git que j’utilise tous les jours. Annuler un commit est assez rare.
Au final, je n’utilise pas beaucoup git diff
parce que j’utilise VSCode, qui a une intégration complète avec Git et Github. Dans l’interface de VSCode, je peux comparer les fichiers et voir les modifications apportées directement, et c’est plus lisible que le git diff
dans le terminal.
Par contre, pour tout le reste, j’utilise le terminal. git status
est une commande dont la sortie est très claire et explicite.
Parmi les autres commandes que j’utilise très souvent se trouvent git branch
et git switch
que j’utilise pour naviguer parmi les branches de mon projet, ainsi que git clone
, git pull
, et git push
, utilisées pour collaborer en ligne à l’aide de Github ou Gitlab.
Quelques conseils
Pour une meilleure utilisation de Git, voici quelques conseils simples :
- Faites de petits commits : ne validez qu’une seule fonctionnalité à la fois. Ainsi, il est plus facile de revenir en arrière et chaque commit a un sens car il est indépendant. Par “petit” j’entends une seule fonctionnalité/bug, mais ce commit peut affecter plusieurs fichiers, évidemment. L’idée c’est qu’un commit doit correspondre à une étape dans le développement du projet.
- Soignez vos messages : Si vous avez bien suivi le point précédent, écrire un message de commit clair devrait être relativement évident. “Fixed grid layout bug on home page” est très clair. “Fixed bug” l’est beaucoup moins. Si votre commit contient plusieurs bug fixes/fonctionnalités, vous allez vous retrouver avec des messages comme “Fixed navigation bug and updated readme and added long awaited feature and ….“, ce qui n’est pas vraiment lisible ni clair.
Avec des petits commits à chaque étape du développement, Git vous aide à organiser pas à pas le développement de votre projet, de façon sécurisée !
J’espère que cette introduction vous a aidé à démarrer et à appréhender Git plus sereinement. Apprendre Git peut sembler intimidant au départ, mais le workflow de base n’est pas si compliqué !
Dans la partie 2 de cette série Apprendre Git, on parlera des commandes permettant de gérer les branches.
[…] la première partie de cette mini-série Apprendre Git, on a découvert l’outil de contrôle de version […]