Système permettant de gérer des changements effectués sur des documents, fichiers sources, sites web, etc.
Gérer c'est pouvoir:
Une solution standard:
monfichier.txt
monfichier.txt.old # cpold
monfichier.v2.txt
monfichier.v2.3txt
monfichier.v2.3.GC.txt
monfichier.v2.3.TR.txt
monfichier.v2.3.GC.TR.20190624.txt
monfichier.vFinal.txt
monfichier.vFinal.withmodif.txt
Problèmes:
Cela suppose d'automatiser au maximum les phases suivantes:
merge
) les versionsCentralisésl'historique complet du dépôt est sur le serveur. Chaque client possède uniquement un instantané
Distribuéschaque copie locale contient tout l'historique
Le livre en ligne git est extrêmement bien fait et vous apprendra tout ce que nous n'avons pas le temps de vous montrer:
https://git-scm.com/bookUn tutoriel plus rapide:
https://www.atlassian.com/git/tutorialsUn guide intéressant:
https://hacker-tools.github.io/version-controlUn petit jeu si vous vous ennuyez pendant ce cours ou plus tard:
https://learngitbranching.js.orgIl y a plusieurs niveaux de configuration dont:
Note: la configuration reste locale à la machine, elle n'est pas associé au dépôt (mais c'est possible si nécessaire)
On peut lister la configuration actuelle avec:
$ git config --list
Avant d'utiliser git il faut toujours configurer au moins:
$ git config --global user.name "Prénom Nom"
$ git config --global user.email "Prénom.Nom@email.cc"
$ git config --global init.defaultBranch main
Note: la configuration peut être locale (i.e. ne pas utiliser --global) si l'on veut utiliser des identifiants différents pour un ou plusieurs dépôt
L'objectif du dépôt est de stocker des recettes de cuisines.
Chaque recette prendra ce format:
- ingrédient 1
- ingrédient 2
- ingrédient 3
Première opération
Deuxième opération
Cuisson
etc.
Initialiser un dépôt
$ git init
Ajouter les modifications à l'index (un fichier ou tous les fichiers modifiés)
$ git add fichier
$ git add . # tous les fichiers
Ajouter toutes les modifications de l'index au dépôt
$ git commit
Vérifier l'état du dossier (working tree) et de l'index (staging area)
$ git status
A chaque étape observer le status du dépôt:
# Mes recettes
Chaque fichier contient des recettes que j'apprécie
add
puis au dépôt avec commit
)
# Mes recettes
Chaque fichier contient une recette que j'apprécie
git log
" pour voir le résultat (à discuter ensemble)$ git log
$ git diff [filename]
Modifier une recette et utiliser la commande ci-dessus
$ git diff commit-hash [filename]
Regarder les modifications effectuées depuis la modification du fichier readme.md
$ git diff hash-ancien hash-recent [filename]
Regarder les différences entre les deux versions du fichier readme.md
Ne jamais se priver d'utiliser la commande git status
$ git status
On branch main
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: sandwich1.md
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: salade.md
Untracked files:
(use "git add <file>..." to include in what will be committed)
salade2.md
Vous y trouverez notament:
Vérifier le statut après chaque opération:
"Zut... j'ai fait trop de changements dans mon fichier et je voudrais les insérer en plusieurs commit"
$ git add -p; git commit
Ajouter les modifications ci-dessous en plusieurs commits.
# Mes recettes
Chaque fichier contient des recettes que j'apprécie
## Entrées
- salade niçoise
- scalade de chèvre
## Plats d'hiver (ou pas)
- fondue
- tartiflette
OUI | Peut-être | NON |
Des fichiers textes
Des petits fichiers binaires de type assets(icones, images, etc.) |
Des fichiers binaires de taille plus importantes (voir git lfs Des fichiers de configuration (e.g. IDE, .vscode, etc.) Librairies |
Tout fichier n'appartenant pas au projet (e.g. .DS_Store, Thumbs.db, etc.) Fichier générables (executables, résultats de calculs, etc.) Mots de passe |
Il existe une solution pour eviter d'ajouter des fichiers non voulus dans l'index: .gitignore
Le boss: "Hey j'ai eu une super idée pour notre programme... Ca te prendra combien de temps pour le faire ?"
Le programmeur: "Ben... une semaine..."
Deux jours plus tard...
Le boss: "Aie... on a un client qui a trouvé un bug il faut le corriger de toute urgence !"
Le programmeur: "Ben je peux pas, je suis en train de modifier le code pour la nouvelle feature et du coup rien n'est stable !"
... advienne que pourra ...
Pas la peine d'avoir un boss ou de travailler en équipe pour faire face à ce genre de problème
Le programmeur: "J'ai deux idées pour ajouter cette fonctionnalitée à mon programme... je me demande laquelle est la meilleure ?"
Bonne vielle solution: je copie mon dossier deux fois et je compare les solutions (défauts déjà discutés)
Nouvelle solution: je crée deux branches et je travaille en parallèle sans qu'une branche impacte l'autre.
La commande suivante permet de créer une branche:
git branch new-branch-name
On se déplace d'une branche à une autre en utilisant:
git checkout la-branche-de-destination
Note: la commande checkout
peut aussi être utilisée pour se rendre vers un commit passé
Note: le déplacement peut modifier le working tree
Pour connaitre la liste des branches:
git branch
Tout au long de cet exercice utlisez git status
pour vérifier sur quel branche vous êtes.
git checkout commit
git checkout -- fichier
Le but d'une branche est souvent d'être intégrée à sa branche de départ. Pour intégrer la branche new
dans la branche old
il faut:
git checkout old
git merge new
Il existe dans la communité une divergence d'opinion sur l'utilisation de git rebase
au lieu de git merge
. Nous vous montrons la commande merge
car rebase
peu être desctructive et poser cetains problèmes
Deux cas de figure possibles:
old
a reçu des commits depuis la création de new
→ merge commitOui, tant que les branches ont modifié des fichiers différents, autrement cela se complique...
Dans ce cas il est recommandé d'utiliser une interface graphique (e.g. un IDE) ou de faire appel à la commande
git mergetool
Dans l'exerice suivant nous utiliserons notre IDE favori avec un usage intensif de git status
auteur
master
auteur
vers la branche master
. S'aider de l'IDE.git log --graph --all
master
de ce dépôt et la pousser sur le remotemaster
et la pousser sur le remoteLorsque l'on travaille avec git il est utile d'avoir une aide visuelle nous indiquant dans quelle branche on est.
Pour bash, si l'outil bash-completion
est installé vous pouvez configurer votre prompt avec la fonction __git_ps1
:
export GIT_PS1_SHOWDIRTYSTATE=1
export PS1='\w$(__git_ps1 " (%s)")\$ '
"Zut, je voudrais changer de branche mais j'ai fait des changements que je ne veux pas commiter..."
La commande stash
est idéale pour cela:
$ git stash # place les changements dans une liste (cachette) → "a clean working directory"
$ git stash list # liste le contenu de la cachette
$ git stash apply [stash-name] # applique les modifications sur le commit courant sans le retirer de la liste
$ git stash pop [stash-name] # applique les modifications sur le commit courant en le retirant de la liste
$ git commit --amend
$ git revert commit-hash # "git reset commit-hash" pour "revenir en arrière" mais c'est à éviter