Voici le vingt-troisième volet de la formation Git. Dans mon précédent article, nous avons évoqué quelques précautions à prendre lorsqu’il s’agit de synchroniser son dépôt local avec un dépôt publiquement accessible. Aujourd’hui nous allons continuer dans cette lancée et parler de la gestion des branches avec un dépôt public.
En temps normal, voici – à peu de choses près – le workflow que vous utiliserez au quotidien avec Git :
- Vous avez une idée pour une nouvelle fonctionnalité.
- Vous créez une nouvelle branche dédiée à cette fonctionnalité.
- Vous basculez sur cette branche.
- Vous développez votre fonctionnalité.
- Vous revenez sur la branche d’intégration.
- Vous intégrez votre travail à la branche d’intégration.
- Vous supprimez la branche sur laquelle vous venez de travailler.
- Etc.
Avec un dépôt public, la gestion des branches et leur fusion peuvent être gérées de plusieurs façons. Aujourd’hui nous allons nous concentrer sur une première manière de faire, qui ne changera absolument rien à vos habitudes. Suivez le guide.
Publier la fusion de deux branches
Pour commencer, créez un répertoire ~/formation-git/atelier-33
pour les fichiers de notre atelier pratique :
$ cd ~/formation-git/ $ mkdir atelier-33 $ cd atelier-33
Allez sur GitHub et créez un dépôt privé hello
avec un fichier README
initial :
Clonez ce dépôt :
$ git clone git@github.com:kikinovak/hello.git Cloning into 'hello'... remote: Enumerating objects: 3, done. remote: Counting objects: 100% (3/3), done. Receiving objects: 100% (3/3), done. remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 $ ls hello $ cd hello/ $ ls README.md
Pour nous éviter du travail de recopiage, nous allons nous servir des fichiers hello.sh
, hello-cow.sh
et hello-figlet.sh
du répertoire atelier-13
. Copiez ces fichiers dans votre répertoire de travail :
$ cp -v ../../atelier-13/hello*.sh . '../../atelier-13/hello-cow.sh' -> './hello-cow.sh' '../../atelier-13/hello-figlet.sh' -> './hello-figlet.sh' '../../atelier-13/hello.sh' -> './hello.sh'
Créez trois branches hello
, hello-cow
et hello-figlet
:
$ git branch hello
$ git branch hello-cow
$ git branch hello-figlet
$ git branch
hello
hello-cow
hello-figlet
* main
Vous aurez sans doute remarqué que la branche d’intégration de notre dépôt s’appelle main
et non pas master
. Ici, c’est GitHub qui a décidé de donner un nom plus politiquement correct à ses branches créées par défaut.
Ajoutez le script hello.sh
à la branche hello
:
$ git switch hello Switched to branch 'hello' $ git add hello.sh $ git commit -m "Ajout du script hello.sh" [hello 2730bcc] Ajout du script hello.sh 1 file changed, 9 insertions(+) create mode 100755 hello.sh
Ajoutez le script hello-cow.sh
à la branche hello-cow
:
$ git switch hello-cow Switched to branch 'hello-cow' $ git add hello-cow.sh $ git commit -m "Ajout du script hello-cow.sh" [hello-cow e55dd24] Ajout du script hello-cow.sh 1 file changed, 10 insertions(+) create mode 100755 hello-cow.sh
De même, ajoutez le script hello-figlet.sh
à la branche hello-figlet
:
$ git switch hello-figlet Switched to branch 'hello-figlet' $ git add hello-figlet.sh $ git commit -m "Ajout du script hello-figlet.sh" [hello-figlet b58a344] Ajout du script hello-figlet.sh 1 file changed, 10 insertions(+) create mode 100755 hello-figlet.sh
Revenez dans la branche main
et éditez le fichier README.md
. Peu importe le détail de cette opération, du moment que vous le modifiez un peu :
$ git switch main Switched to branch 'main' Your branch is up to date with 'origin/main'. $ vim README.md $ git add README.md $ git commit -m "Peaufinage du fichier README." [main 83765a0] Peaufinage du fichier README. 1 file changed, 2 insertions(+), 1 deletion(-)
Les plus perspicaces parmi vous auront peut-être subodoré la visée pédagogique de cette dernière opération. Il s’agit de nous compliquer la vie un tout petit peu et de faire en sorte que la fusion de nos branches consistera en un merge commit au lieu d’un simple fast-forward merge.
Rappelez-vous que la commande git push
sert à « pousser » les modifications de notre branche d’intégration (en l’occurence main
) vers la branche correspondante origin/main
de notre dépôt public. Voyons un peu où nous en sommes pour l’instant :
$ git status On branch main Your branch is ahead of 'origin/main' by 1 commit. (use "git push" to publish your local commits) nothing to commit, working tree clean
Git nous informe ici que notre branche main
locale a une longueur d’avance par rapport au dépôt public (origin/main
). Commençons par mettre les deux à la même enseigne :
$ git push Enumerating objects: 5, done. Counting objects: 100% (5/5), done. Writing objects: 100% (3/3), 302 bytes | 302.00 KiB/s, done. Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 To github.com:kikinovak/hello.git ee84a90..83765a0 main -> main
Si nous jetons un œil à l’historique du dépôt public, nous verrons uniquement le commit initial et celui où nous avons modifié le fichier README.md
. En revanche, aucune trace des autres commits dans les trois autres branches :
Je retourne dans ma console et j’intègre la première de mes trois branches dans ma branche d’intégration :
$ git branch
hello
hello-cow
hello-figlet
* main
$ git merge hello
Merge made by the 'recursive' strategy.
hello.sh | 9 +++++++++
1 file changed, 9 insertions(+)
create mode 100755 hello.sh
Voyons où en sont les choses :
$ git status On branch main Your branch is ahead of 'origin/main' by 2 commits. (use "git push" to publish your local commits) nothing to commit, working tree clean
Question pour un champion : pourquoi Git me dit-il que je suis en avance de deux commits par rapport au dépôt public ? Pouvez-vous identifier les deux commits en question ?
Je publie le résultat de cette fusion :
$ git push Enumerating objects: 7, done. Counting objects: 100% (7/7), done. Delta compression using up to 8 threads Compressing objects: 100% (5/5), done. Writing objects: 100% (5/5), 622 bytes | 622.00 KiB/s, done. Total 5 (delta 0), reused 0 (delta 0), pack-reused 0 To github.com:kikinovak/hello.git 83765a0..47c6c19 main -> main
Et je jette un œil à l’historique de mon dépôt public, où je retrouve la réponse à la question que je viens de me poser :
À présent, j’intègre la branche hello-cow
:
$ git merge hello-cow Merge made by the 'recursive' strategy. hello-cow.sh | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100755 hello-cow.sh $ git status On branch main Your branch is ahead of 'origin/main' by 2 commits. (use "git push" to publish your local commits) nothing to commit, working tree clean $ git push Enumerating objects: 7, done. Counting objects: 100% (7/7), done. Delta compression using up to 8 threads Compressing objects: 100% (5/5), done. Writing objects: 100% (5/5), 701 bytes | 701.00 KiB/s, done. Total 5 (delta 0), reused 0 (delta 0), pack-reused 0 To github.com:kikinovak/hello.git 47c6c19..aedc2ad main -> main
Je vérifie si mes commits fusionnés apparaissent bien dans l’historique de mon dépôt public :
Et il ne me reste plus qu’à intégrer ma branche hello-figlet
:
$ git merge hello-figlet Merge made by the 'recursive' strategy. hello-figlet.sh | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100755 hello-figlet.sh $ git status On branch main Your branch is ahead of 'origin/main' by 2 commits. (use "git push" to publish your local commits) nothing to commit, working tree clean $ git push Enumerating objects: 7, done. Counting objects: 100% (7/7), done. Delta compression using up to 8 threads Compressing objects: 100% (5/5), done. Writing objects: 100% (5/5), 669 bytes | 669.00 KiB/s, done. Total 5 (delta 1), reused 0 (delta 0), pack-reused 0 remote: Resolving deltas: 100% (1/1), completed with 1 local object. To github.com:kikinovak/hello.git aedc2ad..beb2603 main -> main
Un coup d’œil sur l’historique du dépôt public :
Une précision importante ici : le dépôt public ne sait rien des branches hello
, hello-cow
et hello-figlet
. N’oubliez pas que lorsque vous effectuez un git push
, vous publiez uniquement ce qui se trouve sur la branche d’intégration, en l’occurrence main
.
En effet, le menu déroulant dans l’interface web de GitHub ne nous affiche qu’une branche unique main
, avec un historique linéaire :
En contrepartie, notre historique local est plus complexe :
$ git log --oneline --graph --all * beb2603 (HEAD -> main, origin/main, origin/HEAD) Merge branch 'hello-figlet'. |\ | * b58a344 (hello-figlet) Ajout du script hello-figlet.sh * | aedc2ad Merge branch 'hello-cow'. |\ \ | * | e55dd24 (hello-cow) Ajout du script hello-cow.sh | |/ * | 47c6c19 Merge branch 'hello'. |\ \ | * | 2730bcc (hello) Ajout du script hello.sh | |/ * / 83765a0 Peaufinage du fichier README. |/ * ee84a90 Initial commit
Il ne nous reste plus qu’à faire un brin de ménage dans nos branches locales, qui ne nous servent plus à rien :
$ git branch --delete hello Deleted branch hello (was 2730bcc). $ git branch --delete hello-cow Deleted branch hello-cow (was e55dd24). $ git branch --delete hello-figlet Deleted branch hello-figlet (was b58a344).
Cette manière de travailler avec des branches locales que l’on fusionne avant de passer à la publication convient très bien si vous développez tout seul votre projet. En revanche, si vous travaillez à plusieurs, il existe une autre méthode de fusionner les branches avec un workflow très différent. Elle fera l’objet de notre prochain article.
Exercice
- Créez un répertoire
~/formation-git/atelier-34
. - Connectez-vous à GitLab.
- Créez un dépôt privé
roadtrip
doté d’un fichierREADME
initial. - Clonez ce dépôt.
- Copiez les fichiers
Cartes.md
,Entretien.md
etRoadtrip.md
depuis le répertoireatelier-19
. - Laissez les fichiers dans le répertoire de travail sans les ajouter à l’index pour l’instant.
- Créez trois branches respectives
cartes
,entretien
etroadtrip
. - Ajoutez les trois fichiers aux trois branches respectives avec un message qui va bien.
- Revenez dans la branche d’intégration.
- Modifiez votre fichier
README
. - Publiez cette dernière modification.
- Vérifiez l’historique du dépôt public dans l’interface de GitLab.
- Intégrez la branche
cartes
à la branche d’intégration. - Publiez cette dernière modification.
- Vérifiez l’historique du dépôt public dans l’interface de GitLab.
- Procédez de même avec les branches
entretien
etroadtrip
. - Affichez votre historique local complet.
- Supprimez les branches dont vous n’avez plus besoin.
Lire la suite : Le pull request
La rédaction de cette documentation demande du temps et des quantités significatives de café espresso. Vous appréciez ce blog ? Offrez un café au rédacteur en cliquant sur la tasse.
1 commentaire
anonyme · 4 mars 2023 à 16 h 55 min
Excellente série, merci beaucoup!