GIT insolite : ce moment où tu as fait n’importe quoi !

J’ai fait de la bonne m**** tout à l’heure mais je l’ai fixée alors je te partage ici mon expérience GIT du jour. Billet qui j’espère t’aidera pour retrouver non pas l’être mais le code cher.

Mais que se passe-t-il ?

Je créé mon petit plugin WP et je le versionne bien entendu ^^. Oui mais je l’ai créé déjà (je parle du code) et je fais :

git init
git remote add origin https://github.com/mon_pseudo_github/mondepot.git

et puis je fais :

git add .
git commit -m "initial"

Oui mais voilà la veille et l’avant-veille j’ai donné de ma personne pour contribuer en tant que bénévole à l’un des meilleurs WordCamp Paris de la lignée. Alors je suis joyeux mais un peu fatigué.

J’ai créé un dépôt sur GitHub initialisé avec un readme machin et au moment de faire :

git push

Il m’a bien dit que ce n’était pas possible et qu’il fallait mettre à jour (le readme machin à récup) avant de pousser.

Et là je me suis mis à copier-coller ce qu’il me disait sans réfléchir. « Sans réfléchir » c’est le début des emmerdes !

Et boom !

Tout pété, perdu les fichiers, je me retrouve avec un pauvre readme dans mon dossier, impossible de récupérer mes fichiers, aucun reset possible, les références introuvables !

Je ne sais pas ce que j’ai foutu mais ce n’est pas que du bon ! J’ai tout cassé :

stupid people

Mais put*** ils sont où ces fichiers ?!! Ho ! C’est GIT là ! Ils ne sont quand même pas perdus ?!! Non pas que le code soit précieux ou ultra-complexe mais c’est 30 minutes de ma vie quoi, je vais pas tout refaire.

La puissance de GIT : perdu de recherche !

L’occasion d’utiliser des commandes que je n’utilise pas au quotidien. Allez, je vais lancer les recherches, j’en ai rien à faire, même si cela prend un tout petit plus de temps que de réécrire le code je vais restaurer tout ça !

Sait-on jamais, cela pourrait me servir dans un autre contexte avec des classes un peu plus longues et pénibles à réécrire.

Je teste donc :

find .git/objects -type f

Eh oui GIT sauvegarde tout, réparti dans des objects soit tout plein de petits dossiers et sous-dossiers. Il me sort donc la liste des objets avec leurs SHA-1 respectifs.

cat-file

La commande précédente me donne donc une liste d’objects dans ce style :

.git/objects/ID_OBJECT/SHA-1

La commande cat-file de GIT m’a permis ici de restaurer mes fichiers qui n’étaient donc absolument pas perdu malgré mes errements du début :

git cat-file -p ID_OBJECTSHA-1

Détaillons ce qui se passe ici dans la commande :

le cat-file me permet d’inspecter l’object en question et en quelque sorte de récupérer les infos et l’option -p m’évite un affichage dégueulasse.

Comme ici je me rends compte que j’ai bien retrouvé le code que je croyais perdu je vais pouvoir restaurer tout ça :

git cat-file -p ID_OBJECTSHA-1 > mon_fichier.php

Si je fais maintenant :

less mon_fichier.php

Je vais retrouver normalement mon fichier trop longtemps disparu ^^.

Remarque : less est une commande linux qui permet de lire un fichier sans l’éditer. Elle est basée sur vi et more. Elle s’avère plus performante notamment quand les fichiers sont longs car elle n’a pas besoin de charger tout le fichier pour commencer à le lire.

Bonus

Si vous ne voulez pas vous amuser à ouvrir chaque object pour savoir s’il s’agit d’un js, d’un fichier php ou des fichiers de traduction par exemple, vous pouvez déjà faire :

git cat-file -t ID_OBJECTSHA-1

Vous aurez le type de fichier associé.

Passer de la bidouille à la théorie

Bon, arrivé à ce point on pourrait se dire que c’est réglé, seulement je ne sais pas vous mais moi j’ai bien envie d’aller plus loin. Pour l’avoir constaté la théorie est parfois perçue par certains comme rasoire et justement à éviter.

Il faut impérativement mettre en pratique parce que ouais la théorie c’est chiant, ça sert à rien, c’est pas la vraie vie.

C’est quelque part assez vrai mais pour mettre en pratique il faut bien abstraire à un moment ou un autre, et ce n’est pas parce que d’autres l’ont fait pour vous  (open source) que vous êtes exempté.

Comment GIT sauvegarde ses données ?

Après chaque commit, GIT stocke des « images » qu’on va pouvoir mixer par la suite autrement dit l’état des fichiers à un instant T.

Mais comme on est pas dans cette daube de SVN (c’est très personnel, j’exagère sûrement) on ne va pas enregistrer une copie de chaque fichier du dépôt.

GIT ne stocke donc pas des différences mais un flux d’images.

L’avantage de cette conception est, contrairement à SVN, de ne pas faire des enregistrements inutiles. Si rien n’est changé rien n’est enregistré.

Source

GIT dans tout ses états

Les 3 état d’un fichiers dans GIT sont :

  1. modified
  2. staged
  3. commited

« Modified », comme son nom l’indique mais les changements ne sont pas enregistrés encore. A partir de « staged » un marqueur est ajouté aux fichiers concernés pour être inclus dans le prochain enregistrement. « Commited », les changements sont enregistrés.

J’ai eu des remarques d’étudiants, comparant GIT à SVN et me disant :

avec SVN c’est enregistré automatiquement !
Oui mais SVN c’est moins sophistiqué et ça a rapidement trouvé ses limites comme expliqué plus haut. Donc certes, un peu plus de commandes, mais c’est tout à fait négligeable par rapport au gain obtenu.

Quand vous voyez apparaître un /.git/ dans vos dossiers après avoir « gitté » vos projets, c’est en fait un mini-système de fichiers avec sa base données qui sont créés et c’est ça qui se transmet d’un clone à l’autre ^^. Et c’est ça qui m’a permis de restaurer mes lignes de code tout à l’heure.

Disclaimer

Je ne prétends pas avoir la meilleure méthode de restore ici, elle a juste bien fonctionné ^^ et j’ai trouvé de la documentation en rapport.

Conclusion

La puissance de GIT est à nouveau démontrée ici j’espère. A l’instar des systèmes de fichiers UNIX et autres on peut arriver à restaurer des fichiers même quand on a fait n’importe quoi comme ici.

C’est tout de même rassurant, rien ne se perd, tout se transforme.