Aller au contenu principal

TP2 — Fondamentaux Git

Travaux Pratiques 45 min Module 01

Objectifs

À la fin de ce TP, vous aurez pratiqué :

  • Le staging précis avec git add -p
  • L'écriture de messages de commit professionnels
  • L'exploration de l'historique avec les variantes de git log
  • L'utilisation de git blame pour suivre les changements
  • L'annulation de changements avec git restore, git reset et git revert
  • L'utilisation de git stash pour changer de contexte

Mise en place

mkdir git-tp2-fondamentaux
cd git-tp2-fondamentaux
git init
echo "*.pyc" > .gitignore
echo "__pycache__/" >> .gitignore

Créez app.py avec ce contenu initial :

def calculer_total(articles):
total = 0
for article in articles:
total += article['prix']
return total

def appliquer_remise(total, pourcentage_remise):
return total * (1 - pourcentage_remise / 100)

def formater_prix(montant):
return f"{montant:.2f} €"

Créez README.md :

# Application Panier d'Achat

Une application Python pour la gestion de panier d'achat.

## Fonctionnalités
- Calculer les totaux
- Appliquer des remises
- Formater les prix
# Commit initial
git add .
git commit -m "feat: application panier d'achat initiale"

Partie 1 : Staging précis

Mettez à jour app.py avec deux fonctionnalités différentes ajoutées en même temps :

def calculer_total(articles):
"""Calculer le prix total de tous les articles."""
total = 0
for article in articles:
total += article['prix'] * article.get('quantite', 1) # NOUVEAU : support quantité
return total

def appliquer_remise(total, pourcentage_remise):
"""Appliquer une remise en pourcentage à un total."""
if pourcentage_remise < 0 or pourcentage_remise > 100:
raise ValueError("La remise doit être entre 0 et 100") # NOUVEAU : validation
return total * (1 - pourcentage_remise / 100)

def formater_prix(montant, devise="EUR"): # NOUVEAU : paramètre devise
"""Formater un prix pour l'affichage."""
symboles = {"USD": "$", "EUR": "€", "GBP": "£"}
symbole = symboles.get(devise, "€")
return f"{symbole}{montant:.2f}"

def calculer_taxe(total, taux_taxe=0.20): # NOUVELLE : fonction taxe
"""Calculer la taxe sur un total."""
return total * taux_taxe

Utilisez maintenant le staging interactif pour créer 2 commits séparés :

# Utiliser le staging interactif
git add -p app.py

# Commit 1 : uniquement la quantité et la validation de remise
git commit -m "feat(panier): ajout support quantité et validation remise"

# Commit 2 : devise et fonction taxe
git add app.py
git commit -m "feat(panier): ajout support multi-devises et calcul de taxe"

# Vérifier que vous avez 3 commits
git log --oneline

Partie 2 : Explorer l'historique

# Voir l'historique complet
git log

# Historique compact
git log --oneline

# Historique avec statistiques de diff
git log --stat

# Historique avec diff complet
git log -p --oneline

# Filtrer par message de commit
git log --grep="feat"
git log --grep="validation"

Suivre un changement spécifique

Ajoutez cette fonction à la fin de app.py :

def appliquer_coupon(total, code_coupon):
"""Appliquer une remise avec un code coupon."""
coupons = {
"SAVE10": 10,
"SAVE20": 20,
"BIENVENUE": 15
}
remise = coupons.get(code_coupon, 0)
return appliquer_remise(total, remise)
git add app.py
git commit -m "feat(panier): ajout du système de codes coupon"

# Trouver quand "appliquer_remise" est apparue pour la première fois
git log -S "appliquer_remise" --oneline

# Voir le changement exact
git log -p -S "appliquer_remise" --oneline

Utiliser git blame

# Voir qui a écrit chaque ligne
git blame app.py

# Se concentrer sur des lignes spécifiques
git blame -L 1,10 app.py

Partie 3 : Annuler des changements

3a. Restaurer les changements du répertoire de travail

# Modifier README.md
echo "## TRAVAIL EN COURS - NE PAS UTILISER" >> README.md

# Vérifier le statut
git status
git diff README.md

# Oups ! Annuler le changement
git restore README.md

