PROJET AUTOBLOG


Sam & Max: Python, Django, Git et du cul

Site original : Sam & Max: Python, Django, Git et du cul

⇐ retour index

Mise à jour

Mise à jour de la base de données, veuillez patienter...

Annuler les derniers commits avec Git

dimanche 29 juin 2014 à 10:59

(Amélioration de ce dont je parle ici)

Use case typique : on a merdé les derniers commits, et on veut oublier tout ce qu’on a fait et retourner à l’état d’il y a x commits précédents.

Par exemple, là je veux revenir à mon commit 85711ad... :

commit 093bab5aa9d41f580037d51421b7c5d0db73e2ce
Author: sam 
Date:   Sat Jun 28 09:37:55 2014 +0700

    Ok, c'est la merde internationale

commit 0b768f1c0e37a6141e6cd4c472eb3f369f4334d7
Author: sam 
Date:   Sat Jun 28 09:37:36 2014 +0700

    Je commence à merder

commit 85711ad1e8c54f3fd3048d405addef48921e90fd
Author: sam 
Date:   Sat Jun 28 09:37:20 2014 +0700

    J'adore ce commit

Il y a plein de manières de faire, et on voit sur la toile beaucoup de solutions à base de checkout et de reset. La plupart sont dangereuses ou ont un résultat inattendu, présuppose un état de votre repo ou va vous mettre dans une situation que vous ne maîtrisez pas.

Devinez quoi ? Il y a plus simple, et plus propre.

Etape 1: avoir une copie de travail propre

Avant d’inverser des commits, assurez vous que votre copie de travail est nette. Pas de fichiers modifiés en attente d’être commités. Le moins de fichiers non trackés par git possible (idéalement zéro, soit c’est commité, soit c’est dans le .gitignore).

Si vous avez des fichiers modifiés, vous pouvez soit les mettre de côté temporairement avec git stash, soit annuler toutes les modifications avec git reset --hard HEAD. Attention, cette dernière commande n’est pas réversible et va mettre à plat votre copie de travail pour qu’elle soit l’exacte copie du dernier commit de votre histo.

Etape 2

???

Etape 3: profit !

git revert --no-commit 85711ad1..HEAD

Ceci va modifier la copie de travail (donc les fichiers que vous avez sur le disque dur en direct, pas l’histo git) en appliquant des patchs qui contiennent les différences entre HEAD et le commit avec ce hash.

En clair : vos fichiers vont être dans l’état dans lequel ils étaient à ce commit. En prime, l’index est mis à jour.

Vous pouvez alors faire les derniers ajustements que vous le souhaitez. Il faut ensuite finaliser la procédure par un commit avec un message significatif :

git commit -m "Abort ! Abort ! Inversion des 2 derniers commits, retour à 85711a"

Si vous aviez fait un stash, c’est le moment de faire un stash apply derrière.

Maintenant, si vous matez l’histo, vous verrez qu’on n’a pas effacé les commits précédents, on a juste fait un commit qui inverse tout ce qu’ils avaient fait :

commit 03e55de36ad29a26a461874988d4066ebf6fe6be
Author: sam 
Date:   Sat Jun 28 09:43:32 2014 +0700

    Abort ! Abort ! Inversion des 2 derniers commits, retour à 85711a

commit 093bab5aa9d41f580037d51421b7c5d0db73e2ce
Author: sam 
Date:   Sat Jun 28 09:37:55 2014 +0700

    Ok, c'est la merde internationale

commit 0b768f1c0e37a6141e6cd4c472eb3f369f4334d7
Author: sam 
Date:   Sat Jun 28 09:37:36 2014 +0700

    Je commence à merder

commit 85711ad1e8c54f3fd3048d405addef48921e90fd
Author: sam 
Date:   Sat Jun 28 09:37:20 2014 +0700

    J'adore ce commit

Ce qui évite bien des problèmes : pas de réécriture de l’histo, possibilité de récupérer du code dans les commits inversés plus tard, claire indication de ce qui s’est passé…

N’oubliez pas que souvent, revenir à un commit précédent est overkill. Il est généralement beaucoup plus simple de juste récupérer un ou deux fichiers dans l’état de l’époque avec :

git checkout [hash] -- chemin/vers/fichier

flattr this!

Error happened! 0 - count(): Argument #1 ($value) must be of type Countable|array, null given In: /var/www/ecirtam.net/autoblogs/autoblogs/autoblog.php:428 http://ecirtam.net/autoblogs/autoblogs/sametmaxcom_a844ada43a979e3b1395ab9acb6afafb84340999/?Inverser-les-derniers-commits-avec-Git #0 /var/www/ecirtam.net/autoblogs/autoblogs/autoblog.php(999): VroumVroum_Blog->update() #1 /var/www/ecirtam.net/autoblogs/autoblogs/sametmaxcom_a844ada43a979e3b1395ab9acb6afafb84340999/index.php(1): require_once('...') #2 {main}