TP4 : Voyage dans le temps
Objectifs¶
Le but de ce TP est de comprendre les commandes suivantes :
Une petite révision¶
Quand vous travaillez sur un nouveau poste
Vous pouvez créer un nouveau PAT et utiliser
git clonepour cloner le Remote Repo sur votre poste.Vérifiez que Git est bien configuré sur votre poste avec
git config --global user.nameetgit config --global user.email.
Le voyage dans le temps¶
Nous avons appris que Git utilise un graphe de commits pour représenter les différentes versions de notre projet au cours du temps. Maintenant, nous allons apprendre comment naviguer dans ce graphe.
Checkout¶
Nous pouvons naviguer à travers les différents sommets de ce graphe, ce qui signifie que nous pouvons revenir à différents états de notre dépôt dans le passé, enregistrés par les commits. Avant de commencer, vérifiez que votre dépôt est bien propre (toutes les modifications sont dans un commit).
Exécutez
git checkout <commit hash>avec le commit hash d’un ancien commit. Votre commande pourrait ressembler àgit checkout abc0123par exemple.
Observez l’état de votre (ancien) Repo.
Revenez au sommet le plus récent (et quittez l’état detached HEAD) en exécutant
git checkout main.
git checkout -
git checkout -La commande git checkout - permet de revenir au dernier sommet visité (avant le sommet courant où se trouve HEAD).
Vous pouvez aussi utiliser
git diff <commit hash>pour voir les différences entre votre Working Tree courant et l’état de votre Repo après un ancien commit.Voyagez dans le graphe de vos commits et observez l’état de votre Repo (avec
checkout,diff,statusetgraph), puis revenez au présent lorsque vous maîtrisez ce voyage dans le temps.
Stash¶
Pour préparer notre voyage dans le temps, nous allons apprendre à conserver les modifications courantes du présent qui ne sont pas encore dans notre graphe de commits, car revenir dans le passé modifiera la réalité observée dans notre Working Tree.
Avant de commencer, vérifiez l’état de votre graphe de commits avec
git graph.Créez un répertoire
TP4/avec un fichiertime-travel.txtcontenant le contenu de votre choix.Exécutez
git addetgit commitpour enregistrer ces changements.Observez avec
git graphqu’un nouveau sommet a bien été ajouté avec votre message de commit.Modifiez le contenu du fichier
time-travel.txtsans fairegit addnigit commit.Exécutez
git stashet observez le contenu de ce fichier.
git stash
git stashLorsque nous avons besoin d’interrompre temporairement notre session de travail pour voyager dans le temps par exemple (revenir à l’état du dépôt dans le passé), nous devons suivre les principes de code propres comme “faire un commit seulement quand le code compile ou passe les tests”.
Vu qu’un commit n’a pas encore été effectué, nos modifications n’existent pas encore dans le graphe des commits, mais nous voulons les conserver.
La commande git stash permet de garder les modifications courantes dans une pile (comme une pile d’assiettes) sans faire de add ni de commit.
Les effets précis de cette commande avec ses options seront vus dans la suite de ce TP et au prochain TP.
Exécutez
git stash popet observez le contenu detime-travel.txt.
git stash pop
git stash popLes modifications dans “l’assiette” au-dessus de la pile sont remises dans le Working Tree et l’assiette est supprimée de la pile.
La pile de git stash sera étudiée dans la suite avec l’introduction des branches.
Créez trois fichiers
modified-time-travel.txt,staged-time-travel.txtetignored-time-travel(sans extension) contenant le contenu de votre choix.Add, commit, push et vérifiez que les modifications sont sur le Remote Repo, sauf pour
ignored-time-travelqui est ignoré (si vous avez bien configuré votre.gitignorepour ignorer les fichiers sans extension, sinon il faut corriger votre.gitignore, nettoyer votre Remote Repo et reprendre à partir de 8).Créez un nouveau fichier
untracked-time-travel.txtdansTP4/avec le contenu que vous voulez sans fairegit add.Modifiez le contenu de
modified-time-travel.txtsans fairegit add.Modifiez le contenu de
staged-time-travel.txtet faitesgit add staged-time-travel.txtsans fairegit commit.Modifiez le contenu de
ignored-time-travel.
À ce stade, vérifiez bien que vous avez un nouveau fichier non suivi (untracked-time-travel.txt), un fichier modifié qui était déjà suivi (modified-time-travel.txt), un fichier modifié et ajouté à la staging area (staged-time-travel.txt) et un fichier modifié mais ignoré (ignored-time-travel).
Exécutez
git stashet observez le contenu des quatre fichiers. Quelles sont les modifications qui ont disparu et celles qui sont restées ?Exécutez
git stash poppour récupérer toutes vos modifications.Exécutez
git stash -uet observez le contenu des quatre fichiers. Quelles sont les modifications qui ont disparu et celles qui sont restées ?Exécutez
git stash poppour récupérer toutes vos modifications.Cette fois, exécutez
git stash -aet observez le contenu des quatre fichiers. Quelles sont les modifications qui ont disparu et celles qui sont restées ?Exécutez
git stash poppour récupérer toutes vos modifications.
Maintenant, vous devez savoir quelles modifications sont enregistrées dans la pile de git stash.
git stash -u et git stash -a
git stash -u et git stash -aPar défaut, git stash récupère seulement les modifications des fichiers suivis et celles présentes dans la staging area.
Si vous voulez prendre en compte les modifications dans un nouveau fichier, vous pouvez utiliser git stash -u (abréviation de git stash --include-untracked).
Si vous voulez également inclure les modifications dans les fichiers ignorés, vous pouvez utiliser git stash -a (abréviation de git stash --all).
Exécutez
git checkout <ancien commit hash>et observez le message d’erreur.
Le danger du voyage dans le temps
Si vous exécutez git checkout alors qu’il y a des modifications qui ne sont pas dans la pile de git stash, Git vous avertit qu’elles risquent d’être perdues.
Il est donc conseillé d’utiliser git stash -a pour prendre en compte toutes vos modifications avant de faire git checkout.
Add, commit et push toutes vos modifications.
Reset¶
Le voyage dans le temps nous rend parfois nostalgiques d’un meilleur passé.
Malheureusement, nous ne pouvons que l’observer avec une tête détachée.
Si seulement nous pouvions changer la réalité et réinitialiser...
Créez un fichier
reset.txtcontenant une ligne de votre choix, puis add et commit sans push.Ajoutez une deuxième ligne à
reset.txt, puis add et commit sans push.Observez
git graphetgit status.Exécutez
git reset HEAD~1pour supprimer le dernier commit.Observez
git graph,git statuset le contenu dereset.txt.
git reset
git resetLa commande git reset permet de supprimer les derniers sommets du graphe de commits.
Vous pouvez également exécuter git reset HEAD~<nombre> pour annuler les <nombre> derniers commits.
Add et commit sans push vos changements encore une fois. Puis faites des modifications dans
reset.txtsur les lignes suivantes en effectuant un commit différent sans push pour chaque ligne.
Maintenant, vous devez avoir plusieurs commits à la suite qui modifient le contenu de reset.txt.
Choisissez un commit dans le passé (après la création de
reset.txt) et exécutezgit reset <commit hash>. Puis observezgit graphetgit status.
git reset <commit hash>
git reset <commit hash>Au lieu de faire git reset HEAD~<nombre>, vous pouvez aussi utiliser git reset <commit hash> pour supprimer tous les commits qui viennent après un commit spécifique.
Effectuez de nouveau quelques commits en modifiant
reset.txtsans push.Exécutez
git reset --softavecHEAD~<nombre>ou<commit hash>et observezgit graphetgit status. Quelle est la différence entre--softet le comportement par défaut dereset?Refaites des commits sans push.
Exécutez
git reset --hardavecHEAD~<nombre>ou<commit hash>et observezgit graphetgit status. Quelle est la différence ?
--soft, --mixed et --hard
--soft, --mixed et --hardgit reset dispose de trois options principales : --soft, --mixed et --hard.
--softannule les commits tout en conservant leurs changements dans la staging area.--mixedest le comportement par défaut deresetet conserve les changements des commits annulés dans le Working Tree.--hardsupprime à la fois les commits annulés et leurs changements.
Nous insistons sur le fait que les commits et suppressions doivent être faits localement avant d’être poussés vers le Remote Repo. Pourquoi ?
Est-ce que cela veut dire qu’un commit synchronisé ne peut jamais être “annulé” ? Nous allons voir comment annuler un commit qui est déjà sur le Remote Repo.
Add, commit et push toutes vos modifications.
Revert¶
Et je croyais pouvoir modifier la réalité...
Alors que ce n’est que ma réalité...
Comment puis-je annuler mes commits erronés ?
Si je les ai déjà partagés avec le monde entier.
Créez un fichier
revert.txtavec une ligne de texte et effectuez un commit avec push.Ajoutez une deuxième ligne à
revert.txtet effectuez un commit avec push.
Imaginons que la deuxième ligne ajoutée soit une erreur. Nous allons revert ce commit tout en conservant l’historique.
Exécutez
git revert HEAD. Entrez un message dans l’éditeur, comme pour un message de commit.Vérifiez le contenu de
revert.txt,git statusetgit graph.
git revert
git revertLa commande git revert permet de créer un nouveau commit qui annule les modifications des commits précédents.
Les différentes options de git revert seront explorées dans la suite de ce TP.
Expérimentez avec un nouveau commit et
git revert HEAD --no-edit, puis vérifiez le contenu derevert.txt,git statusetgit graph.
git revert --no-edit
git revert --no-editIci, vous constaterez qu’un nouveau commit a été créé avec le message par défaut Revert "<message du commit annulé>".
Effectuez au moins trois changements dans
revert.txtavec add, commit et push pour chaque ligne séparément.
Nous pouvons également effectuer un revert de plusieurs commits. Chaque commit annulé sera accompagné d’un commit de revert.
Exécutez
git revert HEAD~3..HEAD --no-editpour revert les trois derniers commits. Vérifiez le contenu derevert.txt,git statusetgit graph.
git revert HEAD~<nombre>..HEAD
git revert HEAD~<nombre>..HEADVous pouvez omettre l’option --no-edit pour ajouter un message pour chaque commit annulé. Vous auriez aussi pu utiliser git revert -n HEAD~3..HEAD (-n pour --no-commit), ce qui ne crée pas automatiquement plusieurs commits, puis exécuter git commit -m "<message>" pour créer un seul commit (au lieu de trois) avec le message que vous souhaitez.
Expérimentez avec plusieurs commits puis
git revert -n HEAD~3..HEADetgit commit -m "<message>", tout en vérifiant le contenu derevert.txt,git statusetgit graph.
Vu que vous ne supprimez aucun commit mais que vous effectuez de nouveaux commits qui annulent les anciens, il n’y a pas de risque pour l’historique du Remote Repo.
Vérifiez que votre dépôt est bien propre. Revenez aux objectifs et cochez les points que vous avez maîtrisés. Entraînez-vous sur les commandes et les notions que vous n’avez pas encore bien comprises. Faites appel à votre encadrant si besoin.
Quiz !
N’oubliez pas de compléter le quiz du TP sur Moodle !
Teaser : voyager entre univers parallèles
Dans le prochain TP, nous allons voir comment créer des univers parallèles (des branches), voyager entre différents univers et fusionner des univers pour n’en obtenir qu’un seul !