Table des matières

, , , ,

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 <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.

Références