Changer des commits de branche
Tu pensais avoir changé de branche et tu as créé un ou plusieurs commits pour t’apercevoir après coup qu’ils ne sont pas au bon endroit ?
Voyons ensemble comment te sortir de cette mauvaise situation.
Cet article fait partie de notre série pour savoir annuler, défaire et corriger.
Plusieurs situations = plusieurs solutions
Comme souvent avec Git, on peut trouver plusieurs solutions à un même problème. À toi alors de trouver celle qui te convient le mieux, sachant qu’il n’y a de meilleure solution que celle qui te met à l’aise. On vise surtout à obtenir un résultat !
On peut résumer les situations aux 3 cas suivants :
1. Création de branche ratée
Tu pensais avoir créé une branche (disons dev
), mais pour une raison quelconque ça n’a pas fonctionné. Tu n’as pas prêté attention au message d’erreur et tu as créé plusieurs commits (d1
et d2
) :
Pour régler ça, tu dois procéder en deux étapes :
- Tu peux créer ton étiquette de branche à ton emplacement actuel
- et ramener l’étiquette
main
à l’emplacement dem3
:
git branch dev
git branch -f main m3
Si tu vérifie ton historique, tu verras que tu es retombé sur tes pattes !
2. Changement de branche raté
La branche sur laquelle tu voulais créer tes commits existe déjà (dev
). Tu as voulu changer de branche et tu n’as pas vu que ton switch
(ou checkout
) a échoué. Tu as créé tes commits (d2
et d3
) sur ta branche courante.
Tu veux donc que d2
et d3
soient “déplacés” sur la branche dev
. Tu pourrais aller sur dev
et copier-coller les 2 commits en faisant du cherry-picking pour ensuite les retirer de main
avec un reset
, mais ça serait un peu lourd à mettre en œuvre. Je te recommande d’utiliser plutôt la commande rebase
et de sélectionner l’intervalle à déplacer :
git rebase --onto d1 m3 d3
Cette opération déplace les commits à la suite du commit d1
mais te laisse en tête détachée, c’est-à-dire que les commits ne sont rattachés à aucune branche, seulement à HEAD. Il faut donc forcer le déplacement de l’étiquette de la branche dev
sur la copie de d3’
pour terminer l’opération :
git switch --force-create dev d3’
Notre historique ressemble alors à ça :
J’ai noté des primes (’
) pour les commits d2
et d3
pour signaler qu’il s’agit de copies avec de nouveaux identifiants.
main
contient encore les anciens commits
On constate que main
contient encore les commits d2
et d3
. Tu dois donc les retirer. Tu peux faire ça avec reset
:
# On se remet sur "main"
git switch main
git reset --keep m3
Tu peux vérifier une dernière fois que le résultat est celui attendu :
3. Changement de branche doublement raté
Comme dans la situation 2, tu as créé tes commits d2
et d3
sur ta branche courante main
, pensant être sur dev
, puis tu as créé d’autres commits (m4
et m5
) toujours sur main
. Les commits d2
et d3
sont “coincés” entre m3
et m4
.
Tu peux utiliser la même solution que pour la situation précédente sauf en dernière étape où tu ne pourras pas simplement faire un reset sur main
.
# 1. on copie les commits "d2" et "d3" sur "dev"
git rebase --onto d1 m3 d3
# 2. on force le repositionnement de "dev" sur le commit "d3’"
git switch --force-create dev d3’
En dernière étape, tu veux retirer d2
et d3
de main
et garder m4
et m5
. Tu peux faire ça avec un autre rebase avec l’option --onto
:
git rebase --onto m3 d3 main
Vous pouvez aussi regarder le programme de notre formation "Comprendre Git" ou nous poser vos questions sur notre forum discord.