Sauvegarder une branche git, sans empêcher les rebase

2012-01-17

Je suis assez régulièrement dans une situation où je travaille sur une branche de longue durée (plus de quelques jours), appelons la big_feature.

Pour maintenir cette branche à jour par rapport à master, j’utilise de préférence git rebase (par rapport à git merge).

Ça donne par exemple :

$ git checkout big_feature
$ git rebase master

Le problème est que si je pousse ma branche big_feature sur un dépôt distant, les “rebase” deviennent dangereux. Mais si je ne pousse jamais cette branche, et que je perds le contenu de mon dépôt local, alors je perds tout mon travail sur cette branche.

Évidemment, tout développeur sérieux dispose de sauvegardes de son poste de travail, mais selon les outils il peut être fastidieux d’y accéder juste pour quelques fichiers. Et puis il y a ceux qui n’ont aucune sauvegarde (les fous !). Pourquoi ne pas utiliser Git pour ça ?

Je me suis donc créé un petit script (accessible depuis mes dépôts) qui me permet de pousser ma branche courante sur un dépôt distant (origin par convention, modifiable en ajoutant un paramètre à l’appel du script), mais de manière à identifier qu’elle n’est qu’à des fins de sauvegarde.

#!/bin/sh
set -e
CUR=`git branch | grep '\*' | awk '{print $2}'`
REM=${1:-'origin'}
git push --force ${REM} ${CUR}:backup/${USER}/${CUR}

On trouvera donc sur le dépôt distant, un groupe de branches appelées “backup”, puis un sous-groupe pour chaque développeur, dans lequel il y trouvera ses branches de sauvegardes, nommées comme ses branches locales.

Ça crée donc une convention, facile à comprendre.

Plus généralement, si il y a un ou plusieurs “/” dans le nom d’une branche, Git va traiter ça comme des portions d’arborescence de système de fichier et grouppera donc toutes les branches dans les mêmes dossiers et éventuellement sous-dossiers.

J’utilise ce système pour toutes les branches qui correspondent à des fonctionnalités, par exemple :

  • features/new_login
  • features/alternate_footer

Ainsi dans les outils (graphiques ou en mode texte), je vois ces branches groupées, voire même de manière arborescente. Si vous ouvrez le dossier .git de votre dépôt, vous verrez que Git crée réellement des dossiers et sous-dossiers dans .git/refs/heads et .git/refs/remotes/xyz/ et les branches y sont de vrais fichiers appelés comme la dernière partie du nom donné à la branche.


Commentaires

Matthieu Paret 2012-10-30 05:35:54

Pourquoi dis-tu “les “rebase” deviennent dangereux” ? Parce que l’on est obligé d’utiliser l’option -f lorsque l’on pousse la branche ?

Jérémy Lecour 2012-10-30 11:00:37

Si on travaille à plusieurs sur une même branche et que l’un d’entre nous modifie l’historique lié à la branche (ce qui se passe lors d’un rebase) les autres perdent la synchro et des prises de têtes arrivent à grand pas.

Matthieu Paret 2012-10-30 17:55:24

Avec un git pull –rebase, cela ne résoud pas en partie le problème ?