Aller au contenu principal

Aide-mémoire Git

Rangé par situation. Les six premières sections couvrent la journée ordinaire, la septième s'appelle « je me suis trompé » et c'est celle qu'on vient vraiment chercher.

Se configurer, une fois pour toutes

Terminal5 commandes
$git config --global user.name "Prénom Nom"
$git config --global user.email "prenom.nom@mail.fr"
$git config --global init.defaultBranch main
$git config --global pull.rebase false# fusionner plutôt que rejouer
$git config --list# tout relire

Démarrer

Terminal3 commandes
$git init# transformer le dossier courant en dépôt
$git clone <url># récupérer une copie d'un dépôt existant
$git clone <url> nom-local# en choisissant le nom du dossier

La boucle de la journée

Quatre commandes, dans cet ordre, et elles suffisent à presque tout.

Terminal5 commandes
$git status# où j'en suis : c'est la commande à taper en cas de doute
$git add fichier.py# préparer un fichier précis
$git add .# préparer tout ce qui a changé
$git commit -m "message" # enregistrer un instantané de ce qui est préparé
$git push# envoyer sur le dépôt distant
Les trois zones, qui expliquent tout le reste
Un fichier passe par trois endroits : le répertoire de travail, ce qu'on voit ; l'index, ce qui est préparé par add ; le dépôt, ce qui est enregistré par commit. Presque toutes les commandes d'annulation se lisent comme « ramener quelque chose d'une zone vers la précédente », et savoir de quelle zone il s'agit suffit à choisir la bonne.

Regarder ce qui s'est passé

Terminal7 commandes
$git log --oneline# une ligne par commit
$git log --oneline --graph --all# avec les branches dessinées
$git log -p fichier.py# l'historique d'un seul fichier, avec les diffs
$git diff# ce qui a changé et n'est pas préparé
$git diff --staged# ce qui est préparé et pas encore enregistré
$git show <commit># le contenu d'un commit
$git blame fichier.py# qui a écrit quelle ligne, et quand

Les branches

Terminal6 commandes
$git branch# lister
$git switch -c ma-branche# créer et s'y placer
$git switch main# revenir sur la principale
$git merge ma-branche# ramener son travail dans la branche courante
$git branch -d ma-branche# supprimer une branche fusionnée
$git push -u origin ma-branche# la publier la première fois

Travailler avec les autres

Terminal4 commandes
$git pull# récupérer et fusionner le travail des autres
$git fetch# récupérer sans fusionner, pour regarder d'abord
$git remote -v# voir les dépôts distants
$git log HEAD..origin/main# ce qui est arrivé et que je n'ai pas encore

En cas de conflit, Git s'arrête et marque les fichiers concernés. La marche à suivre est toujours la même : ouvrir chaque fichier, choisir ce qui reste entre les repères, effacer les repères, puis git add le fichier et git commit.

Terminal4 commandes
$git status# la liste des fichiers en conflit
$git add fichier-resolu.py
$git commit# le message de fusion est proposé
$git merge --abort# ou tout annuler et revenir avant la fusion

Je me suis trompé

C'est la section à mettre en signet. Elle est rangée par ce qu'on veut défaire.

Ce qu'on veutLa commande
Annuler mes modifications d'un fichier, non préparéesgit restore fichier
Retirer un fichier de la préparation, sans perdre les changementsgit restore --staged fichier
Corriger le message du dernier commitgit commit --amend -m "nouveau message"
Ajouter un oubli au dernier commitgit add oubli puis git commit --amend --no-edit
Annuler le dernier commit, garder les changementsgit reset --soft HEAD~1
Annuler le dernier commit et les changementsgit reset --hard HEAD~1
Annuler un commit déjà envoyé, proprementgit revert <commit>
Mettre mon travail de côté un instantgit stash puis git stash pop
Récupérer un commit perdugit reflog puis git reset --hard <commit>
reset ou revert, et pourquoi le choix n'est pas libre
reset réécrit l'histoire : il convient tant que les commits n'ont pas été envoyés. revert ajoute un commit qui défait le précédent, et c'est le seul choix acceptable sur une branche partagée. Réécrire une histoire que d'autres ont déjà récupérée les oblige à réparer leur copie, et c'est la manœuvre qui fâche une équipe.
Rien n'est perdu pendant trente jours
git reflog garde la trace de toutes les positions par lesquelles le dépôt est passé, y compris celles qu'aucune branche ne désigne plus. Un reset --hard malheureux se répare presque toujours en y retrouvant l'identifiant d'avant, puis en s'y replaçant. C'est la première chose à essayer avant de conclure qu'un travail a disparu.

Ce qui se trompe le plus souvent

Le piègeCe qu'il faut faire
reset sur une branche partagéerevert, qui ajoute un commit au lieu de réécrire
.gitignore posé trop tardgit rm --cached fichier pour cesser de le suivre
Un secret enregistré puis retiréle considérer comme divulgué et le changer
git add . sans regardergit status puis git diff avant chaque commit
Un reset --hard malheureuxgit reflog, qui garde tout pendant trente jours
Un conflit qu'on ferme sans relirechercher les repères restants avant de valider

Ne pas versionner n'importe quoi

Un fichier .gitignore à la racine, une ligne par motif.

Terminal1 commande
$cat .gitignore
node_modules/
__pycache__/
.env
*.log
dist/
.gitignore n'agit pas sur ce qui est déjà suivi
Ajouter un fichier au .gitignore ne le retire pas du dépôt s'il y a déjà été enregistré : Git continue de suivre ce qu'il suit. Il faut l'en sortir explicitement, en gardant le fichier sur le disque.
Terminal2 commandes
$git rm --cached .env# cesser de le suivre, sans le supprimer
$git commit -m "retirer .env du suivi"

Un secret déjà enregistré, lui, reste dans l'historique même après cette manœuvre. Le seul réflexe sûr est de le considérer comme divulgué et de le changer.

Pour aller plus loin

La gestion de versions avec Git explique ce que Git range et pourquoi, Git au quotidien déroule la journée type et les quatre façons d'annuler, et Travailler à plusieurs traite des branches, des conflits et de la revue.

Version imprimable : les tables de syntaxe seules, sur une feuille.

Les autres aide-mémoire sont sur cette page, et les exercices dans Pratiquer.