Pour déplacer le pointeur HEAD sur un commit identifié par son SHA (pour l'exemple 0cb5c64):
git reset --hard 0cb5c64
Le blob précédemment pointé par le HEAD n'est alors plus référencé mais il est conservé dans le dépôt. Git conserve un moment les données pour permettre à l'utilisateur de rattraper d'éventuelles erreurs de manipulation.
Il est possible de forcer le nettoyage du dépôt, ce qui conduira à la suppression de tous les objets non référencés:
git reflog expire --expire-unreachable=now --all git gc --prune=now
Dans l'exemple ci-dessous on souhaite abandonner les modifications apportées sur la branche master et ne conserver que le travail de la branche de dev, on va déplacer l'étiquette master vers dev
* ccc3065 (HEAD -> master) Modification fileA.txt | * 3dd7f5b (dev) Ajout fichier B |/ * c21ec74 Import initial
git checkout master git reset --hard 3dd7f5b
Si on affiche à nouveau l'historique, le blob ccc3065 pointé précédemment par le head n’apparaît plus:
* 3dd7f5b (HEAD -> master, dev) Ajout fichier B * c21ec74 Import initial
master et dev pointent sur le blob 3dd7f5b. On peut cependant encore afficher le blob ccc3065:
git show ccc3065
commit ccc3065cf197b028de87a4786aa64a7ac19f1454
Author: Yoann BEZILLE <yoann.bezille@mairie-tournefeuille.fr>
Date: Tue Jan 25 21:16:42 2022 +0100
Modification fileA.txt
. . .
La commande git show présente le SHA complet, on retrouve l'objet dans le dépôt:
cd .git/objects/cc/ ls -l total 4 -r-------- 1 yoann yoann 848 janv. 25 21:16 c3065cf197b028de87a4786aa64a7ac19f1454
Pour forcer la suppression de tous les objets détachés de toute branche:
git reflog expire --expire-unreachable=now --all git gc --prune=now
Après exécution des commandes ci-dessus, le blob n'existe plus:
git show ccc3065 fatal: argument 'ccc3065' ambigu : révision inconnue ou chemin inexistant.