ce notebook est complètement optionnel
use case 1¶
avant de voir le cherry-pick dans le détail, donnons d’abord un use case classique
on en profite d’ailleurs pour introduire la notion de tag, que l’on n’a pas encore eu l’occasion de voir jusqu’ici
vous êtes en charge de l’évolution et la maintenance d’un logiciel
le développement de la future version 4 se fait sur la branche main
mais la plupart des clients utilisent une version stable 3.0
et le reste des clients n’a pas eu le temps d’upgrader et utilisent la 2.2
typiquement dans ce cas de figure on va créer:
deux branches
3.x
et2.x
pour suivre les évolutions de la version 3autant de tags que de versions publiées, ici par exemple 2.0, 2.1, 2.2, 3.0
le repo ressemble à ceci - (le carré représente le commit courant; de plus, imaginez entre les versions 2.0 et 3.0 un bien plus grand nombre de commits..)
cherry-pick
¶
dans ce genre de cas, il arrive qu’on corrige sur main
un bug important (voyez le commit marqué d’une croix ci-dessus); et du coup on veut pouvoir facilement appliquer ce fix sur les deux branches - mais bien entendu sans prendre les autres commits qui sont sur main
c’est exactement que sert cherry-pick
; ce qu’on ferait dans ce cas-là ce serait
git switch 3.x
git cherry-pick <le-hash-du-bugfix>
git switch 2.x
git cherry-pick <le-hash-du-bugfix>
# et pour se remettre sur main
git switch main
on le voit, cherry-pick nous permet d’appliquer seulement un commit sur la branche courante
en tous cas si ça fonctionne, après
(ne pas faire attention aux hashes, qui ne sont pas les mêmes que dans le premier diagramme...)
revert
¶
La commande revert
fonctionne d’une manière assez voisine à cherry-pick
, sauf que revert
va appliquer le commit à l’envers, c’est-à-dire avec l’objectif de le défaire
ça s’utilise donc dans des contextes très différents de notre use case 1
use case 2¶
typiquement on pense à revert
dans le cas où on a créé un commit, puis on se rend compte que ce n’était pas une si bonne idée que ça
imaginons qu’on est dans cet état
on a le choix entre deux stratégies trés différentes
supprimer complètement toute trace du dernier commit¶
dans ce cas, on feraitgit reset --hard HEAD^
mais bon, admettons que tout est clair, si on fait ça on se retrouve avec
faire un nouveau commit qui défait le dernier¶
du coup il y a autre alternative, qui consiste à enregistrer le fait qu’on a essayé ça et que ça n’a pas marché
c’et-à-dire à remettre un nouveau commit qui revient en arrière
et pour faire ça on ferait simplement
git revert HEAD
en effet, comme on l’a déjà mentionné la logique de git revert
c’est un peu celle de cherry-pick, mais à l’envers
ici je vais défaire le commit courant, encore un abus de langage: je vais appliquer le changement entre HEAD
et son parent, mais à l’envers
puisqu’on crée un nouveau commit, git revert va nous demander un message, disons qu’on met “undo the wrong idea”, et dans ce cas de figure on se retrouve avec
dans lequel le contenu des commit HEAD
et HEAD~2
est identique
mais cette approche a l’avantage de, à nouveau, laisser dans l’historique une trace de cette expérience