Nouveau en Git 2.23 : git restore

Tu le sais peut-être déjà, une nouvelle version de Git est sortie en août 2019 et ajoute 2 nouvelles commandes dérivées de la commande checkout : git restore et git switch

Alors pourquoi créer des commandes qui enrobent le comportement d’une autre ? Eh bien le problème avec git checkout, c’est que c’est un concept assez ambigu, même chez les anglophones. Les personnes qui maintiennent Git on donc été décidé d’ajouter ces commandes pour avoir un vocabulaire plus proche des actions qu’on va mener. En revanche, elles sont pour l’instant toutes les deux à l’état expérimental, ce qui est écrit en gros dans la doc’ et implique qu’on n’est pas à l’abri de légères évolutions dans leur comportement.

Je vais me concentrer ici sur la deuxième commande, git restore, qui permet de restaurer des fichiers dans la copie de travail comme le permettent git checkout et git reset, selon que mes modifications sont indexées ou non. Et n’aie pas peur si tu as tes habitudes avec checkout et reset, tu peux continuer à les utiliser sans problème.

Défaire une modification dans la copie de travail

Je commence avec le premier cas d’utilisation de restore qui sert à défaire une modification dans ma copie de travail. Si j’effectue une modif’, je peux faire un git restore mon-fichier pour appliquer la dernière version connue de l’index.

Je te montre ce que ça donne dans le terminal. 

(Exemple 01-undo-wd-changes)

Mon exemple est déjà prêt avec des fichiers modifiés, comme me le montre git status. Je vois aussi que Git m’affiche la marche à suivre : « utilisez "git restore <fichier>..." pour annuler les modifications dans la copie de travail ». Je m’exécute et fais donc un git restore fichier-1 sous-repertoire/fichier-4. Je refais ensuite un git status pour vérifier… et je n’ai plus de modifcation en cours. On le voit, restore opère exactement comme mon git checkout sur fichiers, et son nom est plus logique pour cette action.

Défaire un ajout ou une modification seulement dans l'index

Maintenant si j’ai des modifs et des créations de fichiers qui sont indexées je vais pouvoir faire un git restore avec l’option --staged pour annuler ces ajouts à l’index. Le gros avantage est que ça fonctionne comme git reset et git rm --cached de manière transparente et plus claire, vu que je demande de restaurer le stage.

(Exemple 03-unstage)

Voilà un exemple de projet avec des fichiers déjà indexés. Je vais en profiter pour créer un nouveau fichier et l’ajouter avec un git add, et pour faire original je vais l’appeler nouveau-fichier

Comme à mon habitude je fais un git status pour vérifier l’état actuel de mon travail. git status me donne une fois de plus la marche à suivre et écrit : « utilisez "git restore --staged <fichier>..." pour désindexer ». Je suis donc la procédure et je fais un git restore --staged fichier-1 sous-repertoire/fichier-3 nouveau-fichier. Je vérifie avec un git status et je constate que mes deux fichiers sont bien revenus à l’état modifié dans la copie de travail.

Défaire une modification dans l'index et la copie de travail

Dernier exemple avec des modifications que je veux retirer de l’index et de ma copie de travail. Cette fois je vais faire un  git restore --source=HEAD --staged --worktree <mes fichiers>. La syntaxe est ici très verbeuse, en tout cas plus verbeuse que git reset HEAD <mes-fichiers>, qui aurait fait la même chose. Après, ça a le mérite d’être explicite puisqu’on spécifie qu’on utilise les fichiers du HEAD pour les appliquer au stage et à la copie de travail.

(Exemple 02-undo-index-and-wd-changes)

Alors qu’est-ce que ça donne dans mon terminal ? Mon projet de démo est prêt avec des fichiers déjà indexés comme le confirme git status. En revanche, mon git status ne me donne pas la marche à suivre pour défaire d’un coup un fichier dans l’index et la copie de travail, je suis obligé de fouiller la doc’ pour voir l’option --worktree. Une fois que j’ai l’info, je sais que je peux faire un git restore --source=HEAD --staged --worktree <mes fichiers>. Un dernier git status pour vérifier… et c’est tout bon, mes modifs ont bien été défaites !