← HUB ✦ Holberton School — Version Control ✦

GIT &
GITHUB

Maîtrise le flux. Collabore sans peur.

C'EST QUOI GIT & GITHUB ?
🎮 LES BASES

Git est un système de contrôle de version qui tourne localement sur ta machine. Il enregistre l'historique de tes modifications. GitHub est un service en ligne qui héberge tes repos Git et permet la collaboration.

🕹️ ANALOGIE GAMING

Git, c'est le système de sauvegarde de ton jeu RPG. Chaque commit est un checkpoint auquel tu peux revenir. GitHub, c'est le serveur en ligne où tu synchronises ta partie pour jouer avec tes amis ou sauvegarder dans le cloud. Tu peux créer des branches = des timelines parallèles pour tester des builds alternatifs sans casser ta run principale.

Working
Directory
→
Staging
Area
→
Local
Repo (.git)
→
Remote
GitHub

   git add         git commit          git push

INSTALLATION & CONFIGURATION
⚙️ PREMIÈRE CONFIGURATION — À FAIRE UNE SEULE FOIS
# Installer Git (Ubuntu/Debian)
sudo apt-get install git

# Configurer ton identité (apparaît dans chaque commit)
git config --global user.name "Ton Prénom Nom"
git config --global user.email "[email protected]"

# Vérifier la config
git config --list

# Définir l'éditeur par défaut (nano = plus simple)
git config --global core.editor "nano"

# Définir la branche par défaut sur 'main'
git config --global init.defaultBranch main
Sans --global, la config s'applique uniquement au repo courant. Avec --global, elle s'applique à tous tes repos sur ta machine.
CRÉER UN REPO — LOCAL & REMOTE
🆕 CRÉER UN REPO LOCAL
# Initialiser un nouveau repo
git init
# → crée un dossier .git caché

# Voir l'état du repo
git status

# Ajouter des fichiers au staging
git add fichier.c     # un fichier
git add .             # TOUT le dossier

# Faire un commit
git commit -m "feat: add main function"
☁️ CLONER UN REPO EXISTANT
# Cloner depuis GitHub
git clone https://github.com/user/repo.git

# Cloner dans un dossier spécifique
git clone https://github.com/user/repo.git mon-dossier

# Lier un repo local à un remote GitHub
git remote add origin https://github.com/user/repo.git

# Voir les remotes configurés
git remote -v
COMMANDES DU QUOTIDIEN — LE CYCLE DE BASE
🔄 LE WORKFLOW QUOTIDIEN
1

Vérifier l'état — toujours commencer par là

git status           # fichiers modifiés, staged, untracked
git diff             # voir les modifs non stagées ligne par ligne
git diff --staged    # voir ce qui est dans le staging
2

Stager les modifications

git add fichier.c    # stager un fichier précis
git add .            # stager tous les changements
git add -p           # choisir les hunks interactivement
git restore --staged fichier.c  # dé-stager sans perdre les modifs
3

Commiter avec un message clair

git commit -m "feat: add login function"
git commit -am "fix: correct null pointer"  # add + commit en 1 (fichiers déjà trackés)
git commit --amend   # modifier le DERNIER commit (message ou fichiers)
4

Push & Pull avec GitHub

git push origin main     # envoyer vers GitHub
git push -u origin main  # -u = set upstream (à faire 1 fois par branche)
git pull                 # récupérer + merger les changements distants
git fetch               # récupérer SANS merger (pour inspecter d'abord)
ÉCRIRE DE BONS MESSAGES DE COMMIT
✍️ CONVENTIONAL COMMITS — LA CONVENTION PRO

Un bon message de commit répond à : "Si appliqué, ce commit va..."

# Format : type: description courte (max 72 chars)

feat:     add user authentication system
fix:      correct null pointer in parse_input
docs:     update README with install instructions
refactor: simplify loop in ft_strlen
chore:    add .gitignore for object files
test:     add unit tests for malloc wrapper

# ❌ Mauvais messages
git commit -m "fix"              # trop vague
git commit -m "asdfgh"           # incompréhensible
git commit -m "Changed stuff"    # inutile
En anglais, commence par un verbe à l'impératif : add, fix, remove, update. Tes coéquipiers (et toi dans 3 mois) te remercieront.
LIRE L'HISTORIQUE — GIT LOG
📜 EXPLORER L'HISTORIQUE
git log                      # historique complet
git log --oneline            # 1 ligne par commit (le plus utile)
git log --oneline --graph --all  # graphe visuel des branches
git log -n 5                 # les 5 derniers commits
git log --author="Alice"      # commits d'une personne
git show a1b2c3d              # détails d'un commit précis
git log -p fichier.c          # historique + diff d'un fichier

