GitVoici 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 :

Dépôt Git

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

AstuceVous 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(-)

AstuceLes 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 :

Git

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

AstuceQuestion 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 :

Git

À 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 :

Git

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 :

Git

ImportantUne 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 :

Git

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 fichier README initial.
  • Clonez ce dépôt.
  • Copiez les fichiers Cartes.md, Entretien.md et Roadtrip.md depuis le répertoire atelier-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 et roadtrip.
  • 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 et roadtrip.
  • 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.

 

Catégories : Formation

1 commentaire

anonyme · 4 mars 2023 à 16 h 55 min

Excellente série, merci beaucoup!

Laisser un commentaire

Emplacement de l’avatar

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *