KeiruaProd

Utiliser git stash pour mettre de côté son travail

Bien que j’utilise git depuis un bon moment, j’ai longtemps été effrayé par l’usage de git stash, par peur de perdre du travail. A tort, car elle se révèle finalement très simple d’utilisation, et très pratique. Cette commande (to stash = réserver) permet de mettre de côté toutes les modifications en cours sans les commiter, pour pouvoir les reprendre plus tard.

Dans ma manière de travailler, c’est utile quand je travaille seul comme quand je travaille avec des collègues. Voici deux cas d’utilisation récents :

Ce que j’ai longtemps fait dans ces situations, c’est de faire un commit temporaire. J’ajoutais mes fichiers modifiés, et je laissais un commentaire du type « temporary commit, edit later ». Plus tard, lorsque je revenais sur le code en question, et que le travail terminé, j’éditais mon commit via git commit –amend. Cette commande permet d’éditer le dernier commit en ajoutant/supprimer des fichiers, et en changeant le message de commit. Attention, c’est à utiliser avec soin si vous pushez/pullez du code souvent.

Plutôt que de committer du code temporaire (qui a finalement tendance à pourir l’historique avec des commits que j’oublie de nettoyer), la solution préconisée par git pour ce genre de choses, c’est git stash.

Cette commande permet de mettre de côté ses modifications pour les récupérer ultérieurement. Une fois exécutée, on peut ensuite changer de branche, faire ses modifications dans la nouvelle branche et revenir, ou bien faire ses modifications directement dans la branche où l’on a réservé les modifications, cela n’est pas un problème.

Avec un exemple d’utilisation, vous allez voir qu’il est très simple de s’en servir. Le point de départ : vous êtes en train de travailler, vous avez ajouté certains fichiers, modifiés d’autres… en vous devez mettre les modifications de côté. C’est parti, on stash.

<br /> git stash<br /> Saved working directory and index state WIP on feature_branch: d9e2bb5 merged v5.3.4<br /> HEAD is now at d9e2bb5 merged v5.3.4<br />

Une fois que c’est fait, votre git status est vide.

<br /> [clem@clem:~/dev/currProject] git status -s<br />

feature_branch<br />

-> rien, les modifications se sont ajoutées à la pile de la réserve<br />

[clem@clem:~/dev/currProject] git stash list<br />

Sur un écran à part, on peut voir que la pile<br />

de la réserve contient un élément: nos modifications<br />

</code>

Vous changez de branche, faites ce que vous avez à faire, puis vient le moment où vous revenez sur la branche courante pour reprendre votre travail là où vous l’avez laissé. C’est le moment d’utiliser git stash pop.

<br /> [clem@clem:~/dev/currProject] git stash pop<br />

On branch feature_branch<br />

You are currently rebasing branch ‘bh’ on ‘fb7b1dc’.<br />

(all conflicts fixed: run “git rebase –continue”)<br />

#<br />

You are currently bisecting branch ‘bh’.<br />

(use “git bisect reset” to get back to the original branch)<br />

#<br />

Changes not staged for commit:<br />

(use “git add <file>…” to update what will be committed)<br />

(use “git checkout – <file>…” to discard changes in working directory)<br />

#<br />

modified: app/Berthe/ServiceXHR/ServiceXHRQuote.php<br />

modified: lib/Evaneos/Berthe/JsonServer.php<br />

#<br /> no changes added to commit (use “git add” and/or “git commit -a”)<br /> Dropped refs/stash@{0} (21f9583cd4159df5627307eada103e29fe165431)<br /> [clem@clem:~/dev/currProject] git status -s<br />

feature_branch<br />

M app/Berthe/ServiceXHR/ServiceXHRQuote.php<br /> M lib/Evaneos/Berthe/JsonServer.php<br /> </code>

Comme vous pouvez le voir sur les 2 commandes ci-dessus, git stash pop enlève les modifications de la pile, les met dans la branche courante, et supprime le sommet de la pile.

Le stash fonctionnant comme une pile, il peut arriver que l’on ne veuille pas récupérer ses modifications. Pour cela, on peut supprimer le dernier élément de la pile via git stash drop. Voici à quoi cela ressemble :

<br /> [clem@clem:~/dev/currProject] git stash<br /> Saved working directory and index state WIP on feature_branch: d9e2bb5 merged v5.3.4<br /> HEAD is now at d9e2bb5 merged v5.3.4<br />

Je sauvegarde les modifications<br />

[clem@clem:~/dev/currProject] git stash drop<br /> Dropped refs/stash@{0} (befd3f17f416548c30624a01118b609ebb1bc0a8)<br />

Je n’en ai plus besoin, je les supprime du stash.<br />

[clem@clem:~/dev/currProject] git status -s<br />

feature_branch<br />

Ma branche courante est vide. Dans cet exemple, c’est comme<br />

si j’avais fait git reset HEAD –hard.<br />

</code>

Et voila, non seulement c’est plus élégant que des commit temporaires, mais c’est aussi très simple d’utilisation.