Branches
Les branches Git
A quoi servent les branches Git ?
Une branche est une version alternative de l'histoire de votre dépôt, donc de votre projet. Une branche vous permet de tester des idées sans perturber le reste de l'équipe tout en profitant du stockage sur le serveur distant, de la gestion de révision, etc.
Regardons tout d'abord un comportement sans banche:
- Toutes les modifications sont faites dans la branche par défaut,
main
oumaster
la plupart du temps - Vous pouvez créer un répertoire par module, et quand vous faites des commits, push et pull sur des fichiers présents dans des répertoires différents, il n’y a jamais de problème de conflits de fusion avec les autres binômes.
- Par contre, chaque fois que vous faites un push et qu'un autre membre du groupe en a fait un depuis votre dernier pull, votre push est refusé tant que vous n’avez pas fait un pull et ce même si ce nouveau pull n’engendre pas de conflits de fusion.
Avec une branche, vous êtes complètement indépendants des autres modules, vous développez sans être perturbés par le travail des autres.
On utilisera des branches dès que l'on veut:
- Tester de nouvelles idées
- Réorganiser une partie du code
- Effectuer des développements en parallèle limitant les risques de conflits
- Sauvegarder un travail en cours même non fonctionnel
Vous pouvez même faire une branche par personne, si vous travaillez sur des parties clairement séparées de celle de votre binôme.
Quand vous êtes prêts à partager votre travail avec d’autres, vous fusionnez votre branche avec la branche principale par exemple.
Une branche peut aussi être mise à la poubelle sans forcément avoir été fusionnée avec une autre branche, si vos tests ne vous ont mené nulle part par exemple.
Attention
Les branches sont un outil très puissant, mais qui peut vite compliquer un projet. Prenez l'habitude:
- de mettre des noms de branches clairs (indiquez les conventions de nommage dans la documentation du projet)
- de supprimer régulièrement les branches n'ayant plus d'utilité
Se servir des branches Git
Pour créer une branche, utilisez simplement
Pour basculer entre vos branches, utilisez
Tous vos commits se font dans la branche courante.
La pile de brouillon (stash) est indépendante des branches, on peut donc faire sans soucis:
Pour voir les branches de votre dépôt, utilisez:
git branch -a
pour la liste des branchesgit branch -v
pour la liste des branches ainsi que le dernier commit ouHEAD
sur chaque branche (identifiant et message)
Note
Lorsque vous faites git clone
, Git active une branche par défaut, souvent appelée main ou master.
Vous pouvez utiliser les tags Git sur les branches. Imaginons un développement important qui ne sera pas fusionné avec la branche principale pendant longtemps. Au bout de quelque temps, les commits s'accumulent et il devient délicat de se souvenir des dernières versions stables de ces développements. Les tags peuvent aider ici.
Note sur switch ou checkout
Vous verrez souvent git checkout
au lieu de git switch
pour les changements de branches. Les deux syntaxes sont possibles:
- Historiquement, seul
checkout
était défini et servait autant pour les commits que pour les branches - Depuis la version 2.23, la commande
switch
est apparue pour ne s'occuper que des branches, mais la commandecheckout
est restée la même.
Il est recommandé d'utiliser switch
afin de bien différentier les changements de branches et les déplacements dans l'historique des commits sur une branche (git checkout commit_id
).
Partager des branches sur le dépôt distant
Pour partager un travail qui se trouve dans une branche Git vers le dépôt distant, il va falloir indiquer à Git vers quel dépôt distant et sous quel nom cette branche doit être poussée.
Nous verrons plus loin les dépôts multiples, pour le moment il est fort probable que son nom soit origin
.
Pour le nom, la pratique habituelle veut qu'on utilise le nom donné à la branche locale, mais ce n'est pas obligatoire.
Ceci n'est à faire que la première fois que la branche est poussée vers le dépôt distant.
Historique des branches
Nous avons déjà parlé de git log
, qui affiche l'historique des commits sur la branche courante.
Vous pouvez aussi voir l'historique sur toutes les branches:
Il peut aussi être utile de voir les différences entre votre branche et la dernière version d'une autre branche (ici main
)):
Fusionner des branches
Une fois votre travail sur une branche terminé, vous voudrez l'intégrer dans la branche principale de votre projet.
Cette fusion est la plus rapide à faire et est recommandée pour les débutants.
-
Placez-vous dans la branche de destination (branche principale par exemple)
-
Intégrez les changements de votre branche
mabranche
-
Résoudre les conflits éventuels comme vu précédemment
Info
Il existe d'autres méthodes pour fusionner les branches (en particulier via rebase) qui ne sont pas traitées ici
Supprimer des branches
Lorsqu'une branche est fusionnée, elle n'est souvent plus utile et peut donc être supprimée. De même, si vous avez créé une branche pour tester des idées mais sans succès, faites le ménage.
Pour supprimer la branche locale:
Pour supprimer la branche locale même si elle contient des modifications non validées:
Si la branche est aussi présente sur le dépôt distant, vous pouvez aussi la supprimer si vous pensez que personne d'autre ne travaille dessus. Pour supprimer la branche du dépôt nommé origin
:
Fusion de branches avancée avec Gitlab/Github
Les serveurs Gitlab/Github proposent des outils supplémentaires pour la gestion des branches, via la possibilité de faire des demandes de fusion de code (MergeRequest pour Gitlab, PullRequest pour Github) qui simplifient beaucoup le travail des administrateurs qui peuvent alors:
- commenter et discuter du bien-fondé des modifications proposées
- demander des changements pour respecter les consignes de développement du projet
- valider que les changements ne cassent pas le code existant
- faire la fusion.
Dans votre projet
Lorsque vous avez fini un travail sur une branche donnée:
- envoyez vos modifications sur le serveur
- allez dans l'interface de gestion des branches sur le serveur
- cliquez sur le bouton
nouveau
pour GitLab puis Merge Request...
pour Github puis Pull Request
- puis sélectionner la branche dans laquelle vous voulez fusionner
Ceci créera automatiquement une demande de fusion de la branche vers la branche cible.
Dans des projets tierces
Même dans les projets logiciels à code source ouvert, peu de contributeurs ont la possibilité de modifier le code d'origine pour des raisons de sécurité.
Note
Historiquement, les contributeurs sans droits d'écriture envoyaient des fichiers de différence (voir les utilitaires diff
et patch
) aux administrateurs, qui décidaient quoi en faire. Il est assez simple de comprendre que ceci n'est pas très flexible et rend le suivi des contributeurs assez compliqué.
Il est là encore possible d'utiliser les outils de Gitlab/Github pour gérer les requêtes de fusion.
Le principe est le suivant:
- vous disposez de votre copie du dépôt d'origine, et cette copie est elle aussi hébergée sur un serveur de même type Gitlab/Github
- on parlera de fork, et ces serveurs ont souvent un bouton de ce nom dans l'interface graphique du projet principal
- vous poussez vos modifications sur votre copie distante (fork), pour laquelle vous avez les droits d'écriture
- le serveur web (pour votre fork) vous proposera alors de créer une MergeRequest / PullRequest, qui sera transférée vers le dépôt d'origine.
Il est cependant très fastidieux (et inutile) d'avoir en local plusieurs copies du dépôt principal. Git nous aide ici en pouvant gérer plusieurs dépôts distants différents dans votre dépôt local.
La marche à suivre est donc:
- clone en local du projet principal, par ex
git clone git@github.com:TPUEO/test.git
- fork du projet initial sur votre compte GitHub/Gitlab, par exemple sur
git@gitlab.enst.fr/monlogin/projets/teama
- ajout dans votre dépôt local d'un dépôt distant:
git remote add forkperso git@gitlab.enst.fr/monlogin/projets/teama
- créez une nouvelle branche :
git switch monfix
- pendant le travail
- récupérer les modifications sur le dépôt d'origine branche
main
directement dans la branche courantegit pull origin main
- ajoutez vos modifications et validez comme d'habitude
- récupérer les modifications sur le dépôt d'origine branche
- au premier push de cette branche, indiquez votre serveur comme serveur distant:
git push --set-upstream forkperso monfix
Une bonne pratique est de créer des branches pour vos futures demandes de merge/pull.
Dépôts multiples et branches
Lorsque vous avez configuré des dépôts distants multiples, certaines branches existent sous le même nom dans ces dépôts et peuvent ne plus être les mêmes.
Pour identifier ces branches, Git utilise le nom du serveur distant associé, tel que renseigné lors de git remote add
.
Par exemple dans l'exemple précédent:
git switch origin/main
indiquera de basculer sur la branchemain
du dépôt d'originegit switch forkperso/main
indiquera de basculer sur la branchemain
de votre fork
Pour consulter l'ensemble des branches disponibles à distance et en local, tapes bit branch -a
. Vous verrez:
- les branches locales
- les branches du serveur d'origine (premier clone) sous la forme
remotes/origin/BRANCHE
- les branches des serveurs additionnels sous la forme
remotes/forkperso/BRANCHE