scratch/content/html/fr/blog/2009-12-14-Git-vs--Bzr.md

152 lines
7.9 KiB
Markdown
Raw Normal View History

2010-04-29 14:59:14 +00:00
-----
2010-02-17 12:27:01 +00:00
isHidden: false
menupriority: 1
kind: article
created_at: 2009-12-14T10:46:36+02:00
2010-04-29 14:59:14 +00:00
title: Git ou Bazaar ?
2010-05-09 12:53:46 +00:00
author_name: Yann Esposito
author_uri: yannesposito.com
2010-04-29 14:59:14 +00:00
subtitle: Pourquoi je suis passé de Bazaar à Git
2010-02-17 12:27:01 +00:00
tags:
- git
- bzr
- DCVS
- Bazaar
-----
begindiv(intro)
Même si je considère que `git` a beaucoup de points noirs, je pense qu'il reste le meilleur DCVS à ce jour avec lequel travailler. C'est pourquoi je commencerai par parler des qualité de bazaar qui manquent à git. Ensuite seulement je donnerai le seul avantage de git qui suffit à le rendre préférable à Bazaar.
enddiv
## La découverte des DCVS
À savoir avant de débuter l'article. Je suis, comme beaucoup, un ancien utilisateur de *subversion*. Je trouve subversion très bien, mais j'ai été conquis par les capacités supplémentaires apportées par les systèmes de versions concurrentes *décentralisés*.
Il y a deux façon de percevoir les systèmes de versions. Soit on voit un système de branches (voir le très bon article sur [betterexplained](http://betterexplained.com/articles/a-visual-guide-to-version-control/)). Soit on peut voir les systèmes de versions comme des moyens d'appliquer des patches. C'est-à-dire que l'on peut soit se concentrer sur les nœuds soit sur les transitions du graphe induit par les différentes versions d'un projet.
Pour git, c'est plutôt ce deuxième point de vue qui a été adopté. C'est un peu normal, étant donné que c'est Linus Torvald qui l'a inventé pour combler les problèmes inhérent aux problèmes de création de code dans le noyau Linux. Et comme historiquement, la communauté Linux se base beaucoup sur les patches, il semblait logique que ce soit ce second point de vue qui soit adopté.
J'ai d'abord été convaincu par Bazaar. Pourquoi ? Les arguments en faveur de bazaar étaient : facilité d'utilisation en particulier, facilité d'adaptation pour tous ceux qui étaient habitués à subversion. Comme c'était mon cas, et que lorsque j'avais essayé de suivre la doc Git à l'époque c'était un peu épique.
Puis avec le temps, je me suis dit que je n'allais quand même pas mourir idiot et que j'allais me mettre sérieusement à `git` histoire de voir si ses défenseurs avaient vraiment raison.
Mon dieu, que ce fut fastidieux. La terminologie est *affreuse* ! Et ce n'est rien de le dire.
## Là où Bazaar est meilleur que `git`
Par exemple, `checkout` qui sert certainement à la même chose du point de vue technique, est dans l'usage un terme employé pour faire des actions qui semblent très différentes à un utilisateur λ. Exemple :
2010-04-15 09:45:50 +00:00
<div><code class="zsh">
2010-02-17 12:27:01 +00:00
git checkout pipo
2010-04-15 09:45:50 +00:00
</code></div>
2010-02-17 12:27:01 +00:00
annule une modification courante du fichier `pipo`
2010-04-15 09:45:50 +00:00
<div><code class="zsh">
2010-02-17 12:27:01 +00:00
git checkout pipo
2010-04-15 09:45:50 +00:00
</code></div>
2010-02-17 12:27:01 +00:00
change de la branche courante vers la branche `pipo`
Et là, comme moi, vous remarquez que la même commande à deux sens complètement différents. Comment ça se passe alors, quand il y a une branche `pipo` et un fichier `pipo` alors ? Et bien par défaut, ça change de branche. Pour lever l'ambigüité il faut utiliser la syntaxe
2010-04-15 09:45:50 +00:00
<div><code class="zsh">
2010-02-17 12:27:01 +00:00
git checkout ./pipo
2010-04-15 09:45:50 +00:00
</code></div>
2010-02-17 12:27:01 +00:00
Oui, bon... Voilà, voilà, voilà....
Ça marche, mais ce n'est pas très convivial. D'autant plus que le mot clé checkout signifiait sous CVS et SVN l'opération pour récupérer un projet distant.
Là où la différence se creuse c'est avec la terminologie Bazaar qui est bien plus naturelle. Car il n'y a pas de commande pour changer de branche, puisqu'il y a une branche par répertoire. Ainsi, pour changer de branche, il suffit de faire `cd path/to/branch`. Et pour revenir en arrière :
2010-04-15 09:45:50 +00:00
<div><code class="zsh">
2010-02-17 12:27:01 +00:00
bzr revert pipo
2010-04-15 09:45:50 +00:00
</code></div>
2010-02-17 12:27:01 +00:00
De plus, la plupart des commandes bazaar prennent en paramètre un numéro de révision, par exemple pour revenir 3 versions précédentes il suffit d'écrire :
2010-04-15 09:45:50 +00:00
<div><code class="zsh">
2010-02-17 12:27:01 +00:00
bzr revert -r -3 pipo
2010-04-15 09:45:50 +00:00
</code></div>
2010-02-17 12:27:01 +00:00
L'équivalent sous git est beaucoup plus cryptique :
2010-04-15 09:45:50 +00:00
<div><code class="zsh">
2010-02-17 12:27:01 +00:00
bzr checkout HEAD~3 pipo
2010-04-15 09:45:50 +00:00
</code></div>
2010-02-17 12:27:01 +00:00
Encore un fois, Bazaar est bien plus lisible.
Revenir dans le temps pour tout le projet :
avec Bazaar :
2010-04-15 09:45:50 +00:00
<div><code class="zsh">
2010-02-17 12:27:01 +00:00
bzr revert -r -3 pipo
2010-04-15 09:45:50 +00:00
</code></div>
2010-02-17 12:27:01 +00:00
et avec `git` ? `git checkout` ? Bien sûr que non voyons ! Ce serait bien trop simple. Ce que l'on trouve dans les forums c'est :
2010-04-15 09:45:50 +00:00
<div><code class="zsh">
2010-02-17 12:27:01 +00:00
git reset --hard HEAD~3
2010-04-15 09:45:50 +00:00
</code></div>
2010-02-17 12:27:01 +00:00
Sauf que cette syntaxe est horrible. Elle oublie 'réellement' les révisions. Il faut donc l'utiliser avec prudence. Mais en effet, je conseillerai plutôt :
2010-04-15 09:45:50 +00:00
<div><code class="zsh">
2010-02-17 12:27:01 +00:00
git checkout HEAD~3 -- . && git commit -m 'back in time'
2010-04-15 09:45:50 +00:00
</code></div>
2010-02-17 12:27:01 +00:00
Histoire d'avoir la branche backup sous la main, car sinon, on risque de perdre définitivement la version courante de HEAD. Qui ramène la branche locale à ce point. Mais il reste des erreur s'il y a eu des ajouts de fichier entre temps. *Le seul et l'unique vraiment propre de revenir en arrière dans git c'est de lancer la commande suivante :*
2010-04-15 09:45:50 +00:00
<div><code class="zsh">
2010-02-17 12:27:01 +00:00
for i in $(seq 0 2); do
git revert -n --no-edit head~$i;
done
git commit -m "reverted 3 versions back"
2010-04-15 09:45:50 +00:00
</code></div>
2010-02-17 12:27:01 +00:00
ce qui signifie sur un système `UNIX` en `zsh` (ou `bash`) faire `git revert` de toutes les dernières versions. Même si quelqu'un d'autre à fait un pull de vos modification intermédiaire il ne sera pas embêté et il sera au courant de ce qu'il s'est passé.
La règle est simple : *Ne JAMAIS utiliser la commande `git reset` avec une version que d'autres personnes auraient pu avoir `fetcher`.*
Voilà, c'est dit. Découvrir ça m'a pris pas mal de temps, avec plein d'essai de tous les cotés. Le plus sûr reste toujours la méthode vue plus haut. Si vous souhaitez automatiser cela, le plus simple est d'ajouter l'alias suivant à votre fichier `~/.gitconfig`. Bien sûr l'alias ne fonctionnera que sur les environnement possédant `zsh`, ce qui est le cas de la plupart des environnements UNIX (Ubuntu, Mac OS X...).
2010-04-15 09:45:50 +00:00
<div><code class="zsh" file="gitconfig">
2010-02-17 12:27:01 +00:00
[alias]
uncommit = !zsh -c '"if (($0)); then nb=$(( $0 - 1 )); else nb=0; fi; i=0; while ((i<=nb)); do git revert -n --no-edit HEAD~$i; ((i++)); done; git commit -m \"revert to $0 version(s) back\""'
2010-04-15 09:45:50 +00:00
</code></div>
2010-02-17 12:27:01 +00:00
# Ce qui fait que `git` est le meilleur DCVS jusqu'à aujourd'hui
Après avoir énoncé les cotés négatifs (et je les trouve nombreux) de git. Voici les cotés positifs qui a eux seul valent la peine de se coltiner tous les problèmes inhérent à `git`.
## Cheap branching
Vous travaillez toujours dans le même répertoire principal. Par exemple, vous pouvez travailler sur deux corrections de bug. Disons `fix1` et `fix2` nécessitant la modification respective de `file1` et `file2`. Vous pouvez travailler dans n'importe quel ordre sur vos deux fichiers dans la branche `master`. Puis, une fois votre travail fini. Aller dans la branche `fix1` pour commiter `file1`. Puis aller dans la branche `fix2` pour commiter `file2`. Et enfin, merger les deux branches dans `master`.
2010-04-15 09:45:50 +00:00
<div><code class="zsh">
2010-02-17 12:27:01 +00:00
> vim file1
> vim file2
> git br fix1
> git add file1
> git commit -m 'fix1'
> git br fix2
> git add file2
> git commit -m 'fix2'
> git commit master
> git merge fix1
> git merge fix2
2010-04-15 09:45:50 +00:00
</code></div>
2010-02-17 12:27:01 +00:00
Et il est vraiment très agréable de ne pas se soucier d'être dans la *bonne* branche. Vous n'avez à vous occuper que de votre code et seulement ensuite vous occuper du système de version.
Sous Bazaar, il m'est souvent arriver de coder dans la mauvaise branche. Pour récupérer le coup, on doit copier les modifications du fichier dans la bonne branche et faire un revert sur le fichier en question, puis aller dans la bonne branche pour commiter les modifications. Enfin, la plupart du temps, je me trompe de branche et puis tant pis, je merge les deux tout en sachant que c'est sale.
C'est pourquoi je préfère utiliser `git`. Si Bazaar venait à implémenter ce système de *cheap branching*, je le replacerai certainement en tête.
2010-04-29 14:59:14 +00:00