Cela fait presque 2 mois que j’utilise git et git-svn au lieu de svn, pour Wormux ou dans mon travail. Git est sans doute plus complexe que subversion, mais cette complexité apporte quelques avantages (je suis plutôt réservé quant aux avantages pour des graphistes ou autres).
Le micro-commit
Avec git, plus d’hésitation à “commiter” localement les fichiers une fois qu’on commence à avoir quelque chose de convenable. Si au final, ce n’était pas une bonne idée, il suffira de revenir en arrière dans l’historique mais les autres développeurs ne seront pas impactés. Ça permet d’avoir des messages de commits plus précis, et des modifications plus fines par commit, plus facile à annuler et à comprendre. On est alors dans un cycle de développement beaucoup plus itératif.
Admettons qu’on veuille faire une modification massive de l’organisation du code et qu’on souhaite que tout ne soit visible qu’en version “finale” aux autres développeurs, car on est pas sûr à 100% de ce qu’on va faire, et que l’on craigne devoir revenir en arrière plusieurs reprises dans le processus. Avec git, à chaque étape, on fait un commit, et si finalement les dernières modifications (non commitées) ne conviennent pas, on utilisera git stash
ou git checkout HEAD
pour annuler ces modifications. Une fois qu’on est satisfait, on envoie le tout sur le dépôt centralisé avec git svn dcommit
:)
Avec subversion, il est probable qu’on n’ait pas osé commiter chaque petite modification, et du coup, dès qu’il faut revenir en arrière, c’est galère :(
La gestion de branche locale à porter de main
L’autre avantage, c’est la facilité avec laquelle on peut gérer des branches locales. Par défaut, avec git-svn, on a une branche locale appelée master. Personnellement, je ne fais aucune modification sur cette branche et me contente de la maintenir à jour par rapport au trunk svn à l’aide des commandes suivantes :
git svn fetch
pour mettre à jour l’historique par rapport aux modifications apportées sur le dépôt centralisé SVN. Ça n’applique pas ces modifications sur votre copie locale.
git checkout master
pour passer sur la branche master. Nécessaire uniquement si vous étiez sur une autre branche.
git rebase trunk
pour synchroniser la branche courante avec la branche distante trunk.
Je fais toutes mes modifications sur une autre branche, appelons là local-devel. Je crée la branche avec git branch local-devel
puis passe sur cette branche avec git checkout local-devel
. À partir de là, je commence à travailler puis commite localement de temps en temps.
Il m’est arrivé par 2 fois d’avoir une correction de bug plus urgente à faire. Je repasse alors sur la branche master (git checkout master
), je la met à jour (git svn fetch && git rebase trunk
), je branche (git branch fastfix && git checkout fastfix
), je corrige le bug, je compile, je teste, je commite localement (git commit -a
), je propage la modification (git svn dcommit
), je remet à jour ma branche master (git checkout master && git rebase trunk
) et efface la branche devenue inutile (git branch -D fastfix
) puis je retourne ensuite à mon développement standard que je rebase sur la branche master (git checkout local-devel && git rebase master
). C’est une certaine gymnastique, mais au final, c’est plus confortable que faire un svn diff qu’on redirige dans un fichier pour ré-appliquer le patch plus tard ;)