Exemple de sortie git log --oneline --graph --all :

* f3a9c12 (HEAD -> main) Merge branch 'feature/login' |\ | * e4d8b01 (feature/login) feat: add password validation | * c2a7f90 feat: add login route * | b1e3d42 fix: correct memory leak in parser |/ * a0f2c11 (origin/main) feat: initial project setup
.GITIGNORE — EXCLURE DES FICHIERS
🙈 CRÉER UN .GITIGNORE

Fichiers à ne JAMAIS commiter : binaires compilés, fichiers secrets, dépendances.

# .gitignore — à créer à la racine du projet

# Binaires compilés (C)
*.o
*.a
a.out

# Fichiers secrets
.env
*.key
secrets.txt

# Éditeurs
.vscode/
*.swp
*~

# OS
.DS_Store        # macOS
Thumbs.db        # Windows
Génère un .gitignore adapté à ton projet sur gitignore.io. Si tu as déjà commité un fichier par erreur : git rm --cached fichier puis commit.
BRANCHES — TRAVAILLER EN PARALLÈLE
🌿 TOUT SUR LES BRANCHES
🕹️ ANALOGIE GAMING

Une branche, c'est une timeline alternative de ton projet. Sur main tu as la version stable. Sur feature/login tu expérimentes sans risquer de casser le jeu principal. Si ça marche, tu merge la timeline alternative dans la principale.

# Voir toutes les branches
git branch                   # branches locales (* = branche courante)
git branch -a               # locales + distantes
git branch -v               # avec le dernier commit de chaque

# Créer une branche
git branch feature/login    # créer sans changer de branche
git checkout -b feature/login  # créer ET basculer dessus
git switch -c feature/login    # même chose, syntaxe moderne

# Changer de branche
git checkout main            # ancienne syntaxe
git switch main              # syntaxe moderne (Git 2.23+)

# Renommer une branche
git branch -m ancien-nom nouveau-nom   # renommer branche locale
git branch -m nouveau-nom              # renommer la branche courante

# Supprimer une branche
git branch -d feature/login  # supprimer (si mergée)
git branch -D feature/login  # forcer la suppression
git push origin --delete feature/login  # supprimer sur GitHub

# Pousser une branche sur GitHub
git push -u origin feature/login  # -u = set upstream tracking
Convention de nommage : feature/nom-feature pour une nouvelle fonctionnalité, fix/nom-bug pour un correctif, hotfix/ pour une urgence en production.
MERGE — FUSIONNER DES BRANCHES
🔀 FUSIONNER UNE BRANCHE
# Scénario : merger feature/login dans main

git switch main                   # 1. aller sur la branche cible
git pull                           # 2. récupérer les dernières modifs
git merge feature/login           # 3. fusionner

# Merge avec message de commit explicite
git merge --no-ff feature/login -m "merge: add login feature"
# --no-ff = force un commit de merge même si fast-forward possible
# (recommandé pour garder l'historique des branches)

# Annuler un merge en cours
git merge --abort
Avant merge : main: A --- B feature: C --- D Après merge (--no-ff) : main: A --- B ----------- M (M = commit de merge) \ / feature: C --- D
CONFLITS — LES RÉSOUDRE SEREINEMENT
⚡ QUAND UN CONFLIT ARRIVE

Un conflit se produit quand deux branches ont modifié la même ligne du même fichier. Git ne sait pas quelle version garder.

1

Git marque les fichiers en conflit

git status
# Both modified: src/main.c
2

Ouvrir le fichier — lire les marqueurs

<<<<<<< HEAD # ta version (branche courante) int count = 0; ======= # séparateur int count = 1; >>>>>>> feature/login # version de l'autre branche
3

Choisir (ou combiner) et nettoyer les marqueurs

int count = 0; # garder ta version, supprimer tout le reste

Supprimer les lignes <<<<<<<, =======, >>>>>>> — elles ne doivent plus exister dans le fichier final.

4

Marquer comme résolu et commiter

