{{tag>dev git supprimer blob commit}}
====== Git : Déplacer le pointeur HEAD ======
La réécriture d’historique ne doit être faite que sur un dépôt local.
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:
Les commandes ci-dessous suppriment des objets que vous pourriez vouloir conserver: stashs, vieux historiques ne se trouvant pas sur des branches, etc. En cas de doute, se référer à la documentation officielle et sauvegarder le dépôt avant toute modification.
git reflog expire --expire-unreachable=now --all
git gc --prune=now
===== Exemple =====
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
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.
===== Références =====
* https://stackoverflow.com/questions/1904860/how-to-remove-unreferenced-blobs-from-my-git-repository