4Fermer6
ZephLe 10/02/2018 à 13:22
Tu devais avoir à la fois au moins un commit en local qui n'existait pas sur la branche distante, et au moins un commit distant qui n'existait pas sur ta branche locale. Visuellement ça veut dire ça :
       o ab12cd (origin/master, branche distante)
o-o--<
       o cd32ab (master, branche locale)
Si tu demandes à Git de se débrouiller avec ça (avec la commande git pull origin master sans spécifier aucune option par exemple) il va créer un commit de merge pour s'en sortir, c'est à dire un commit qui aura 2 parents. Visuellement ça ressemblera à ça :
       o ab12cd
o-o--<   >--o ef45ab (nouveau commit)
       o cd32ab
Git a tendance à privilégier cette option par défaut puisque c'est la seule qui permet de préserver les deux commits précédents (ab12cd et cd32ab) intacts. Si tu veux éviter ça pour garder un historique linéaire, tu es obligé d'en réécrire l'un des deux : soit tu réécris ton commit local pour faire comme s'il avait été écrit à la suite du distant, soit tu réécris le commit distant pour faire comme s'il avait été écrit à la suite du local. Par exemple en choisissant la première option tu peux utiliser git rebase origin/master pour lui dire : réécrit tous mes commits en local qui n'existent pas dans la branche "origin/master" de façon à ce qu'ils soient ajoutés au bout de cette dernière. Le résultat ressemblera à ça :
    ab12cd  fa89de
o-o-o-------o (ancien commit cd32ab réécrit)
C'est tout beau tout propre et tout linéaire, il n'y a plus de commit de merge, mais en revanche ton ancien commit "cd32ab" n'existe plus : il a été remplacé par un nouveau commit "fa89de" qui n'a plus le même parent (qui ne se "base" plus sur le même état du code, d'où le nom de la commande). Comme cette opération va réécrire un (ou plusieurs) commits il y a également un risque que Git n'y arrive pas tout seul et qu'un conflit, c'est à dire une modification concurrente au même endroit dans le même fichier, soit à résoudre.