git add src/main.c         # marquer le conflit comme résolu
git commit -m "fix: resolve merge conflict in main.c"
Ne jamais laisser des marqueurs de conflit (<<<<<<<) dans le code commité. Utilise git diff pour vérifier avant de commiter.
ROLLBACK — REVENIR EN ARRIÈRE
⏪ DEUX STRATÉGIES SELON LE CONTEXTE
⚠️ GIT RESET — RÉÉCRIT L'HISTORIQUE
# Annuler le dernier commit
# (garde les modifs dans staging)
git reset --soft HEAD~1

# Annuler + dé-stager les modifs
# (garde les modifs dans les fichiers)
git reset --mixed HEAD~1

# Annuler + SUPPRIMER les modifs
# ⚠️ DESTRUCTIF — IRRÉCUPÉRABLE
git reset --hard HEAD~1

# Revenir à un commit précis
git reset --hard a1b2c3d

❌ N'utilise JAMAIS reset sur des commits déjà pushés et partagés — ça crée des conflits pour toute l'équipe !

✅ GIT REVERT — SAFE EN ÉQUIPE
# Créer un nouveau commit qui
# annule un commit précédent
# (ne réécrit PAS l'historique)
git revert a1b2c3d

# Revert sans ouvrir l'éditeur
git revert a1b2c3d --no-edit

# Revert le dernier commit
git revert HEAD

✅ revert est toujours safe : il ajoute un commit d'annulation sans modifier l'historique existant.

Règle d'or : branche privée non partagée → reset OK. Branche partagée avec l'équipe → toujours revert.
AUTRES COMMANDES ESSENTIELLES
🛠️ STASH, TAG, RESTORE ET PLUS
# STASH — mettre de côté des modifs temporairement
git stash                   # sauvegarder les modifs non commitées
git stash pop               # restaurer les modifs sauvegardées
git stash list              # voir les stashs
git stash drop              # supprimer le dernier stash

# RESTORE — annuler des modifs
git restore fichier.c       # annuler les modifs non stagées
git restore --staged fichier.c  # retirer du staging

# TAG — marquer une version
git tag v1.0.0              # créer un tag léger
git tag -a v1.0.0 -m "Release v1.0.0"  # tag annoté (recommandé)
git push origin --tags      # pousser tous les tags
git tag                     # lister tous les tags

# CHERRY-PICK — appliquer un commit spécifique sur la branche courante
git cherry-pick a1b2c3d
COLLABORATION — PROJETS DE GROUPE
👥 AJOUTER DES COLLABORATEURS SUR GITHUB
1

Inviter un collaborateur (repo privé ou public)

Sur GitHub : Settings → Collaborators → Add people → entrer le username GitHub de ton coéquipier → il reçoit un email d'invitation.

2

Chacun clone le repo

git clone https://github.com/owner/projet-groupe.git
cd projet-groupe
3

Chacun travaille sur sa propre branche

# Alice travaille sur sa feature
git switch -c feature/alice-auth

# Bob travaille sur la sienne
git switch -c feature/bob-dashboard
4

Récupérer le travail des autres régulièrement

git switch main
git pull                      # récupérer les dernières modifs
git switch feature/alice-auth
git merge main               # mettre ta branche à jour
GITHUB FLOW — LE WORKFLOW PROFESSIONNEL
🚀 LE CYCLE COMPLET D'UNE FEATURE
1. Créer
une branche
→
2. Commiter
régulièrement
→
3. Push sur
GitHub
→
4. Ouvrir une
Pull Request
→
5. Review
par l'équipe
→
6. Merge dans
main
# 1. Partir toujours d'un main à jour
git switch main && git pull

# 2. Créer une branche descriptive
git switch -c feature/user-authentication

# 3. Travailler et commiter souvent
git add . && git commit -m "feat: add JWT token generation"
git add . && git commit -m "feat: add token validation middleware"

# 4. Pousser la branche
git push -u origin feature/user-authentication

# 5. Sur GitHub : New Pull Request → décrire → assigner reviewers

