Introduction à Git
Introduction
- Outil indispensable
- Pas d’évaluation immédiate
- mais utilisé toute la scolarité et vie pro
- Présentation perso en 1min
- Évalué en Compléments d’info 2A
- Suivi d’un TP
- ⚠️ valable pour tous les TP
- n’allez pas trop vite
- suivez précisément les consignes
Introduction
Vous faites parti d’une équipe de 5 personnes qui doit coder une application de jeux de cartes.
😕 Comment mettre en commun votre code ?
- Vous développez chacun de votre coté et à la fin, vous mettez tout en commun
- Vous envoyez vos programmes par mail
- Vous créez un dossier commun
😅 En cas d’erreur, comment revenir en arrière ?
Au programme
- 📌 Versionner son code
- 💾 Historique des modifications
- 👷 Travail en équipe
Pourquoi versionner ?
- Quelle est la bonne version ?
- Comment faire pour revenir en arrière ?
- Qui a écrit ce code ? Quand ?
- les questions que l’on peut se poser en projet
- Mais qui a écrit cette merde ???
- ah ben c’est moi…
Pour connaitre la véritable dernière version
- imaginons que vous partagiez un dossier commun
- ou encore que ce fichier soit dans des mails
- version v0, v1, v2
- même si vous êtes bien intentionné
- ça finira par déraper
├─── Projet info
│ ├─── old
│ │ ├─── Rapport.txt
│ │ ├─── Rapport_new.txt
│ │ ├─── Rapport_v1.0.txt
│ │ └─── Rapport_v1.2.txt
│ ├─── Rapport_old.txt
│ ├─── Rapport_2022.05.15.txt
│ └─── Rapport_2022.05.15_new.txt
😕 Quelle est la bonne version du fichier ?
😊 Un seul fichier + l’historique des modifications
├───Projet info
│ └───Livrables
│ └───Rapport.txt
Date Heure Auteur Message commit
---- ----- ------ --------------
2022.05.29 23h58 bianca "Version finale"
2022.05.29 23h40 archibald "j'avais oublié l'intro"
2022.05.29 21h32 tryphon "ajout partie 2"
2022.05.29 20h25 bianca "v1.1"
2022.05.29 20h12 tryphon "Création du rapport"
Ancien code commenté
Vous souhaitez passer de R-base à ggplot2 pour votre graphique.
Mais vous vous dites que c’est mieux de garder l’ancien code au cas où…
analyse.R
library(ggplot2)
<- data.frame(x = seq(-4, 4, length=100))
data $y <- dnorm(data$x)
data
# plot(data$x, data$y, type="l", lwd=2, col="blue",
# main="Densité de la loi normale centrée réduite",
# xlab="x", ylab="Densité")
# abline(h=0, col="gray")
ggplot(data, aes(x = x, y = y)) +
geom_line(color = "blue", size = 1) +
ggtitle("Densité de la loi normale centrée réduite") +
xlab("x") +
ylab("Densité") +
theme_minimal()
analyse.R - Commit 05016ab - Date 2024.06.02 - Author tryphon
$y <- dnorm(data$x)
data
plot(data$x, data$y, type="l", lwd=2, col="blue",
main="Densité de la loi normale centrée réduite",
xlab="x", ylab="Densité")
abline(h=0, col="gray")
analyse.R - Commit f97f766 - Date 2024.06.04 - Author bianca
library(ggplot2)
<- data.frame(x = seq(-4, 4, length=100))
data $y <- dnorm(data$x)
data
ggplot(data, aes(x = x, y = y)) +
geom_line(color = "blue", size = 1) +
ggtitle("Densité de la loi normale centrée réduite") +
xlab("x") +
ylab("Densité") +
theme_minimal()
Git
- git : connard en argot britannique
Historique
- Créé par Linus Torvalds en 2005
- Pour gérer le développement du noyau Linux
- Le standard incontournable de la gestion de versions
- Anciens outils : CVS, SVN
- Standard : produit qui s’est imposé par l’usage (ex : Moteur de recherche Google, TCP/IP)
- peu causer des problèmes de monopole…
Logiciel
- Logiciel Libre, Open source
- Gratuit
- Décentralisé
😨 Git s’utilise majoritairement en ligne de commande dans un terminal Git Bash
.
😅 Pas de panique, quelques commandes suffisent pour travailler avec Git.
Il existe aussi des interfaces graphiques mais elles sont souvent imparfaites et sources d’erreur.
- Logiciel libre
- code source est ouvert et disponible
- permettant à quiconque de l’utiliser, le modifier, et le distribuer librement
- différent de gratuit
- légérement différent de Open source
- Open Source : avantages pratiques et collaboratifs
- Libre : libertés et les droits éthiques des utilisateurs
- Décentralisé
- chaque utilisateur dispose d’une copie complète de l’historique de tout le projet
Késako
- Git
- Logiciel de gestion de versions
- Git Bash
- Terminal pour écrire des commandes git
- GitHub / GitLab
- Plateforme de développement collaboratif
- Héberge des dépôts Git
- Propose d’autres fonctionnalités (CI/CD, wiki, gestion des incidents…)
- GitHub racheté par Microsoft en 2018
- GitLab, Libre, possible d’avoir son propre GitLab interne
Git Bash
- Terminal de commande
- Plusieurs manières de lancer (Menu Windows, clic droit, inclus dans VSCode)
Conseil : lors de l’installation de Git, choisissez le terminal Unix
- 1ere ligne : prompt (username, machine, répertoire actuel)
- 2e ligne (commence par $) : commande
- 3e ligne : résultat de la commande
Commandes Unix
Commande | Description |
---|---|
ls |
Liste le contenu d’un répertoire |
pwd |
Affiche le répertoire courant |
cd <directory> |
Change le répertoire de travail courant |
mv <src_file> <dest_file> |
Déplace des fichiers ou des répertoires |
cp <src_file> <dest_file> |
Copie un fichier ou un répertoire |
mkdir <directory> |
Crée un nouveau répertoire |
rm <file_or_dir> |
Supprime des fichiers ou des répertoires |
touch <filename> |
Crée un nouveau fichier vide |
cat <filename> |
Affiche le contenu d’un fichier |
grep <text> <filename> |
Rechercher dans un fichier |
Commande | Signification |
---|---|
ls |
list |
pwd |
print working directory |
cd <directory> |
change directory |
mv <src_file> <dest_file> |
move |
cp <src_file> <dest_file> |
copy |
mkdir <directory> |
make directory |
rm <file_or_dir> |
remove |
touch <filename> |
|
cat <filename> |
concatenate |
grep <text> <filename> |
global regular expression print |
- ce qui est entre < … > est à remplacer
- ll : ls -l
- cd : change directory
- pwd : print working directory
- mkdir : make directory
- pour éditer un fichier : vi, nano
- man
Attention avec les commandes rm, kill
Commandes Unix - Exemples
Pour chaque commande, de nombreuses options sont disponibles
ls *.py # liste tous les fichiers python du répertoire courant
ls *.py > a.txt # crée un fichier a.txt contenant le résultat de la commande
cd .. # se positionne dans le répertoire parent
cd ../projet/src # remonter dans le dossier parent puis aller dans projet puis src
cp /p/image.jpg . # copie le fichier image.jpg du disque P dans le dossier courant
./setup.sh # lance le programme setup.sh du répertoire courant
.
: représente le dossier courant..
: représente le dossier parent~
: répertoire personnel de l’utilisateur (echo $HOME
)
répertoire = dossier
La ligne de commande reste très utilisée :
- rapide, efficace
- automatisation
- exemple : renommer 1000 fichiers d’un dossier
Copier-Coller
- CTRL + C et CTRL + V ne fonctionnent pas !
- CTRL + C : stopper un processus (très utile)
2 possibilités pour coller du texte :
- Clic droit
- MAJ + INSERT
Versionner son code
- Au début j’ai parlé de versionner
- Comment faire avec Git
Que versionne-t-on ?
- ✅ des fichiers de type texte (légers)
- ✅ du code source
- ❌ fichiers de données
- ❌ mots de passe
- ❌ outputs : logs, .pdf, .doc
- un dépôt doit rester mince
- quelques Mo max
- possible de mettre du doc ou pdf
- mais git ne sait comparer que du txt, csv, md
- tout ce qui peut s’ouvrir avec notepad
Workflow
- ça fait un peu peur, pas intuitif au début
- c’est un peu plus complexe que d’avoir simplement local et remote
- workspace : tous les fichiers de votre dossier
- staging : fichier reconnus par git
- local : sauvegardes du dépôt local
Créer un commit
2 étapes pour créer une nouvelle version :
git add <filename>
- ajouter le fichier à l’index (i.e. dire à Git de suivre ce fichier)
git add .
: pour ajouter tous les fichiers
git commit -m "<mon message>"
- git utilise la sauvegarde incrémentale
- il ne garde que les modifs apportées depuis le dernier commit
https://talks.freelancerepublik.com/git-commandes-indispensables-developpeurs/
Exemple
├─── Projet info
│ ├─── src
│ │ ├─── main.py
│ └─── doc │ │ └─── Rapport.txt
Votre dépôt avant de commencer à coder.
├─── Projet info
│ ├─── src
│ │ ├─── main.py <- fichier modifié
│ │ ├─── velo.py <- nouveau fichier
│ └─── doc │ │ └─── Rapport.txt
Vous avez :
- modifié un fichier
- créé un nouveau fichier
Vous ajoutez les fichiers créés ou modifiés à l’index :
git add .
Vous créez un point de sauvegarde
git commit -m "feat: ajout de l'utilisation de velo"
git checkout <commit_number>
: les fichiers de votre dépôt sont alors dans l’état où ils étaient à ce commit
Message du commit
😔 Ce n’est pas toujours évident de trouver un message court et explicite.
Utilisez un préfixe à votre message selon le pattern <type>: <sujet>
:
doc:
mise à jour documentairefeat:
nouvelle fonctionnalitéfix:
correctionrefactor:
mise au propre du coderevert:
retour arrièretest:
Modification des tests
Suffixe WIP
Retour arrière
Si finalement, vous n’avez pas envie de « commiter » vos modifications ?
Commande | Description |
---|---|
git restore <file> |
Annuler les modifications locales non indexées du fichier |
git reset <file> |
Desindexer un fichier |
git reset --hard |
Revenir à l’état du dernier commit, perdant toutes les modifications locales |
git stash |
Sauvegarder et remettre le working directory à l’état du dernier commit |
Attention avec les commandes contenant les mots force, hard…
Ignorer des fichiers
.gitignore
est un fichier présent à la racine du dépôt permettant de dire à Git quels fichiers il doit ignorer. Par exemple, s’il contient :
*.csv
➡️ tous les fichiers csv seront ignorés par Gitdata/
➡️ le dossier data et son contenu sera ignoré
Cela est utile, pour exclure par exemple du dépôt Git :
- des fichiers contenant des mots de passe, des jetons d’accès…
- des fichiers volumineux de données qui n’ont pas vocation à être versionnés
- des fichiers de log
- En info, il y a souvent plein de fichiers de config
- ⚠️ Mots de passe ➡️ git garde tout l’historique
- Next
- c’était pour la partie “gestion du dépôt local”
- ensuite regardons comment communiquer avec le dépôt distant
Travailler en équipe
Dépôt local et dépôt distant
- 1 dépôt distant
- appelé aussi remote
- hébergé sur une forge (GitHub, GitLab, Bitbucket…)
- n dépôts locaux
- clone sur votre machine
- git permet la synchronisation des dépôts
Il est tout à fait possible d’avoir plusieurs clones du même dépôt sur son poste.
- avoir un accès internet / réseau local pour communiquer avec remote
- c’était pas nécessaire pour faire des add / commit
Commencer dessin avec :
- un remote v0
- 2 clones de Bob et Alice en v0
Dépôt local et dépôt distant
Chaque dépôt est une copie intégrale du projet.
- Si vous perdez un dépôt, il suffit de repartir d’un autre
Communiquer avec le dépôt distant
git pull
: mettre à jour son dépôt local à partir du dépôt distantgit push
: envoyer ses commits locaux sur le dépôt distant
Il est important de pousser et puller réguliérement son code pour garder son dépôt à jour.
- sinon vos versions vont diverger
IMPORTANT :
- Vous faites toujours vos actions sur un dépôt local
- Vous ne modifiez jamais le dépôt distant
git push
Dépôt local ➡️ Dépôt distant
Pour pouvoir pousser son code, il est nécessaire :
- d’avoir au préalable créé au minimum un commit
- que votre dépôt local soit à jour
- pas de retard de version par rapport au dépôt distant
- si ce n’est pas le cas, il faut commencer par
git pull
Vous pouvez push plusieurs commits
git push - si votre dépôt local n’est pas à jour
! [rejected] main -> main (fetch first)
error: failed to push some refs
hint: Updates were rejected because the remote contains work that you do not
hint: have locally. This is usually caused by another repository pushing to
hint: the same ref. If you want to integrate the remote changes, use
hint: 'git pull' before pushing again. hint: See the 'Note about fast-forwards' in 'git push --help' for details.
Le message est assez explicite.
git push - fichier disparu
- Vous venez de faire un
git push
- Mais votre fichier n’apparait pas sur le dépôt distant…
- Probablement parce que vous avez oublié de l’ajouter à l’index avec
git add <mon_fichier>
Autre possibilité : votre fichier est ignoré par git car il fait parti du .gitignore
ça arrive quand vous voulez aller trop vite
git pull
Dépôt local ⬅️ Dépôt distant
- Mise à jour de votre dépôt local
- S’il y a eu des modifications sur le dépôt distant
Un pull se fait généralement après un commit.
git pull - conflit
Que se passe-t-il si :
- Alice a modifié un fichier et poussé sa modification sur le dépôt distant
- Vous avez également modifié le même fichier et vous faites un
git pull
pour mettre à jour votre dépôt à partir du dépôt distant
😨 Un conflit ! Git ne sait pas choisir quelle est la bonne version entre la votre et celle d’Alice.
git pull - conflit
😅 Pas de panique ! Pour résoudre le conflit, il faut simplement :
- modifier le fichier en question pour garder la bonne version
git add
puisgit commit
pour valider la résolution du conflit
- conflit ≠ erreur
- ça arrive
2 versions s’opposent
- c’est un exemple, il peut y avoir d’autres types
- git est assez bon pour merge (même si 2 modifs sur même fichier)
- mais en cas de doute, il ne peut pas choisir
velo.py
class Velo:
def __init__(self, couleur):
self.couleur = "bleu"
velo.py
class Velo:
def __init__(self, couleur):
self.couleur = "blanc"
velo.py
class Velo:
def __init__(self, couleur):
self.couleur = "noir"
Résoudre un conflit
- Contexte
- Permier arrivé, premier servi
- Le conflit (après votre pull)
- Conflit
- Git n’est pas un juge
- VSCode : accept incoming/current/both change
- Résolution
- supprimez les
<<<<<<<
et=======
➡️ pas du python - si vous relancez votre programme comme ça, il va pas aimer
- supprimez les
Le conflit se résoud sur son dépôt local !
- Alice a poussé son code avant vous
- Vous faîtes donc un
git pull
- En effet, vous devez impérativement mettre à jour votre dépôt local avant de pousser votre code
- 2 versions s’opposent sur votre dépôt local
self.couleur = "noir"
vsself.couleur = "blanc"
- Git n’est pas capable de choisir laquelle est la bonne
- En haut : votre version
- En bas : celle provenant du dépôt distant
class Velo:
<<<<<<< HEAD
def __init__(self, nom, couleur, vitesse_max):
self.couleur = "noir"
=======
def __init__(self, nom, couleur, marque):
self.couleur = "blanc"
>>>>>>> a57ae9120dbf97dbab78f82db81f5fc8f48f3821
Pour résoudre ce conflit, 3 possibilités :
- vous choisissez votre code
- vous choisissez celui d’Alice
- vous choisissez un mix des 2
Ensuite, vous validez, créez un commit et poussez le code (git add .
, puis git commit -m "<message>"
et git push
).
Etat du dépôt local
Est-ce qu’il y a des fichiers :
- non suivis ? Untracked files
- prêts à être commités ? Changes to be committed
- modifiés non ajoutés à l’index ? Changes not staged for commit
La commande git status
permet de répondre à ces questions.
Elle peut être utilisée n’importe quand, sans modération !
git status
Est-ce que votre dépôt local est en avance de n commit par rapport au dépôt distant ?
Cloner un dépôt
git clone
- Allez sur la page du dépôt distant (GitHub, GitLab…)
- Cliquez sur le bouton
Code
- Copiez l’adresse https ou ssh du dépôt distant
git clone <adresse_depot>
- exemples :
git clone https://github.com/ludo2ne/Git-tuto.git
(https)git clone git@github.com:ludo2ne/Git-tuto.git
(ssh)
Créer sans cloner
Il est possible de créer un dépôt local sans cloner un dépôt distant (git init
).
Et éventuellement ensuite de le brancher à un dépôt distant.
Cependant ce cas d’utilisation est assez marginal.
https ou ssh ?
2 protocoles différents pour communiquer avec le dépôt distant.
À utiliser si vous voulez simplement avoir une copie locale du code sans partager vos modifications.
- Plus simple, pas besoin de configuration
- Nécessite un token si vous voulez pousser du code
- Requiert des saisies répétées du token
À utiliser si vous travaillez en projet.
- Configuration initiale des clés SSH
- Plus pratique pour des interactions fréquentes
- Pas de saisie de mot de passe après configuration
- ssh :
- clé publique / clé privée -> config machine
- push and pull
- https :
- token donné par github
- pull only
Commandes principales
Commande | Description |
---|---|
git clone <adr> |
Créer un dépôt local sur son poste |
git status |
Voir où l’on en est |
git add <file> |
Ajouter pour le prochain commit |
git commit -m "<msg>" |
Créer un point de sauvegarde |
git pull |
dépôt local ➡️ dépôt distant |
git push |
dépôt local ⬅️ dépôt distant |
clone : bouton vert code sur GitHub, GitLab
Autres commandes
git diff
: différence avec le dernier commitgit diff <filename>
git checkout <commit_number>
: passer à un commit spécifiquegit log
: historique des commitsgit log --all --decorate --oneline --graph
La routine Git
- pull : des fois qu’un camarade ait codé la nuit
Travailler dans le cloud
- Autre manière de travailler
- Services non perennes
- Sauvegarder votre code
- vous ne travaillerez pas toujours en local
- mais parfois sur des services à la demande
- ex : besoin de puissance de calcul
Les branches
Imaginez que vous souhaitez ajouter une nouvelle fonctionnalité à votre code.
Seulement vous n’êtes pas encore sûr que :
- cette fonctionnalité sera vraiment utile 😐
- qu’elle ne va pas tout casser 😰
- si c’est tout petit, vous pouvez dev en local en faire un reset au cas où
- sinon utilisez une branche
Les branches
Vous aimeriez pouvoir :
- tester votre nouveau code
- de manière isolée
- sans polluer le dépôt
La branche principale se nomme généralement main ou master.
La solution
- Créez une branche
- Développez sur cette branche (add, commit, push…)
- Selon vos conclusions
- fusionnez votre branche avec le tronc
- supprimez votre branche
ça vous permet de coder de manière isolée
Commandes liées aux branches
Commande | Description |
---|---|
git branch -a |
Lister toutes les branches |
git switch <branch> |
Changer de branche |
git switch -c <branch> |
Créer et changer de branche |
git merge <branch> |
Fusionner <branch> dans la branche actuelle |
git branch -d <branch> |
Supprimer la branche |
git push origin <branch> |
Pousser la branche vers le dépôt distant |
Bibliographie
- Git : un élément essentiel au quotidien, Python pour la datascience, Lino Galiana
- Formation Git du Lab INSEE
- Formation Git du SSM Agriculture
- GitFlow
- Développement basé sur le tronc