Envoyé par
gitnoob
j'utilise rien, je fais juste un git log --oneline, je vais tester avec --graph
Dans ce cas, je te conseille effectivement de commencer avec --graph (depuis lequel tu devrais retrouver à peu près ce que tu vois chez Github), puis de choisir un client Git, graphique ou pur texte dans un terminal. Personnellement, j'utilise tig sous Linux, qui a l'avantage d'être packagé dans toutes les distributions, d'être léger, de fonctionner dans un terminal et de s'en tenir à la mise en forme et à quelques commandes élémentaires, ce qui permet de visualiser facilement son dépôt tout en s'en tenant aux vraies commandes Git lorsqu'il s'agit de modifier son dépôt.
En voici une liste :
https://git-scm.com/downloads/guis
https://archive.kernel.org/oldwiki/g...sAndTools.html
je fais ca avec github, je ne sais pas quel mode ca utilise.
c'est quoi la diff entre les deux?
« L'avance rapide » ou « fast forward » (--ff) est effectivement un concept-clé sous Git car il découle naturellement de l'architecture en graphe du système. On y est confronté en permanence. C'est également ce qui fait que la fusion de deux branches et la mise à jour d'une branche par rapport à son homologue sont en fait une seule et même opération sous Git.
Lorsque tu utilises une branche locale main et une branche origin/main (ou master, initialement sous Git), il s'agit en fait bel et bien de deux branches distinctes, même si l'une est configurée pour suivre l'autre. C'est d'ailleurs bien le cas puisque lorsque l'on est tout seul à travailler sur un projet, on ne sert des branches distantes que pour sauvegarde, publication et mise en ligne mais on est plusieurs dessus, alors la branche distante origin/main va évoluer indépendant de la branche locale main au gré de ce que les autres personnes vont pousser dessus. Il faut donc bien rapatrier d'abord les nouveautés qui s'y trouvent avec pull avant d'y intégrer les siennes.
En ce sens, Git va donc traiter les branches locale main et distante origin/main comme s'il s'agissait de deux branches ordinaires, locales, et a priori indépendantes entre elles. Ceci veut dire que tout ce qui suit peut également s'appliquer sur de telles branches ordinaires, lorsque tu les fusionnes.
1er cas
Toi et un de tes collègues avez travaillé tous deux sur origin/main en même temps (parce que vous avez travaillé sur vos main respectives en local avant de pousser tout ça sur le serveur). Vous vous retrouvez dans la situation suivante :
Toi O O Ton collègue
\ /
\ /
O Dernier commit commun en date
|
O
|
…
La branche jusqu'ici commune a alors divergé et c'est ce que Git t'indique quand tu fais git pull. Il faut alors résoudre les éventuels conflits et re-fusionner ces deux nouvelles branches en une seule. Tu obtiens alors :
Toi O Ton collègue
/ \
/ \
O O
\ /
\ /
O Dernier commit commun en date
|
O
|
…
… tu pousses le tout, le serveur est de nouveau synchrone avec l'état de ton dépôt local et vous pouvez continuer à travailler.
2ème cas
Ton collègue est le seul à avoir ajouté des choses sur le serveur depuis la dernière fois que vous étiez synchrones. Tu es donc dans la situation suivante :
O Ton collègue (sur origin/main)
/
/
O Toi — Dernier commit commun en date (sur main)
|
O
|
…
Dans ce cas, on est d'accord que ce graphe-là est en fait exactement le même que :
O Ton collègue (sur origin/main)
|
|
O Toi — Dernier commit commun en date (sur main)
|
|
O
|
…
…dans le sens où c'est un graphe. Seules comptent les références de chaque commit à leur(s) parent(s), la position qu'ils occupent dans le plan n'ayant pas de signification pour la machine. Il faut voir ça comme une chaîne de trombones, si tu préfères. C'est important non seulement pour avoir une bonne représentation de comment tout cela fonctionne, mais également parce que les clients Git cités en tête de commentaire vont te les représenter de la même façon.
On constate également que dans cette situation, on n'a besoin de transférer des données que dans un seul sens (ici, du serveur vers ton dépôt), et que ta branche locale est déjà « entièrement contenue » dans la branche distante (ce qui en fait un sous-ensemble). Par conséquent, il n'y a aucun conflit possible puisque les nouveautés de la branche distante s'appuient déjà sur le sommet de ta branche locale.
En conséquence, la seule chose que Git ait besoin de faire ici est télécharger les objets manquants chez toi (les références qu'ils contiennent construisant automatiquement l'historique) et une fois que c'est fait, mettre à jour l'étiquette main pour qu'elle pointe le dernier objet en date. Une fois que c'est fait, ta branche devient automatiquement l'identique de celle du serveur.
C'est exactement cela que Git appelle une « avance rapide » et si ta branche est configurée pour (elle l'est par défaut), alors Git va procéder de cette façon chaque fois qu'il le pourra. Autrement, tu obtiendras un commit formant un « point de fusion » comme au sommet du premier cas.
On comprend ici que c'est parfaitement adapté à la synchronisation d'une branche locale↔distante. Les commandes push et pull existaient bien avant Git et servaient déjà à synchroniser des dépôts homologues avant même que certains SCM adoptent le modèle en graphe. La plupart du temps, l'utilisateur n'est même pas conscient de ce fait et voit sa branche se compléter naturellement avec les dernières publications en date, ce qui est le comportement attendu.
Par contre, si tu fusionnes deux branches locales chez toi de la même façon, le même phénomène va se produire, mais ce n'est pas forcément ce que tu veux. Si tu fais démarrer une branche develop à partir de main et que tu travailles dessus, tu obtiens :
O Commit spécifique 3 (develop)
|
O Commit spécifique 2
|
O Commit spécifique 1
/
/
O Commit général n (main)
|
O Commit général n-1
|
O Commit général n-2
|
…
Si tu reviens sur main et que tu essaies d'intégrer ta branche develop en la fusionnant, Git aura l'impression que main est en retard sur develop et va la mettre à jour en avance rapide comme dans le cas n° 2 présenté plus haut. Tu obtiens alors :
O Commit spécifique 3 (develop) (main)
|
O Commit spécifique 2
|
O Commit spécifique 1
|
O Commit général n
|
O Commit général n-1
|
O Commit général n-2
|
…
… ce qui est pratique si develop est la branche instable et que seule main contient ce qui a été validé et peut être publié. Mais peut-être souhaitais-tu faire exactement ce que tu fais avec les sous-branches que tu as supprimé ensuite (cleanup, clear_input, etc.), à savoir : conserver la structure de la branche annexe, même si la branche principale ne contient aucun commit entretemps :
O Point de fusion (main)
|\
| \
| \
| |
| O Commit spécifique 3 (develop)
| |
| O Commit spécifique 2
| |
| O Commit spécifique 1
| |
| /
| /
|/
O Commit général n
|
O Commit général n-1
|
O Commit général n-2
|
…
Dans tous ces cas, tu peux soit configurer la branche une fois pour toutes pour qu'elle adopte le comportement souhaité par défaut, soit passer à git commit l'option --ff ou l'option --no-ff.
- --ff force le mode « avance rapide ». La commande échoue si ce n'est pas possible ;
- --no-ff interdit l'avance rapide même si elle aurait été possible, et force la création d'un point de fusion dans tous les cas.
Ceci nous amène à la conclusion de notre dernier commentaire : en utilisant une refspec, tu as forcé la mise à jour d'une étiquette locale pour qu'elle pointe au même endroit qu'une étiquette distante, quelles que soient ces étiquettes même si elles n'ont rien à voir entre elles. C'est en principe une mauvaise chose, mais si tu as forcé develop à se positionner au même endroit que origin/main, alors il se trouve que tu as obtenu par accident ce que tu aurais obtenu en fusionnant develop dans main car comme tu as accidentellement développé sur cette dernière, c'était develop qui était en retard par rapport à main et la fusionner l'aurait mise à jour en avance rapide, et donc aurait fait pointer les étiquettes au même endroit.
Bref, vérifie bien que tu as retrouvé tout ce que tu voulais retrouver et si c'est le cas, c'est que tu as pu retomber sur tes pieds par un coup de chance. Mais sois plus prudent la prochaine fois. ;-)
je suis en train de lire doucement ta reponse. merci
N'hésite pas à poser les questions qui en découleraient dans ce même fil, et à cliquer sur en bas de page quand tu auras obtenu pleine satisfaction.
Partager