Les branches
Globalement, créer une branche, c’est créer une nouvelle trajectoire, isolée de la branche principale. Les branches peuvent être utilisées pour
- Paralléliser le développement de plusieurs fonctionnalités (et éviter que le développement de l’une n’interfère sur l’autre),
- Démarrer un développement exploratoire, dont l’issue est incertaine,
- Ou corriger un bug,
- Organiser le travail d’équipes de développement.
Les branches constituent l’une des fonctionnalités les plus importantes de GIT. Nous avons 5 principales opérations sur les branches
- Liste des branches existantes,
- Création d’une nouvelle branche,
- Changement de la branche active,
- Fusion de deux branches,
- Suppression d’une branche.
Liste des branches existantes
$ git branch
branche-1
branche-2
* branche-3
main
La branche « active » est celle sur laquelle pointe HEAD
, autrement dit, c’est la branche dans laquelle s’effectuera le prochain commit. Elle est indiquée par la couleur verte, et par le préfixe *
..
Création d’une branche
La syntaxe est simple :
$ git branch <nom de la nouvelle branche>
L’outil alerte si le nom de la branche existe déjà.
La commande
git branch <branche>
créé une branche, mais ne la rend pas active.
Dans la figure 2, nous avons bien une branche qui vient d’être créée, mais le pointeur HEAD
pointe toujours sur le dernier commit de la branche principale.
La création d’une branche se fait à partir de la branche sur laquelle nous nous trouvons. Dans la figure 1, la branche
branche3
n’est pas issue demain
, mais bien debranche2
.
Changement de la branche active
La commande checkout
La syntaxe est la suivante : git checkout <nom de la branche>
. Exemple :
$ git branch
* main
branche1
$ git checkout branche1
Switched to branch 'branche1'
$ git branch
main
* branche1
Nous retrouvons donc la fameuse commande checkout
, cette fois, avec une troisième syntaxe. Au passage, cela permet de revenir à la définition d’une branche : une branche selon GIT est une étiquette qui pointe vers un commit. Voilà pourquoi nous retrouvons cette commande checkout qui permet de déplacer le pointeur HEAD
, d’un commit vers un autre.Il est possible de changer de branche, tout en la créant :
$ git checkout -b <nouvelle branche> # Création de la branche et checkout.
Les effets de la commande
Comme indiqué dans la figure 3, la commande checkout, dans ce cas, n’affecte pas le répertoire de travail, ni l’index (staging area). Si vous avez des modifications en cours, la commande le rappellera (ici file2.txt
).
$ git status # Nous sommes dans la branche main, et le fichier file2.txt est modifié (suivi, non-indexé)
On branch main
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: file2.txt
$ git checkout branche1 # Changement de branche, la commande nous signale l'existence de la modification
Switched to branch 'branche1'
M file2.txt
$ git status # Le status montre que même après le changement de branche, la modification est toujours là
On branch branche1
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: file2.txt
Il y a une petite nuance à apporter sur ce qui vient d’être dit : la commande a un effet sur l’arborescence que vous manipulez. Si vous êtes dans une branche dans laquelle vous avez créé plusieurs répertoires, et fichiers (que vous les ayez commités ou pas), ces fichiers et répertoires disparaîtront de votre arborescence de travail, lors du checkout vers une autre branche. Ils réapparaîtront lorsque vous reviendrez sur cette branche.
Donc
- Si vous êtes dans une branche A, et que vous modifiez un fichier dans un sous-répertoire qui n’existe pas dans une branche B
- Si vous passez à la branche B, le répertoire disparaîtra, et votre modification avec.
Heureusement, la commande le signale :
$ git status
On branch feature # Nous sommes dans la branche feature
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: folder1/file5.txt # Le fichier file5.txt est modifié (il se trouve dans le répertoire folder1)
no changes added to commit (use "git add" and/or "git commit -a")
$ git checkout master # Nous tentons de passer de la branche feature a la branche master.
error: Your local changes to the following files would be overwritten by checkout:
folder1/file5.txt
Please commit your changes or stash them before you switch branches.
Aborting
La commande stash
Dans le cas que nous venons de décrire, nous souhaitons changer de branche, mais les modifications en cours nous en empêchent. Il nous faut valider (commit) ces modifications pour être autoriser à changer de branche. Mais que faire si nous ne sommes pas prêts ?
GIT nous offre une solution pour ce genre de cas : la commande git stash
. Cette commande permet de stocker temporairement nos modifications en cours (dans le répertoire de travail), et de les réappliquer ultérieurement.
Reprenons l’exemple précédent : nous ne pouvons pas quitter la branche feature
.
$ git status
On branch feature
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: folder1/file5.txt
no changes added to commit (use "git add" and/or "git commit -a")
$ git stash
Saved working directory and index state WIP on feature: a1396b0 folder
$ git status
On branch feature
nothing to commit, working tree clean
$ git checkout master
Switched to branch 'master'
$ git status
On branch master
nothing to commit, working tree clean
Une fois effectuer les changements dans la branche master
, nous pouvons revenir à la branche feature
, et réappliquer les modifications initiales :
$ git checkout feature # On retourne dans la branche feature
On branch feature
nothing to commit, working tree clean
$ git stash pop # On récupère les modifications sauvegardées précédemment
On branch feature
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: folder1/file5.txt
no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (f68ba3df2993fed0389e44b37bb33fe8ced794ec)
La commande git stash pop
applique les modifications sauvegardées dans notre espace de travail, puis supprime « la sauvegarde ».
Il est possible d’appliquer les modifications, et les conserver pour les réappliquer ultérieurement, avec la commande git stash apply
.
Par défaut, la commande git stash
s’applique aux changements
- De la zone staging (index),
- Sur les fichiers suivis, modifiés, mais non indexés (tracked) du répertoire de travail
La commande ne s’applique ni sur les fichiers non-suivis, ni sur les fichiers ignorés, à moins d’utiliser les paramètres -u
, et -a
:
- L’option
-u
(ou--include-untracked
) inclut les fichiers non-suivis, - L’option
-a
(ou--all
) inclut tous les fichiers, y compris les fichiers ignorés.
Gérer plusieurs stashes
Exécuter git stash
à plusieurs reprises, va créer plusieurs stashes. Ces éléments sont stockés sous la forme d’une pile LIFO (Last In, First Out).
Commande | Description |
---|---|
git stash list | Afficher la liste des stashes |
git stash pop | Récupère les modifications correspondant au dernier stash |
git stash save "<message>" | Sauvegarde les modifications, en annotant le stash |
$ git stash pop stash@{<numéro>} | Récupère les modifications du stash correspondant à <numéro> |
$ git stash show [-p] | Affiche le résumé d’un stash (les modifications). -p donnera tous les détails |
git stash list | Afficher la liste des stashes |
git stash clear | Supprime l’ensemble de la pile de stashes |
git slash drop <identifiant> | Supprime le stash désigné par l’identifiant |
git stash branch add-stylesheet <identifiant> | Créer une branche à partir des modifications du stash désigné par l’identifiant |
Les lignes suivantes mettent en pratique les commandes que nous venons de lister :
# Vérification de la situation. Nous avons 1 fichier modifié, mais non indexé
$ git status
On branch feature
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: folder1/file5.txt
no changes added to commit (use "git add" and/or "git commit -a")
# Sauvegarde des modifications en cours (dont notre fichier file5.txt)
$ git stash
Saved working directory and index state WIP on feature: a1396b0 folder
# Nous avons bien cette sauvegarde
$ git stash list
stash@{0}: WIP on feature: a1396b0 folder
# Création d'un fichier file6.txt
$ echo a > file6.txt
# La commande status nous montre bien le file6.txt, non-suivi
$ git status
On branch feature
Untracked files:
(use "git add <file>..." to include in what will be committed)
file6.txt
nothing added to commit but untracked files present (use "git add" to track)
# Sauvegarde de nore répertoire de travail, et de la zone d'index.
$ git stash -u
Saved working directory and index state WIP on feature: a1396b0 folder
# Nous avons bien deux sauvegardes
$ git stash list
stash@{0}: WIP on feature: a1396b0 folder
stash@{1}: WIP on feature: a1396b0 folder
# Creation et indexation du fichier file7.txt
$ echo y > file7.txt
$ git add file7.txt
# Le fichier est dans la zone d'indexation (prêt pour le commit)
$ git status
On branch feature
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
new file: file7.txt
# Nous sauvegardons cette modification, en lui donnant une description
$ git stash save "Add y in the file7.txt"
Saved working directory and index state On feature: Add y in the file7.txt
# Nous voyons bien la description dans la liste des sauvegardes
$ git slash list
stash@{0}: On feature: Add x in the file7.txt
stash@{1}: WIP on feature: a1396b0 folder
stash@{2}: WIP on feature: a1396b0 folder
# Nous souhaitons récupérer le fichier file6.txt
$ git stash drop stash@{1}
Dropped stash@{1} (2ebf490ba5238004467ecd098d9ac3c81c933ef5)
# Le fichier 6 est récupéré, il ne nous reste que deux sauvegardes
$ git stash list
stash@{0}: On feature: Add x in the file7.txt
stash@{1}: WIP on feature: a1396b0 folder
# Nous utilisons la sauvegarde 1 pour créer une branche
$ git stash branch new-feature stash@{1}
Switched to a new branch 'new-feature'
On branch new-feature
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: folder1/file5.txt
no changes added to commit (use "git add" and/or "git commit -a")
Dropped stash@{1} (5bb6b01e19430308af478b2a983f3486498d9ef2)
Fusion de deux branches avec la commande merge
A un moment donné, si nous sommes satisfaits de nos modifications, nous pouvons les intégrer à la branche principale. On parle de fusion de branches (merge). Lors d’une fusion, GIT va intégrer toutes les modifications contenues sur chaque branche dans une seule et même arborescence.
Le processus de fusion habituel est
- On se place d’abord sur la branche qui va recevoir toutes les modifications,
- On effectue la fusion
- A partir de ce moment, toutes les modifications de la branche
feature
sont intégrées à la branchemain
.
Dans ce cas, l’opération de fusion créé un nouveau commit, qui a deux parents. Il ne remplace pas le commit courant.
Une fusion correspond à l’intégration de toutes les modifications effectuées sur les deux branches que nous souhaitons fusionner. GIT est capable d’identifier les modifications dans les différents fichiers, et de les agréger. Dans certains cas, cependant, GIT ne peut pas gérer les “conflits”, qu’il faut alors résoudre manuellement.
Pour cela GIT interrompt le processus de fusion, et ajoute des marqueurs dans les fichiers à fusionner. Nous devons éditer les fichiers manuellement afin de résoudre ces conflits.
Ce travail manuel est assez rébarbatif lorsqu’il est fait avec l’outil GIT en ligne de commande. Il vaut mieux effectuer ce genre d’opération, soit avec un outil embarqué dans votre environnement de développement, soit depuis un serveur git centralisé comme Github.La commande git merge --abort
ne peut être exécutée qu’après un git merge
conduisant à de conflits non résolus automatiquement. Cette commande tentera alors d’annuler l’opération de fusion, et de revenir à la situation initiale. Cette tentative peut conduire éventuellement à la perte de vos modifications en cours.
Exécuter
git merge
en ayant des modifications non commitées est fortement déconseillé
Résumé
La figure 7 donne un exemple d’utilisation de deux branches simultanément.L’important est de bien identifier où l’on se trouve lorsque l’on effectue des modifications.
- Création de la branche
- Comme nous n’avons pas changé de branche, les modifications sont toujours effectuées dans la branche
main
- Pour développer dans la branche
feature
nous devons explicitement le demander - La branche active étant maintenant
feature
, toutes les modifications seront “enregistrées” dans cette branche - Mais rien ne nous empêche de revenir à la branche
main
, - Et y enregistrer des modifications
Commentaire : Il ne s’agit que d’un exemple
- En pratique, il est déconseillé de développer directement dans la branche
main
. On développe dans des branches, que l’on fusionne avec la branchemain
à chaque fin de cycle de développement, - Et il est bien sur conseillé d’avoir des sessions de travail par branche. Si vous devez changer de branche régulièrement, vous ferez, immanquablement une erreur à un moment donné.
Retour sur l’état de « tête détachée »
Dans le chapitre précédent, nous avons parlé de l’état de tête détachée (detached head). Nous allons revenir sur cet état, et nous allons en profiter pour mieux comprendre l’utilisation des commandes log
, et reflog
.
Situation de départ, nous n’avons qu’une seule branche main
. Dans cette branche, nous avons deux commits :
$ git log
commit 8169912adcfe5612389e69501f4192db09a85c25 (HEAD -> main)
Author: Emmanuel
Date: Tue Apr 20 21:42:23 2021 +0200
Second commit
commit 1b975d5493080c428fa8421aab72eb52e994cd9f
Author: Emmanuel
Date: Tue Apr 20 21:41:23 2021 +0200
Initial release
Maintenant, créons la situation de tête détachée, en faisant pointer HEAD
$ git checkout 1b975d5
Note: switching to '1b975d5'.
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by switching back to a branch.
If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -c with the switch command. Example:
git switch -c <new-branch-name>
Or undo this operation with:
git switch -
Turn off this advice by setting config variable advice.detachedHead to false
HEAD is now at 1b975d5 Initial release
La commande nous signale la situation de façon claire.
Continuons nos modifications sur le fichier :
$ echo c > file1.txt
$ git status
HEAD detached at 1b975d5
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: file1.txt
no changes added to commit (use "git add" and/or "git commit -a")
Nous effectuons un commit
$ git commit -m -a "3rd commit"
[detached HEAD e5245ff] 3rd commit
1 file changed, 1 insertion(+), 1 deletion(-)
Effectuons une nouvelle modification pour obtenir le commit 89cd6ad.
Si nous regardons la liste des commits avec la commande git log
:
$ git log
commit 89cd6ad35b505a42df8b98b3d29ef6f939df6c13 (HEAD)
Author: Emmanuel
Date: Tue Apr 20 22:01:33 2021 +0200
4th commit
commit e5245ffea64186bdc958c0253fc95f664e3977d2
Author: Emmanuel
Date: Tue Apr 20 21:48:18 2021 +0200
3rd commit
commit 1b975d5493080c428fa8421aab72eb52e994cd9f
Author: Emmanuel
Date: Tue Apr 20 21:41:23 2021 +0200
Initial release
Ici, nous ne voyons plus le second commit. Pour voir l’ensemble des commits, il faut utiliser la commande git reflog
$ git reflog
89cd6ad (HEAD) HEAD@{0}: commit: 4th commit
e5245ff HEAD@{1}: commit: 3rd commit
1b975d5 HEAD@{2}: checkout: moving from main to 1b975d5
8169912 (main) HEAD@{3}: commit: Second commit
1b975d5 HEAD@{4}: commit (initial): Initial release
Au passage, notons la différence entre les commandes git log
, et git reflog
:
git log
liste les commits relatifs à la branche en cours (donc il remonte l’historique en partant du pointeurHEAD
),git reflog
nous donne l’historique des « mouvements » du pointeurHEAD
.
Reprenons notre développement : La situation n’est pas encore catastrophique, mais que se passe-t-il si nous tentons de revenir sur la branche main
?
$ git checkout main
Warning: you are leaving 2 commits behind, not connected to
any of your branches:
89cd6ad 4th commit
e5245ff 3rd commit
If you want to keep them by creating a new branch, this may be a good time
to do so with:
git branch <new-branch-name> 89cd6ad
Switched to branch 'main'
Là encore, les messages de GIT sont clairs. Nous avons bien deux commits qui ne sont plus rattachés à rien.
$ git log
commit 8169912adcfe5612389e69501f4192db09a85c25 (HEAD -> main)
Author: Emmanuel
Date: Tue Apr 20 21:42:23 2021 +0200
Second commit
commit 1b975d5493080c428fa8421aab72eb52e994cd9f
Author: Emmanuel
Date: Tue Apr 20 21:41:23 2021 +0200
Initial release
Donc là, nous avons perdus 2 commits sur les 4. La commande git reflog
nous donne
$ git reflog
8169912 (HEAD -> main) HEAD@{0}: checkout: moving from 89cd6ad35b505a42df8b98b3d29ef6f939df6c13 to main
89cd6ad HEAD@{1}: commit: 4th commit
e5245ff HEAD@{2}: commit: 3rd commit
1b975d5 HEAD@{3}: checkout: moving from main to 1b975d5
8169912 (HEAD -> main) HEAD@{4}: commit: Second commit
1b975d5 HEAD@{5}: commit (initial): Initial release
Pour terminer notre périple : si nous souhaitons conserver ces commits, en les identifiants clairement, nous avons la possibilité de les rattacher à une branche.
$ git branch nouvbranche 89cd6ad # Creation d'une branche qui va pointer sur le 4ieme commit
$
$ git reflog
8169912 (HEAD -> main) HEAD@{0}: checkout: moving from 89cd6ad35b505a42df8b98b3d29ef6f939df6c13 to main
89cd6ad (nouvbranche) HEAD@{1}: commit: 4th commit
e5245ff HEAD@{2}: commit: 3rd commit
1b975d5 HEAD@{3}: checkout: moving from main to 1b975d5
8169912 (HEAD -> main) HEAD@{4}: commit: Second commit
1b975d5 HEAD@{5}: commit (initial): Initial release
Ce qui donne graphiquement :Nous sommes maintenant revenu à une situation « propre », avec l’ensemble de nos commits attachés à une branche.
J’ai été un peu long sur ces explications, mais je pense que c’est un cas très intéressant pour mieux comprendre la notion de pointeur, et de branche.
Avance rapide, et vraie fusion
Revenons aux fusions, en entrant un peu plus dans le détail. Précédemment, j’ai dit que la fusion créait systématiquement un commit de fusion. Ce n’est pas tout à fait vrai. Lorsque nous invoquons la commande git merge
, nous avons deux cas de fusion : le fast-forward (avance rapide), et le true merge (vrai fusion).
Plaçons-nous dans la situation suivante :
- Nous avons une branche
main
, avec déjà un certain historique, - Nous décidons l’implémentation d’une nouvelle fonctionnalité : nous avons créé pour cela une branche
feature
, dans laquelle nous avons effectué des modifications, - Entre temps, des utilisateurs nous ont signalé des erreurs. Pour gérer la correction, nous avons donc créé une branche
patch
, pour les corriger.
Le fast-forward
Notre correction étant prête, nous souhaitons l’incorporer à notre branche principale. Utilisons donc la commande merge
:
$ git checkout main
Switched to branch 'main'
$ git merge patch
Updating e31b465..291892b
Fast-forward
file2.xt | 2 +
1 file changed, 2 insertions(+)
Ici, le commit G est un descendant direct du commit C de la branche main
. Il n’y a pas de modifications divergentes à fusionner. GIT se contente alors d’avancer le pointeur HEAD
. Cette opération s’appelle un fast-forward (avance rapide), comme indiqué dans la réponse de la commande merge
.
Supprimer maintenant la branche patch
dont nous n’avons plus besoin.
Le true merge
Maintenant que l’application fonctionne de nouveau sans erreur, nous reprenons le fil de notre développement. Notre nouvelle fonctionnalité est prête, les modifications de la branche feature
peut être incorporées à la branche principale. Si nous effectuons une fusion, nous obtenons
$ git checkout main
Switched to branch 'main'
$ git merge feature
Merge made by the 'recursive' strategy.
file2.txt | 1 +
1 file changed, 1 insertion(+)
Dans cas, GIT va réaliser une fusion à trois sources (three-way merge): le dernier commit de la branche main
(G), le dernier commit de la branche feature
(F), et le premier ancêtre commun (C). L’outil va créer un nouveau commit, appelé commit de fusion (merge commit), et va déplacer le pointeur head
sur celui-ci.
Nous parlons dans ce cas, d’une vraie fusion (true merge). Nous pouvons maintenant supprimer la branche feature
, dont nous n’avons plus besoin.
Influencer le comportement de GIT
Dans les deux cas précédents, nous avons laissé GIT décider de la statégie de fusion. Comme vous pouvez le constater avec les figures figure 16 et figure 18, appliquer l’une ou l’autre des méthodes de laisse pas le même historique. Pour diverses raisons, notamment lorsque l’on travaille en groupe, notre volonté peut être de
- Garder un historique des modifications, pour privilégier la traçabilité,
- Ou, au contraire, proposer un historique propre et linéaire pour une compréhension plus aisée.
Il est possible d’influencer la stratégie de fusion avec le paramètre --no-ff
, qui comme son nom l’indique, demande à GIT de ne pas réaliser de fast-forward.
$ git checkout main
Switched to branch 'main'
$ git merge patch --no-ff
Fusion de deux branches avec la commande rebase
Jusqu’à présent, nous nous sommes basés sur des exemples, où une branche de développement, issue d’une branche principale, “avance” plus vite que sa branche mère. Mais que se passe-t-il, si l’historique de la branche principale évolue régulièrement, en parallèle de notre branche de développement ?
L’exemple
Reprenons notre exemple précédent. A la fin du fast-forward, nous avons :
Lors du développement de la nouvelle fonctionnalité, nous découvrons que le patch est nécessaire au son fonctionnement.
Pour remédier à cette situation, nous pouvons considérer une fusion, non pas de la branche de feature
vers la branche main
, mais au contraire, de la branche main
vers la branche feature
, pour ensuite continuer nos développements :
et nous pouvons poursuivre le développement sur la branche feature
, puis incorporer cette branche à notre branche principale (en mode true merge)
Comme vous pouvez le constater, l’historique de développement devient un peu compliqué. Comprendre cette historique avec les commandes git log
va devenir extrêmement complexe.
Nous avons une autre possibilité d’intégrer le patch dans la branche de développement, en utilisant la commande rebase
, dont la syntaxe est tout à fait similaire, à celle de la commande merge
:
$ git checkout feature
$ git rebase main
La commande rebase
« réécrit » l’historique de la branche en créant de nouveaux commits (E’, F’ dans le cas de la figure 22) pour chaque commit de la branche d’origine. Nous avons donc maintenant :
- Les modifications de la nouvelle fonctionnalité, incluant le patch,
- Un historique beaucoup plus propre que celui obtenu avec la commande
merge
.
A partir de là, nous pouvons continuer le développement de la fonctionnalité, avant de l’intégrer dans la branche principale :
Pour résumer
La commande git rebase
peut être utilisée lorsque nous sommes dans les situations suivantes :
- Certaines fonctionnalités de la branche principale sont pertinentes pour notre développement,
- La base de départ de notre branche de développement est jugée obsolète,
- Les deux branches divergent trop, et la future fusion risque d’être complexe à exécuter.
Utiliser la commande git merge
est possible, mais comporte deux principaux inconvénients
- En fonction des cas, cette opération peut rendre la lecture de l’historique relativement complexe à comprendre,
- Le commit issu de la fusion des deux branches peut intégrer un grand nombre de modifications comparé à son prédécesseur, ce qui peut rendre, là encore, les choses difficiles à comprendre.
La commande git rebase
permet donc d’intégrer l’historique de la branche principale, tout en conservant un historique simple.
- Les avantages
- L’historique du projet est plus propre,
- L’historique étant linéaire, il est plus facile à remonter,
- Les inconvénients
- On perd certains points de contexte : les moments de divergence, et de convergence (les merges),
- La commande peut potentiellement poser des problèmes vis-à-vis des dépôts distants (que nous verrons dans le chapitre suivant),
- La commande
merge
ne touche pas aux commits existants. La commanderebase
réécrit l’historique : elle peut être potentiellement dangereuse.
Suppression d’une branche
La commande pour supprimer une branche est la suivante :
$ git branch -d <nom de la branche à supprimer>
A noter que l’on peut également utiliser le paramètre -D
qui est équivalent à -d -f
(--delete --force
)Les commits de la branche feature
ne sont pas effacés. Ils subsistent, et peuvent être listés grâce à la commande git reflog
, qui référence l’historique du pointeur HEAD
.
Stratégie de fusion et flux de travail
Avec ce chapitre, nous commençons à voir qu’utiliser GIT n’est pas qu’une question technique, mais c’est également une question de méthodologie, surtout lorsque l’on travaille en groupe, avec des dépôts distants.
Il est important de définir des conventions, et une méthodologie commune de travail sans quoi,
- Il y aura toujours un risque de perte des modifications,
- L’historique de ces modifications deviendra illisible, et la traçabilité deviendra quasiment impossible.
Conclusion
Nous venons d’aborder la notion de branche dans GIT. Nous en avons profité pour “jouer” un peu avec les pointeurs. Les épisodes 2 et 3 montrent bien ce que j’annonçais dans l’épisode 1 : bien comprendre l’outil, c’est avant tout savoir ou l’on se trouve : à la fois dans les différentes zones de stockage, et à la fois dans notre arbre de commits.
Nous allons continuer notre apprentissage de GIT, en abordant, dans le prochain épisode, les dépôts distants.
Commentaires