Branches Git : intuition et réalité
(jvns.ca)- Beaucoup de gens estiment que la manière dont fonctionnent les branches Git n’est pas intuitive
- L’article explique l’écart entre le modèle intuitif courant des branches Git et la façon dont les branches sont réellement représentées en interne dans Git
- Il montre que le modèle intuitif et le fonctionnement réel de Git sont en fait très étroitement liés
- Il discute des limites du modèle intuitif et des raisons pour lesquelles il peut poser problème
Modèle intuitif des branches
- Beaucoup de gens comparent les branches à « des branches d’un pommier ».
- Dans Git, une branche n’a pas de notion de « parent », ce qui diffère de l’idée qu’elle serait dérivée de
main.
Dans Git, une branche correspond à tout l’historique
- Dans Git, une branche n’est pas simplement un commit séparé : elle inclut tout l’historique de tous les commits précédents.
- À travers un dépôt d’exemple, l’article montre que
mainetmybranchont tous deux 4 commits.
Les branches sont stockées sous forme d’ID de commit
- En interne, dans Git, une branche est stockée sous la forme d’un petit fichier texte contenant un ID de commit.
- Le commit le plus récent de chaque branche est enregistré dans ce fichier.
- Comme il n’existe pas de relation parent-enfant entre les branches, Git ne connaît pas les relations entre elles.
L’intuition des gens n’est généralement pas si fausse
- Dire que l’intuition des gens sur Git est « fausse » est quelque peu absurde.
- Même un modèle « faux » peut en pratique être utile.
Rebase utilise lui aussi la notion « intuitive » de branche
- Le rebase ne réapplique sur
mainque les commits de la branche « intuitive ». - Le résultat du rebase correspond au modèle intuitif.
Merge utilise lui aussi la notion « intuitive » de branche
- Le merge ne copie pas les commits, mais il a besoin d’un commit de base partagé.
- La merge base permet de retrouver le commit à partir duquel les branches du modèle intuitif ont divergé.
Les pull requests GitHub utilisent aussi cette idée intuitive
- Quand on crée sur GitHub une pull request pour fusionner
mybranchdansmain, seuls les commits de la branche intuitive sont affichés.
L’intuition est utile, mais elle a ses limites
- La définition intuitive d’une branche correspond bien au travail réel avec Git, mais Git ne perçoit pas différemment une branche issue de
main.
Tronc et branches dérivées
- Les gens perçoivent
mainetmybranchdifféremment, et cela influence leur manière d’utiliser Git. - Git ne fait pas la différence entre une branche qui serait une « dérivation » d’une autre et n’importe quelle autre branche.
Git peut faire un rebase « à l’envers »
- Comme Git ne sait pas si une branche est une « dérivation » d’une autre, c’est à l’utilisateur de savoir quelle branche doit être rebasée et à quel moment.
git rebase mainet le rebase inversegit rebase mybranchsont tous deux possibles. Même chose pour le merge
L’absence de hiérarchie entre les branches Git est un peu étrange
- Dire que la branche
mainn’a rien de spécial vient du fait que Git ne reconnaît pas les relations entre les branches. - Il existe bien des relations entre les branches, mais Git n’en sait rien
L’interface des branches Git est elle aussi étrange
- Si l’on veut ne voir que les commits « dérivés », la manière d’utiliser
git logetgit diffest différente.
Sur GitHub, la branche par défaut est spéciale
- GitHub possède une « branche par défaut », qui joue un rôle particulier.
L’avis de GN⁺
L’idée la plus importante de cet article est de comprendre la différence entre l’intuition qu’ont les gens des branches Git et le fonctionnement réel de Git. Cet article aidera les ingénieurs logiciel débutants à mieux comprendre le concept de branche Git et à l’utiliser plus efficacement. Comprendre comment le modèle intuitif des branches Git correspond au travail réel, et comment Git ne gère pas les relations entre branches, est à la fois intéressant et instructif.
1 commentaires
Avis Hacker News
git reset --hardetgit stash. Pour annuler une mauvaise fusion, j’utilisegit reset --hard <dernier commit avant la fusion>, et pour appliquer sur la branche principale de petites modifications d’une branche locale, j’utilisegit stash, puis je bascule sur la branche principale pour fairegit stash apply.git addetgit commit. Il aide à visualiser les branches pendant la lecture.git merge my-branchfusionnemy-branchdans la branche courante, etgit rebase my-branchrebase la branche courante surmy-branch.HEAD) ait une « queue » pointant vers le commit de base où cette branche a commencé. Comme les branches sont souvent rebasées, il arrive qu’on doive réfléchir à leur point de départ. Ce serait plus pratique si Git indiquait que le commit de base appartient àmain.git range-diff. Cet outil compare deux plages commemain..previousetmain..current.