Skip to content

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 ou masterla 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

git switch -c mabranche

Pour basculer entre vos branches, utilisez

git switch mabranche

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:

git stash
git pull
git switch other_branch
git stash pop

Pour voir les branches de votre dépôt, utilisez:

  • git branch -a pour la liste des branches
  • git branch -v pour la liste des branches ainsi que le dernier commit ou HEAD 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 commande checkout 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.

git switch -c new_feature
git push --set-upstream origin new_feature

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:

git log --all

Il peut aussi être utile de voir les différences entre votre branche et la dernière version d'une autre branche (ici main)):

git diff main
# ou par fichier
git diff main FICHIER

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)

    git switch main
    

  • Intégrez les changements de votre branche mabranche

    git merge 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:

git branch -d mabranche

Pour supprimer la branche locale même si elle contient des modifications non validées:

git branch -D mabranche

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:

git push -d origin mabranche

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 courante git pull origin main
    • ajoutez vos modifications et validez comme d'habitude
  • 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 branche main du dépôt d'origine
  • git switch forkperso/main indiquera de basculer sur la branche main 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