# 6. Après merge sur GitHub, nettoyer
git switch main
git pull                                    # récupérer le merge
git branch -d feature/user-authentication  # supprimer la branche locale
Une Pull Request = une opportunité de review avant de merger dans main. Toujours décrire ce que fait la PR et comment tester. Jamais merger sa propre PR sans review si on est en équipe.
TABLEAU RÉCAP — TOUTES LES COMMANDES
📊 RÉFÉRENCE RAPIDE COMPLÈTE
CommandeCe que ça fait
git initInitialise un repo Git dans le dossier courant
git clone <url>Clone un repo distant en local
git statusÉtat du repo (modifiés, stagés, non trackés)
git add .Stage tous les fichiers modifiés
git commit -m "msg"Enregistre les changements stagés
git pushEnvoie les commits sur GitHub
git pullRécupère + merge les commits distants
git fetchRécupère sans merger (inspecter d'abord)
git log --onelineHistorique compact des commits
git diffVoir les modifications non stagées
git branchLister les branches locales
git switch -c <branche>Créer et basculer sur une nouvelle branche
git switch <branche>Changer de branche
git branch -m <nouveau>Renommer la branche courante
git merge <branche>Fusionner une branche dans la courante
git merge --abortAnnuler un merge en cours
git revert <hash>Annuler un commit (safe, crée un nouveau commit)
git reset --soft HEAD~1Annuler le dernier commit, garder les modifs stagées
git reset --hard HEAD~1Annuler + supprimer les modifs ⚠️ DESTRUCTIF
git stashMettre de côté les modifs non commitées
git stash popRestaurer les modifs mises de côté
git restore <fichier>Annuler les modifs non stagées d'un fichier
git tag -a v1.0.0 -m "msg"Créer un tag annoté (release)
git remote -vVoir les remotes configurés
git branch -d <branche>Supprimer une branche locale (si mergée)
git push origin --delete <b>Supprimer une branche sur GitHub
ERREURS CLASSIQUES & SOLUTIONS
🆘 LES SITUATIONS DE PANIQUE — ET LEURS SOLUTIONS
"J'ai commité sur main au lieu de ma branche"
git branch feature/ma-feature  # créer la branche avec les commits
git reset --hard origin/main   # remettre main à son état distant
git switch feature/ma-feature  # aller sur la bonne branche
"J'ai fait un mauvais message de commit"
git commit --amend -m "feat: bon message cette fois"
# Attention : seulement si le commit n'est PAS encore pushé !
"git push refusé — rejected"
# Quelqu'un a pushé avant toi — récupère d'abord
git pull --rebase    # récupère + rejoue tes commits dessus
git push             # maintenant ça marche
"J'ai supprimé un fichier par erreur"
git restore fichier-supprime.c  # si pas encore commité
git checkout HEAD~1 -- fichier.c # récupérer depuis un commit précédent
"J'ai commité un fichier secret (.env, token)"
git rm --cached .env           # retirer du tracking sans supprimer
echo ".env" >> .gitignore       # ajouter au .gitignore
git commit -m "chore: remove .env from tracking"
# ⚠️ Si déjà pushé : considère le secret comme compromis, change-le !
"Je veux voir l'état d'un ancien commit sans modifier"
git checkout a1b2c3d    # "detached HEAD" — lecture seule
git switch main        # revenir à la normale
RÉSUMÉ — LE WORKFLOW PARFAIT EN ÉQUIPE
🏆 LA CHECKLIST DU PRO
╔══════════════════════════════════════════════════════════════════╗
║  AVANT de commencer à coder                                      ║
╚══════════════════════════════════════════════════════════════════╝
git switch main && git pull          # toujours partir d'un main à jour
git switch -c feature/ma-feature    # créer une branche dédiée

╔══════════════════════════════════════════════════════════════════╗
║  PENDANT le développement                                        ║
╚══════════════════════════════════════════════════════════════════╝
git status                            # vérifier régulièrement
git add . && git commit -m "feat: ..."  # commiter souvent, petites étapes
git push                              # pousser régulièrement (backup)

╔══════════════════════════════════════════════════════════════════╗
║  POUR merger dans main                                           ║
╚══════════════════════════════════════════════════════════════════╝
# Option A — Pull Request sur GitHub (recommandé en équipe)
git push -u origin feature/ma-feature  # puis New PR sur GitHub

# Option B — Merge local (projets solo)
git switch main && git pull
git merge --no-ff feature/ma-feature
git push
git branch -d feature/ma-feature       # nettoyer

╔══════════════════════════════════════════════════════════════════╗
║  RÈGLES D'OR                                                     ║
╚══════════════════════════════════════════════════════════════════╝
# ✅ Commiter souvent, avec des messages clairs
# ✅ Toujours travailler sur une branche, jamais directement sur main
# ✅ Toujours git pull avant de commencer
# ✅ Un .gitignore dès le début du projet
# ✅ revert en équipe, reset seulement en solo
# ❌ Jamais commiter de secrets, tokens, mots de passe
# ❌ Jamais force push sur main (git push --force)