Par Maxime Jumelle
CTO & Co-Founder
Publié le 2 févr. 2022
Catégorie Cloud / DevOps
Que l'on soit Data Scientist, Data Engineer, développeur ou architecte, s'il y a un outil qu'il faut maîtriser, c'est bien Git (prononcé « guite »). Si ce nom est aussi connu, c'est parce qu'il apparaît comme la solution indispensable lorsque l'on collabore à plusieurs sur un projet et est défini comme le standard n°1 des bonnes pratiques de développement.
Git est un système de versions distribué (Distributed VCS pour Version Control System), c'est-à-dire un outil qui permet le contrôle des versions d'un projet, qu'il y ait un ou plusieurs contributeurs. Ce besoin de gérer les versions est d'autant plus renforcé que les environnements sont de plus en plus décentralisés sous forme de microservices, rendant les itérations de développement de plus en plus courtes.
Tout d'abord, qu'est-ce qu'un outil de gestion de versions ? Ces outils, initialement utilisés par les développeurs, sont quasi-exclusivement utilisés pour gérer des codes sources. L'outil est en effet pensé pour suivre l'évolution des lignes de chaque fichier afin de repérer exactement où et quand ont eu lieu les changements.
Ce procédé est justement très puissant : il ne suffit pas versioner l'intégralité du fichier, mais les lignes qui le composent. Cela permet par exemple de travailler à deux sur le même fichier, mais sur des parties de codes différentes. Git va être capable de fusionner conjointement les modifications apportées sans écraser une des deux modifications. Git va donc permettre de suivre l'évolution d'un code source, mais également de travailler à plusieurs dessus.
Il existe deux types principaux outils de gestion de versions.
Git est un outil distribué mais avec un ou plusieurs serveurs : plutôt que d'envoyer directement les modifications aux autres utilisateurs, il est possible d'utiliser Git avec plusieurs serveurs distants auxquels les utilisateurs vont s'y connecter.
❓ Mais donc Git, GitHub et GitLab c'est la même chose ?
Non, et c'est une confusion que l'on retrouve souvent lorsque l'on débute avec Git.
Les fournisseurs Cloud disposent également de services d'hébergement de projets Git. Ils ont également l'avantage de proposer des intégrations avec d'autres services, permettant une approche orientée DevOps.
Pour illustrer les exemples, nous allons créer un compte sur GitHub, qui est très facile à prendre en main.
Les projets versionnés avec Git sont appelés des dépôts (repository). Il s'agit d'une copie d'un projet, que chaque utilisateur possède en local, tout comme le serveur central. Un dépôt est donc en particulier constitué des fichiers du projet, mais contient également d'autres informations que nous allons voir.
Un dépôt peut être local, auquel cas il se situe sur son ordinateur, ou distant, lorsqu'il est stocké sur un serveur distant dont les utilisateurs authentifiés peuvent y avoir accès. Lorsque l'on souhaite débuter un projet avec Git, il y a deux possibilités.
Créons un nouveau dépôt sur GitHub.
Nous attribuons le nom git-test
à notre projet avec une description. Nous choisissons une visibilité publique, c'est-à-dire que tout le monde pourra lire le code présent (mais pas le modifier). À noter que sous GitHub, les dépôts privés nécessitent un compte payant.
Ensuite, nous pouvons choisir d'initialiser le dépôt avec plusieurs fichiers.
README.md
est l'équivalent du « lisez-moi », permettant de présenter le projet et d'y fournir des instructions pour installer/exécuter..gitignore
permet de spécifier les dossiers et fichiers à ne pas considérer dans le dépôt Git. Par exemple, on ne souhaite pas mettre dans le dépôt Git un fichier qui contiendrait des mots de passe.LICENSE
est utile dans le cas des dépôts publics avec des licences open-source.Une fois sélectionné, nous pouvons créer le dépôt.
Nous avons bien les deux fichiers présents comme demandés lors de la création. Maintenant, nous allons récupérer ce dépôt en local. Pour cela, nous pouvons cliquer sur le bouton Code puis copier la commande git
à exécuter dans un terminal.
git clone https://github.com/XXXXXXXXX/git-test.git
Cloning into 'git-test'... remote: Enumerating objects: 4, done. remote: Counting objects: 100% (4/4), done. remote: Compressing objects: 100% (3/3), done. remote: Total 4 (delta 0), reused 0 (delta 0), pack-reused 0 Unpacking objects: 100% (4/4), 1.59 KiB | 326.00 KiB/s, done.
Nous avons bien récupéré tous nos fichiers. À noter qu'il y a un dossier nommé .git
: ce dernier contient tous les fichiers nécessaires au dépôt, aussi bien des copies de code que des journaux ou des informations diverses.
Pour créer un dépôt Git en local, il suffit de se diriger dans le dossier contenant le code source et d'exécuter la commande
git init
.
Il est maintenant possible de commencer à développer.
À ce stade, nous n'avons pas encore apporté de modifications. C'est à partir de maintenant que les choses sérieuses vont commencer. Lorsque nous allons commencer à ajouter et modifier des fichiers, nous allons rentrer dans un cycle de développement.
Dans ce cycle, nous allons ajouter ou supprimer des fichiers, ajouter des lignes de codes dans un fichier A puis dans un fichier B sans toucher au fichier C. L'objectif de Git est maintenant de savoir quelles ont été précisément les modifications apportées.
C'est le rôle du commit. Au préalable, nous devons indiquer à Git quels sont les fichiers qu'il doit suivre, c'est-à-dire ceux dont il doit à chaque fois vérifier quels ont été les changements. On appelle cela le tracking.
Pour ajouter des fichiers au tracking Git, nous utilisons la commande git add
suivi d'un fichier ou d'un dossier. Prenons la commande suivante.
git add .
Pour rappel, .
fait référence au répertoire courant : nous traquons (suivons) tous les fichiers du dossier actuel (sauf ceux mentionnés dans le fichier .gitignore
). Cette opération n'est pas faite qu'une seule fois pour chaque fichier, puisqu'une fois tracké, il sera automatiquement dans le viseur de Git.
Ajoutons un fichier python nommé code.py
qui va contenir le code suivant (on peut faire nano code.py
si l'on reste uniquement dans le terminal, même s'il est plus pratique d'utiliser Visual Studio Code).
from datetime import datetime print("Hello ! Il est {}.".format(datetime.now().strftime("%H:%M:%S")))
Ajoutons maintenant ce fichier au tracking Git avec git add .
(ou juste git add code.py
).
Nous allons maintenant dire à Git que ce fichier a été modifié avec un commit. Pour commit, nous avons besoin de deux informations.
Le message de quelques mots permet d'indiquer aux autres utilisateurs la raison du commit. Essayons de créer un commit.
git commit -m "Ajout du fichier code.py"
*** Please tell me who you are. Run git config --global user.email "you@example.com" git config --global user.name "Your Name" to set your account's default identity. Omit --global to set the identity only in this repository. fatal: unable to auto-detect email address (got 'jovyan@ba60e5f3ddb9.(none)')
Comme nous pouvons le voir, Git n'est pas très content ! Et c'est normal, puisque nous n'avons pas dit qui nous sommes. Pour pouvoir commit, il manque nos informations utilisateur. Pour cela, exécutons les deux commandes suivantes.
git config --global user.email "adresse@mail.com" git config --global user.name "Prénom Nom"
Relançons à nouveau le commit.
git commit -m "Ajout du fichier code.py"
[main 261b4e4] Ajout du fichier code.py 1 file changed, 3 insertions(+) create mode 100644 code.py
Les modifications ont correctement été apportées. Regardons un peu plus en détails avec la commande git log
.
commit 261b4e4532a4dcac3d71cd44af91090ae73272ae (HEAD -> main) Author: Maxime Jumelle <adresse@mail.com> Date: Wed Feb 10 10:24:33 2021 +0000 Ajout du fichier code.py commit 0ed9a1b172909ba4f69139a500d671b004a141a6 (origin/main, origin/HEAD) Author: Maxime Jumelle <adresse@mail.com> Date: Wed Feb 10 10:48:54 2021 +0100 Initial commit
Cette commande permet de retracer l'historique des commits. Ici, nous voyons qu'un identifiant SHA est attribué à chaque commit (261b4...).
Attention toutefois, un commit ne modifie pas le dépôt distant ! Il n'enregistre que les modifications en local. Si l'on souhaite l'envoyer vers le dépôt distant, nous devons faire un push.
git push origin main
Username for 'https://github.com': XXXXXXXXX Password for 'https://XXXXXXXXX@github.com': Enumerating objects: 4, done. Counting objects: 100% (4/4), done. Delta compression using up to 8 threads Compressing objects: 100% (3/3), done. Writing objects: 100% (3/3), 410 bytes | 410.00 KiB/s, done. Total 3 (delta 0), reused 0 (delta 0) To https://github.com/XXXXXXXXX/git-test.git 0ed9a1b..261b4e4 main -> main
Pour pouvoir push, nous devons spécifier deux informations.
origin
. Il s'agit de l'alias par défaut avec Git pour un serveur distant.Lors d'un push, il est nécessaire de s'authentifier pour avoir les droits d'écriture sur le dépôt distant.
Lorsque l'on tape le mot de passe, rien ne s'affiche à l'écran car il est caché pour des raisons de sécurité, mais il est bien pris en compte dans le terminal.
Si l'on retourne sur GitHub, nous devrions voir les nouvelles références apportées.
Et voilà ! Nous venons de faire notre premier push ! 😎
Une des fonctionnalités les plus puissantes de Git est incontestablement celui des branches. Pour bien comprendre leur intérêt, revenons sur les cycles de développement des applications.
Prenons comme exemple un site Web et considérons qu'il est actuellement en ligne avec la version la plus récente. Toutes les semaines, le site Web doit être mis à jour pour lui ajouter un article de blog au format HTML. Ainsi, les développeurs doivent effectuer un commit chaque semaine pour ajouter les nouvelles modifications.
Or, en parallèle, on souhaite effectuer une refonte visuelle du site Web, mais cette refonte va prendre plusieurs semaines ! Comment travailler en parallèle sur cette refonte sans poser de conflits avec la version actuellement en ligne qui doit être mise à jour avec les nouveaux articles de blog chaque semaine ?
C'est là qu'interviennent les branches. La branche principale main
contient la version en ligne. Chaque semaine, un commit est effectué sur la branche main
. Pour pouvoir travailler sur la refonte visuelle, les développeurs vont créer une nouvelle branche nommée refonte
qui sera dupliquée à partir de la branche main
. Ainsi, les développeurs pourront travailler en parallèle sur la refonte visuelle tout en pouvant mettre à jour continuellement la version en ligne.
git status
On branch main Your branch is up to date with 'origin/main'. nothing to commit, working tree clean
Nous sommes bien sur la branche main
. Créons une nouvelle branche refonte
à partir de la branche main
avec la commande git checkout -b
.
git checkout -b refonte
Switched to a new branch 'refonte'
Nous sommes à présent sur la branche refonte
comme le confirmera git status
. Nous allons dans un premier temps ajouter le fichier module.py
.
from datetime import datetime def obtenir_temps(): return "Hello ! Il est {}.".format(datetime.now().strftime("%H:%M:%S"))
Puis nous allons modifier le fichier code.py
.
from module import obtenir_temps print(obtenir_temps())
Effectuons un commit sur cette branche.
git add . git commit -m "Nouvelle branche"
[refonte d1cbd09] Nouvelle branche 2 files changed, 6 insertions(+), 2 deletions(-) create mode 100644 module.py
Il ne reste plus qu'à faire un push pour mettre à jour le dépôt distant.
git push origin refonte
Enumerating objects: 6, done. Counting objects: 100% (6/6), done. Delta compression using up to 8 threads Compressing objects: 100% (4/4), done. Writing objects: 100% (4/4), 509 bytes | 509.00 KiB/s, done. Total 4 (delta 0), reused 0 (delta 0) remote: remote: Create a pull request for 'refonte' on GitHub by visiting: remote: https://github.com/XXXXXXXXX/git-test/pull/new/refonte remote: To https://github.com/XXXXXXXXX/git-test.git * [new branch] refonte -> refonte
Sur GitHub, nous pouvons maintenant sélectionner une branche sur GitHub.
Sur cette nouvelle branche, nous voyons les modifications apportées.
En parallèle, retournons sur la branche main
.
git checkout main
Un checkout
sans argument nous permet de changer de branche. APrès ce checkout, le fichier module.py
disparaît car il n'est pas présent dans la branche main
. Modifions le fichier README.md
.
# Test Git Nous travaillons sur les branches de Git !
Là-aussi, mettons à jour les références vers le dépôt distant.
git add . git commit -m "Mise à jour du README" git push origin main
Supposons dorénavant que la refonte visuelle soit terminée. Comment allons-nous rapatrier le contenu mis à jour de la branche refonte
sur la branche main
sans écraser les modifications faites depuis sur cette même branche depuis la création de refonte
?
En particulier, nous avons modifié le fichier README.md
dans la branche main
, or nous n'y avons pas touché dans la branche refonte
. Et encore une fois, Git est très puissant, car lors de la fusion d'une branche vers une autre, il va détecter les lignes non modifiées et ne pas écraser le fichier README.md
. Il faut garder à l'esprit que Git s'intéresse toujours au contenu le plus récent : il va donc récupérer le fichier module.py
, mettre à jour le code code.py
et ne pas modifier README.md
.
Pour cela, nous devons nous positionner sur la branche qui va recevoir la fusion (ici la branche main
), puis lancer la commande suivante.
git merge refonte
À ce moment là, un éditeur de texte (Vim) nous demande de spécifier un message pour cette fusion. Pour pouvons laisser le message par défaut et taper sur les touches (dans l'ordre) :wq
(pour write and quit).
Merge made by the 'recursive' strategy. code.py | 4 ++-- module.py | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) create mode 100644 module.py
Si notre fusion s'est bien passée, nous avons dorénavant les trois fichiers, et nous pouvons faire un push vers le dépôt distant.
git push origin main
Tous nos fichiers sont maintenant présents et à jour sur la branche main
.
Les branches sont donc très utiles pour développer de nouvelles fonctionnalités ou pour séparer les codes sources de développement et de production.
Pour aller plus loin avec Git, le livre Pro Git est accessible en ligne et couvre de très nombreux aspects.
Vous souhaitez vous former au Cloud / DevOps ?
Articles similaires
28 févr. 2024
Pour de nombreuses entreprises, innover chaque jour en proposant des applications à ses utilisateurs est un sujet primordial. Pour autant, cette course au déploiement continu de nouvelles applications nécessite des compétences bien particulières sur les architectures Cloud, l'automatisation de projets et la supervision. C'est à partir de ce moment qu'intervient le rôle de l'ingénieur DevOps dans les entreprises.
Maxime Jumelle
CTO & Co-Founder
Lire l'article
23 févr. 2024
Dans le monde du DevOps, les conteneurs sont rapidement devenus des incontournables, aussi important que les machines virtuelles. Des plateformes de conteneurisation comme Docker ont permis de simplifier et d'accélérer la création d'image et l'exécution de conteneurs sur différents systèmes, à portée de tous.
Maxime Jumelle
CTO & Co-Founder
Lire l'article
16 févr. 2024
Dans l'approche GitOps, il existe de nombreux outils permettant d'exécuter des pipelines CI/CD : certains se concentrent uniquement sur la partie intégration continue, d'autres avec le déploiement en plus. S'il y en a un qui est considéré comme l'un des plus matures et des plus robustes, c'est bien GitLab.
Maxime Jumelle
CTO & Co-Founder
Lire l'article
60 rue François 1er
75008 Paris
Blent est une plateforme 100% en ligne pour se former aux métiers Tech & Data.
Organisme de formation n°11755985075.
Data Engineering
IA Générative
MLOps
Cloud & DevOps
À propos
Gestion des cookies
© 2024 Blent.ai | Tous droits réservés