Je suis développeur web freelance et propose des formations à Symfony2 ! Contactez-moi pour en discuter.

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 :

  • Je travaille sur une fonctionnalité avec un collègue. Il a besoin d’un correctif sur un bout de code que j’ai écrit avant pour pouvoir continuer à travailler. Je travaille sur une branche ‘feature’, et doit donc revenir sur la branche ‘dev’, dernière version stable de ma branche de développement, pour y apporter un correctif. Dans ma branche ‘feature’ actuelle, je suis en plein milieu d’un développement, je ne peux absolument pas lui fournir ce nouveau code à moitié terminé, ni faire un commit du code au milieu de son développement pour changer de branche. Je dois donc mettre le code sur lequel je travaille actuellement de côté, pour le reprendre par la suite.
  • Je travaille sur une fonctionnalité seul, en javascript par exemple. Lors de mon développement, je me rends compte qu’avant de pouvoir finir ce que j’ai commencé, je dois changer quelque chose ailleurs dans le code (sur la partie PHP qui va exposer une API par exemple). Comme j’aime avoir des commits unitaires et fonctionnellement séparés, je préfère avoir les modifications de l’API en PHP dans un commit, et celles du JS qui l’utilise ensuite. Comme j’ai déjà commencé à travailler sur le JS, je dois mettre mon code de côté.

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.

1
2
3
git stash
Saved working directory and index state WIP on feature_branch: d9e2bb5 merged v5.3.4
HEAD is now at d9e2bb5 merged v5.3.4

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

1
2
3
4
5
6
[clem@clem:~/dev/currProject] git status -s
## feature_branch
# -> rien, les modifications se sont ajoutées à la pile de la réserve
[clem@clem:~/dev/currProject] git stash list
# Sur un écran à part, on peut voir que la pile
# de la réserve contient un élément: nos modifications

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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[clem@clem:~/dev/currProject] git stash pop
# On branch feature_branch
# You are currently rebasing branch 'bh' on 'fb7b1dc'.
#   (all conflicts fixed: run "git rebase --continue")
#
# You are currently bisecting branch 'bh'.
#   (use "git bisect reset" to get back to the original branch)
#
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   app/Berthe/ServiceXHR/ServiceXHRQuote.php
#   modified:   lib/Evaneos/Berthe/JsonServer.php
#
no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (21f9583cd4159df5627307eada103e29fe165431)
[clem@clem:~/dev/currProject] git status -s
## feature_branch
 M app/Berthe/ServiceXHR/ServiceXHRQuote.php
 M lib/Evaneos/Berthe/JsonServer.php

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 :

1
2
3
4
5
6
7
8
9
10
11
[clem@clem:~/dev/currProject] git stash
Saved working directory and index state WIP on feature_branch: d9e2bb5 merged v5.3.4
HEAD is now at d9e2bb5 merged v5.3.4
# Je sauvegarde les modifications
[clem@clem:~/dev/currProject] git stash drop
Dropped refs/stash@{0} (befd3f17f416548c30624a01118b609ebb1bc0a8)
# Je n'en ai plus besoin, je les supprime du stash.
[clem@clem:~/dev/currProject] git status -s
## feature_branch
# Ma branche courante est vide. Dans cet exemple, c'est comme
# si j'avais fait git reset HEAD --hard.

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

Répondre

Unable to load the Are You a Human PlayThru™. Please contact the site owner to report the problem.