Mémo Git : les branches

Tel Tarzan, sautez de branche en branche, fusionnez, rebasez... bref toute la puissance de Git en action !

Illustration : les branches de GIT

Création, déplacement, suppression...

Créer une nouvelle branche :

git branch nom_nouvelle_branche [A]

Facultatif : préciser le commit [A] sur lequel pointe la branche.

Créer une branche et y basculer directement :

git checkout -b nom_nouvelle_branche

Supprimer une branche :

git branch -d branche_à_supprimer

La suppression sera refusée si la branche indiquée n'a pas été fusionnée avec la branche actuelle.
Pour forcer la suppression remplacer l'option -d par -D.
Tout le travail de la branche supprimée est alors perdu.

Afficher la liste des branches existantes :

git branch

Le * désigne la branche sur laquelle vous êtes positionné actuellement.
En ajoutant l'option -v vous obtenez des informations sur le dernier commit de chaque branche.
L'option --merged permet de voir les branches qui ont déjà fusionné avec celle actuelle, l'option --no-merged donnant le résultat inverse.
L'option -r liste les branches distantes et l'option -a, les branches locales et distantes.

Basculer vers une branche existante :

git checkout nom_branche_visée

Renommer une branche existante :

git branch -m [ancien_nom] nouveau_nom

Si ancien_nom n'est pas précisé, c'est la branche actuelle qui est renommée.
L'option -M permet de forcer le changement de nom même si nouveau_nom est déjà utilisé.

Convention de nommage des branches :

  • master : dernière version stable.
  • maint : master + backports de maintenance.
  • next : version stable de la nouvelle version en développement.
  • pu (proposed updates) : fonctionnalités de la future version nécessitant encore du travail.

Créer une branche à partir d'une remise :

git stash branch nom_de_la_nouvelle_branche

Générer un nom humainement lisible pour chaque commit d'une branche :

git describe nom_de_la_branche

-> Nécessite l'existence d'étiquettes annotées.

Afficher l'identifiant du commit sur lequel pointe une branche :

git rev-parse nom_de_la_branche

Fusionner les branches

Fusionner la branche sur laquelle vous vous situez avec une autre branche :

git merge autre_branche

En cas de conflit de fusion (mêmes sections de fichier ayant été modifiées différemment dans les deux branches fusionnées), lancez git status pour connaître les fichiers concernés, éditez-les pour régler les problèmes entourés par <<<<<<< et >>>>>>> puis indexer de nouveau ces fichiers pour signifier que le conflit a été résolu.

Pour abandonner la fusion en cours et restaurer son répertoire de travail :

git merge --abort

Pour utiliser un outil de graphique de résolution de conflit :

git mergetool

Une fois tous les conflits résolus, lancez git commit pour finaliser la fusion.

Alternative : récupérer tous les commits d'une autre branche, sans fusionner ni créer un nouveau commit :

git merge --no-commit --squash branche_à_récupérer

Se rebaser sur une branche...

Rebaser une branche directe :

git rebase branche_sur_laquelle_rebaser

Rebaser sur une branche indirecte :

git rebase --onto branche_sur_laquelle_rebaser branche_intermédiaire branche_à_rebaser

Dans les deux cas, effectuez ensuite une fusion en avance rapide sur la branche recevant le rebase :

git merge branche_sur_laquelle_on_a_rebaser

On peut alors supprimer la branche qui vient d'être rebasée :

git branch -d branche_qu_on_a_rebaser

Conseil de Scott Chacon :

Ne rebasez jamais des commits qui ont déjà été poussés sur un dépôt public.
Si vous suivez ce conseil, tout ira bien. Sinon, de nombreuses personnes vont vous haïr et vous serez méprisé par vos amis et votre famille.

Vous voilà prévenus ! :-)

Récupérer un commit donné, présent sur une autre branche :

git cherry-pick somme_de_contrôle_du_commit

Rebase interactif, pour modifier des commits plus anciens :

git rebase -i HEAD~3

-> ici les 3 commits précédent le dernier (sur lequel se trouve HEAD).
-> on peut alors modifier, supprimer, fusionner des commits ou encore changer leur ordre.
-> dans tous les cas les commits seront recalculés donc à éviter si ils sont déjà partagés sur un serveur.

Indexez vos fichiers, enregistrez les nouveaux commits et une fois fini :

git rebase --continue

Historique et comparaison des branches

Voir l'historique des commits en ignorant ceux d'une branche :

git log branche_étudiée --not branche_ignorée

Historique entre une branche et son ancêtre commun avec une autre servant de référence :

git diff branche_de_référence...branche_étudiée

Emplacement d'une branche à une période donnée (hier dans l'exemple) :

git show branche_concernée@{yesterday}

Afficher le reflog au format log :

git log -g branche_concernée

-> reflog ne stocke que des informations locales, c'est un historique de ce que vous avez fait dans votre dépôt.

Liste des commits présents dans une branche et pas dans une autre de référence :

git log branche_de_référence..branche_comparée

Comparer plusieurs branches :

git log refA refB ^refC
git log refA refB --not refC

Les deux syntaxes sont équivalentes en permettant de voir ce qui est dans refA et refB mais pas dans refC.

Voir les commits présents uniquement dans une des branches, les commits communs étant exclus :

git log branche1...branche2

-> L'option --left-right vous indiquera à quelle branche appartient chaque commit (flèche gauche / droite).

Note : cet article fait partie d'un mémo des commandes Git dont la création s'est inspirée du livre "Pro Git" de Scott Chacon, publié sous licence Creative Commons Non Commercial Share Alike 3.0. Les illustrations sont également issues de ce livre. Le mémo en lui-même (hors illustration) est publié sous Licence Art Libre. Par ailleurs, n'hésitez pas à me signaler toute erreur / ambiguïté qui se serait cachée dans cet article.