Comprendre git image/svg+xml Comprendre git Jérémy Soulary Résolution deconflits de merge Remotes Sens des merges Recap Bases Des questions ? Naviguer dansle graphe git Index / WT snapshot du FS lien vers lecommit parent Metadata(commentaire,auteur, date) 31b2d8 31b2d8 Les branches origin/* develop de Bobvu depuis chez Bob(develop) develop de gitlabvu depuis chez Bob(origin/develop) = dernier états connus des branches du serveur. Pour les mettre à jour,il faut faire un fetch (ou un pull) develop de Bobvu depuis chez Bob(develop) develop de gitlabvu depuis chez Bob(origin/develop) develop de gitlabvu depuis gitlab(develop réel) origin/develop est maintenantun ancêtre de develop de Bob Bob peut maintenant push develop Le fast forward est ce qu'il se passe lorsque on pullquand on n'a pas fait de nouveaux commit origin/develop develop origin/develop develop pull de develop V C V C Fast Forward de C sur V Si l'on souhaite merger V dans C,au lieu de créer un nouveau commit de merge,on peut avancer le pointeur de C sur V = avancer un pointeur de branchevers un commit descendant Fast Forward Remote develop de Bob develop de Nat develop de gitlab develop de Pat Car git est décentralisé Tout le monde a des branches différentes !Mais les mêmes commits ! garantie par les SHA-1 => la branche develop du serveur pointerasur le même commit de develop de Bob develop de Bobvu depuis chez Bob(develop) develop de gitlabvu depuis chez Bob(origin/develop) develop de gitlabvu depuis gitlab(develop réel) la branche origin/developde Bob est aussi mise à jour push = déplacer la branche du serveur sur le même commit que notre branche develop de Bobvu depuis chez Bob(develop) develop de gitlabvu depuis chez Bob(origin/develop) develop de gitlabvu depuis gitlab Réalité Avant le fetch : merge de origin/develop dans develop develop de gitlabvu depuis gitlab develop de Bobvu depuis chez Bob(develop) develop de gitlabvu depuis chez Bob(origin/develop) Après le fetch : fetch develop de Bobvu depuis chez Bob(develop) develop de gitlabvu depuis chez Bob(origin/develop) develop de gitlabvu depuis gitlab(develop réel) Il doit alors pull pour:-se mettre à jour-merger origin/develop dans develop pull pull = fetch + merge Un commit pourra être perdu si : - plus atteignable depuis une branche ou un tag - créé il y a plus de 2 semaines Si Bob veut push (son) develop,le serveur va refuser le push. push possible seulement sila branche du serveur est un ancêtre develop de Bobvu depuis chez Bob(develop) develop de gitlabvu depuis chez Bob(origin/develop) develop de gitlabvu depuis gitlab => si on peut l'atteindre ensuivant les flèches push = déplacer la branche du serveur sur le même commit que notre branche Si l'inverse était autorisé, nous pourrions perdre des commits : develop de Bobvu depuis chez Bob(develop) develop de gitlabvu depuis gitlab Récap -git = gestion de graphe-commit = snapshot, garantie par le SHA-1-branche et tags = pointeurs-un merge = commit comme les autres-diff d'un merge => par rapport au 1er parent-origin/* = derniers états connus du serveur-push = déplacer la banche du serveur-sens des merges important pour la lisibilité-on ne modifie que la branche courante Lorsqu'il y a un conflit,git ajoute des marqueurs spécifiquesdans les fichiers en conflit Pour résoudre le fichier et le mettre dans un état correct,il faut utiliser des outils un bête éditeur de texte très hasardeux, et peu pratique ! Un outil dédié aux merges, à 3 vues Versionde la branchecourante Versioncommune Versionde la brancheà merger Comme celui d'IntelliJ : Versionde la branchecourante Versioncommune Versionde la brancheà merger Version mergée Un outil dédié aux merges, à 4 vues Comme P4Merge : Un outil de diff classique à 2 vues Comme celui d'Eclipse (par exemple) : Versionde la branchecourante Versionde la brancheà merger Mais 2 vues ne suffisent passurtout si on ne connaît pas le code à merger. Ce qui arrive facilement si nous sommes plusieursà travailler sur une branche de feature par exemple. Comment savoir ici quel est la version garder de ces lignes ? p4merge résout les conflits "évidents",seuls ceux en rouge sont à résoudre à la main. Versionde la branchecourante Versioncommune Versionde la brancheà merger Version mergée graphe qui rappelleles versions affichées Il faut éditer les parties en rouge,et choisir quelle version garder,ou écrire à la main la version mergée } Code couleur et forme des différentes parties. Un clic sur les icônes conservera ou supprimerales parties concernées. partie modifiéedans la branchecourante partie modifiéedans la brancheà merger 4 parties ça fait beaucoup ! mais on comprend ce qu'il s'est passé... Et donc, concrètement ? Si un merge rencontre un conflit, le merge est stoppé il faut lancer mergetool (depuis l'IDE ou la CLI) p4merge va ouvrir chaque fichier en conflit une fois résolu, il faut commiter le merge Lorsque les fichiers en conflits ont été résolus,il faut commiter pour terminer le merge snapshotdu FS lien vers lesparents Metadata(commentaire,auteur, date) Le merge a "mélangé" les 2 commits,pour créer un nouveau commit quiva lui aussi stocker une snapshot, toutcomme n'importe quel commit Ce n'est pas un patch qui est stocké ! Note : pour résoudre un merge correctement,il peut être nécessaire de modifier d'autresfichiers que ceux qui sont en conflit.Par ex, un refactor d'un coté, un ajout de l'autre Si nous reprenons l'exemple concret, plus haut : Ici, on peut comprendre que c'est dans la branche à merger (à droite), que les nomsde variables ont été modifiés. C'est la version verte que l'ont doit conserver. Les 2 commits ci dessous sont identiques (leur FS)mais leur diff est très différent : Mais cela impact pas mal la lisibilité de l'historique Le sens des merges => presque le même commitseul l'ordre des parents sera différent En effet : diff avec le premier parent dans les outils tout le vert quen'avait pas bleu tout le bleu quen'avait pas vert Pourquoi il ne faut pas travailler dans develop... ... si l'on souhaite garder une lisibilité de l'historique develop origin/develop merge créé après un pull Le premier parent dece merge est à nous Le diff du merge correspondraalors à tous les commits quenous n'avons pas écrit. le diff d'un merge affiche tout ce quela branche mergée apporte,on souhaite ajouter du travailledans le develop du serveur, pas l'inverse Nous sommes l'auteur de ce commit de mergemais pas des modifications affichées dans le diff ! on ne saura pas facilement quand notre travail a été intégré dans develop (du serveur) :car notre merge n'appraraitra pas dans l'historique des fichiers que l'on a modifiés. (cas de bug commité en aout, intégré en septembre dans dévelop, dans le mauvais sens) Autres choses importantes à comprendre - on ne modifie que la branche courante (sauf cmd particulières) => par ex : l'on merge dans la branche courante - des commandes sont ambiguës : reset et checkout avec fichiers sans fichiers checkout reset changer la version d'un fichier changer de branche changer la versiond'un fichier dans l'index déplacer le pointeurde la branche rebase bisect L'index Plein d'autres choses à découvrir cherry-pick log difftool gitlab-ci git-svn submodule stash revert reflog gc & prune filter-branch blame archive imerge Comprendre git ! pour mieux travailler avec Auteur: Jérémy Soulary snapshot du FS lien vers lecommit parent Metadata(commentaire,auteur, date) d95148 = → pointeur vers la référence actuelle généralement une branche, sinon on est en "tête détachée" Commit sur master Commit en mode "tête détachée" FeatureB master HEAD FeatureB master HEAD FeatureB FeatureB HEAD master HEAD master HEAD = master HEAD = master HEAD = d3a4b HEAD = 4cae6 d3a4b d3a4b 4cae6 d3a4b d3a4b 4cae6 git prune à la demande ou automatiquement tout les 30 jours, git fait le menage Tous les commits non atteingnables depuis une référence sont supprimés HEAD, branches et tags master HEAD FeatureB Commit perdus "Commit atteingnable" = en suivant les flêches checkout master HEAD FeatureB master HEAD FeatureB git checkout FeatureB HEAD = master HEAD = FeatureB reset master HEAD FeatureB FeatureB git reset FeatureB HEAD = master HEAD = master master HEAD L'index Le répertoire de travail Les outils status stash cherry-pick diff rebase log blame amend revert "fix develop 1"par @totole 09/11/2017à 09:12:44 master HEAD FeatureB - les SHA-1 : 4cae6, d3a4b- les branches : master, FeatureB- les branches distantes : origin/master- les tags : v2.0.4- HEAD- les parents <ref>^N : master^1, 4cae6^2- les ancètres <ref>~N : master~4, 4cae6~6 d3a4b 4cae6 d3a4b Les références master~4 4cae6^2 master^1 - la ligne de commande- outils intégrés aux IDE- gitk- git gui- gitkraken- gitg- git-cola- ... = état du projet qui sera sauvegardé dans le prochain commit on peut l'imaginer comme un zip créé en se basant sur l'étatdu projet lors du dernier commit "git add fileA.txt" → on ajoute un nouveau fichier ou des modifications "git rm fileA.txt" → on supprime le fichier "git reset master -- fileA.txt" → on utilise la version de master pour ce fichier Lorsque l'on change de branche, l'index est mis à jourpour correspondre à l'état stocké par le commit pointé Lorsque l'on change de branche, le répertoire de travail estmis à jour pour correspondre à l'état stocké par le commit pointé "git checkout master -- fileA.txt" → on utilise la version de master pour ce fichier dans le répertoire de travail = état du projet "visible" dans notre exporateur de fichier Présentation créée avec Sozi t Boutondroit Boutongauche Boutondu milieu Gitlab P4Merge Gitlab affiche l'essentiel mais le contexte peut etre utile : il ne faut pas choisir la bleue ici avec Gitlab, car il aura supprimé automatiquement la ligne 14, qui est utiliséedans la version bleue Résolution des conflits depuis Gitlab Résultat enchoisissant"theirs" P4Merge Intellij vousêtesici HEAD = changer de branche = téléporter la branche Pour résoudre le merge,git cherche le premierancêtre communsaux commits à merger Sinon, il y a alors un conflit :il faut résoudre ce conflit manuellement Si, aucun fichier n'a été modifiésur ces 2 chemins en même temps,git fait le "mélange" des 2 commitsautomatiquement merge = commit normal mais avecplusieurs commits parents il contient donc également :-une snapshot du FS-des metadata (commentaire, ...) v2.0.3 tag = pointeur vers commit le pointeur d'un tag nechangera jamais(sauf suppression) Seulement aussi ! develop FeatureB FeatureA branche = pointeur vers commit nouveau commit => le pointeur avance Seulement ! Nous pouvons créer une branchen'importe quand et surn'importe quel commit acbcf4cb6ce7797bf6df25594c6fc5396fe55278 .git/refs/heads/develop 31b2d8 "fix develop 2"par @totole 09/11/2017à 09:12:44 701e96 SHA-1 = le code barre du commit d95148 le SHA-1 est calculé en fonction detout ce qui compose le commit un commit= Même si un seul fichier est modifié,tout l'état du FS est sauvegardé. Un commit n'est pas un patch ! 701e96 Flèches vers le(s)commit(s) parent(s) git = gestion de graphe Temps commiter = créer un nouveau noeud + lien(s) vers le(s) parent(s) État du projet
1
  1. Titre
  2. Graphe
  3. commit
  4. SHA1
  5. rewrite
  6. branch
  7. tag
  8. merge
  9. resol
  10. conflit
  11. text
  12. 2vues
  13. 2vueszoom
  14. 3vues
  15. 4vues
  16. gitlab-conflits1
  17. gitlab-conflits2
  18. gitlab-conflits3
  19. p4merge
  20. p4mergezoom
  21. conflit-resol
  22. conflit-resol-zoom
  23. merge-resume
  24. sens-merge
  25. sens-merge-diff
  26. develop-checkout
  27. head
  28. prune
  29. checkout
  30. reset
  31. references
  32. remote
  33. origin
  34. avant-fetch
  35. apres-fetch
  36. push-refused
  37. push-refused-detail
  38. pull
  39. pull-dezoom
  40. push-ok
  41. push-after
  42. ff
  43. ff-pull
  44. index
  45. wt
  46. outils
  47. div
  48. recap
  49. next
  50. questions