# Vérifier que le changement est parti
git diff README.md
cat README.md

3b. Désindexer un fichier

# Créer un nouveau fichier accidentellement inclus
echo "mon_mot_de_passe=secret123" > secrets.txt

# Tout ajouter par erreur
git add .
git status
# secrets.txt est maintenant en staging — oups !

# Le désindexer
git restore --staged secrets.txt
git status
# secrets.txt est retourné à l'état non suivi

# L'ajouter à .gitignore pour que ça n'arrive plus
echo "secrets.txt" >> .gitignore
git add .gitignore
git commit -m "chore: ajouter secrets.txt à .gitignore"

3c. Annuler un commit avec git reset

# Faire un commit désorganisé
echo "# TODO: corriger ça plus tard" >> app.py
echo "import pdb; pdb.set_trace()" >> app.py
git add app.py
git commit -m "WIP commit temporaire"

# Oups ! Annuler mais garder les changements dans le répertoire de travail
git reset HEAD~1
git status
# app.py est modifié mais pas commité

# Supprimer les lignes de debug, puis :
git restore app.py
git status
# Répertoire de travail propre, le mauvais commit est parti

3d. Annulation sûre avec git revert

Ajoutez cette fonction cassée à la fin de app.py :

def fonction_cassee():
# Cette fonction a un bug critique
return 1/0 # Division par zéro !
git add app.py
git commit -m "feat: ajout fonction cassée (simulation d'une mauvaise publication)"

# On ne peut pas utiliser reset car c'est "publié"
# Utiliser revert pour créer un commit d'annulation sûr
git revert HEAD --no-edit

# Vérifier que la fonction est disparue de app.py
cat app.py

# Voir l'historique complet
git log --oneline

Partie 4 : Utiliser git stash

Ajoutez cette fonction à la fin de app.py :

def points_fidelite(total, multiplicateur=1.0):
"""Calculer les points de fidélité gagnés pour un achat."""
points_base = int(total)
return int(points_base * multiplicateur)
# Vous êtes à mi-chemin et recevez une demande urgente
# NE PAS commiter un travail à moitié terminé — utilisez stash !

git status
git stash save "WIP: fonctionnalité points de fidélité"

# Vérifier que le répertoire de travail est propre
git status
cat app.py # la fonction points_fidelite a disparu

# Faire le travail urgent
echo "# Note de correction d'urgence" >> README.md
git add README.md
git commit -m "docs: ajout note de correction d'urgence"

# Revenir à votre fonctionnalité
git stash list
git stash pop

# Vérifier que la fonctionnalité est revenue
cat app.py # la fonction points_fidelite est de retour

# Terminer et commiter
git add app.py
git commit -m "feat(panier): ajout du système de points de fidélité"

# Nettoyer le changement README.md
git restore README.md

Checklist de validation

  • L'historique affiche au moins 8 commits avec des messages significatifs
  • Tous les messages de commit suivent le format type: description
  • git log --oneline affiche un historique propre
  • Vous avez utilisé avec succès git add -p pour le staging partiel
  • Vous pouvez utiliser git restore, git reset et git revert dans le bon contexte
  • Vous avez utilisé git stash pour changer de contexte

Vérification finale de l'historique

# Voir l'historique complet du projet
git log --oneline --stat

# Vérifier l'état final du fichier
cat app.py

Fonctions finales attendues dans app.py :

  • calculer_total (avec quantité)
  • appliquer_remise (avec validation)
  • formater_prix (avec devise)
  • calculer_taxe
  • appliquer_coupon
  • points_fidelite

Défis bonus

  1. git bisect : Introduire un bug dans un nouveau commit, puis utiliser git bisect pour trouver quel commit l'a introduit
  2. Commits multi-lignes : Refaire un de vos commits avec un corps détaillé en utilisant git commit --amend
  3. git log --format : Créer un format personnalisé qui affiche : hash, auteur, date, sujet

Résumé

Dans ce TP, vous avez pratiqué tous les fondamentaux Git :

  • Staging précis et commits significatifs
  • Navigation et recherche dans l'historique
  • Méthodes d'annulation sûres et non sûres
  • Changement de contexte avec stash

Vous êtes prêt pour le Module 02 — Branches & Merge !