• [^] # Re: Pourquoi du théorie des patch c'est bien

    Posté par (site web personnel) . En réponse au journal Pijul, un nouveau gestionnaire de source. Évalué à 4.

    C'est marrant comme il suffit de parler d'un concept mathématique relativement avancé en termes un tant soit peu profanes pour t'invoquer. Y a sûrement une nouvelle tradition de magie à la Ouija à monter.

    Je sais d'avance que la suite de cette conversation sera, en réponse, un autre pavé encore plus indigeste pour moi, que je ne comprendrai carrément pas, car j'ai arrêté les maths suffisamment tôt pour ma satisfaction professionnelle vu que j'aime mon travail, mais trop tôt par rapport à la maitrise d'icelles que j'aimerais avoir, mais bon je me lance quand même.

    pijul aussi gère, à sa façon, un graphe orienté d'états successifs

    Oui alors c'est sûr, si tout le monde appelle dans son cas "état" ce qu'il stocke dans un sommet, on gère tous des états. Git stocke en premier lieu des "états"-"sommets" qui représentent concrètement et trivialement le contenu brut du dépôt aux instants T(x), et ajoute par dessus un graphe de relations bête et méchant. J'ai l'impression que pijul travaille dans l'autre sens en ayant comme citoyen de première classe les arêtes avec le patch comme contenu, et en déduit des sommets-"état du dépôt".

    un dépôt c'est une catégorie, c'est-à-dire un graphe orienté qui vérifie certaines propriétés.

    Du peu que je sais j'ai l'impression que le c'est-à-dire est à l'envers. Je peux envisager de voir un graphe orienté comme une catégorie, en tant que suite de morphismes dans le même groupe (transformation de fichiers) à chaque fois, mais à l'inverse, voire toute catégorie comme un graphe orienté, j'ai plus de mal, puisque dans une catégorie par définition les morphismes de groupe n'ont à priori pas les mêmes ensembles de définition et d'image ? Ou alors un graphe peut avoir des sommets "fichiers" et des sommets "bananes" si une des arêtes est un morphisme de groupe partant de l'ensemble "fichiers" et arrivant dans l'ensemble "banane", ce qui, convenons-en, ne sera que peu exploitable comme gestionnaire de sources.

    Les sommets du graphes sont des « fichiers » et les arcs des patchs : si il y a un arcs entre deux sommets alors la cible est le résultat du patch appliqué à la source.

    Si par arc tu veux parler de ce que j'appellerais arête, alors à vérifier mais dans git les sommets c'est pareil (et c'est pas que "des fichiers", c'est "tous les fichiers du dépôt à l'instant T") par contre les arcs ne sont pas valués comme semblent être ceux de pijul, ils ne représentent que la relation "tel commit a tel ascendant dans le graphe". La sortie de git diff par exemple (dans mon souvenir ; si je me goure, j'ai perdu toute crédibilité :-)) n'est pas l'affichage des "patchs" contenus dans les arêtes comme dans pijul, mais est reconstruite en comparant les deux instantanés du dépôt comparés.

    En écrivant ça j'ai l'intuition de retrouver ce pourquoi git est si plaisant à utiliser (surtout comparé à SVN qui était dominant à l'époque, il est vrai). Faire un "rebase" en git (prendre un bout de graphe et le déplacer) est extrêmement efficace (il ne déplace que des relations) mais peut effectivement créer des changements autres que ceux "contenus" dans les commits (même si pour rappel un commit ne contient pas de changement mais décrit un nouvel état complet) d'où conflits à résoudre. Sauf que je ne vois pas comment pijul peut être magiquement mieux. Si pijul a stocké "alors là tu changes la ligne 3 du fichier 'foo' de 'bar' vers 'baz'" comme patch, par quelle magie, lorsque je le rebase sur un nouveau sommet où précédemment la dite ligne 3 a été modifiée de 'bar' vers 'boo', il recolle les morceaux ? A part en disant "oh merde je m'en fous je colle 'baz' puisque de toute façon on voulait 'baz'". Ou alors en disant "euh au secours conflit !".
    Exactement comme git en fait.

    A ce propos je rebondis sur ta première image, c'est précisément le même biais que dans le lien que je critiquais. Vous prenez tous les deux le cas "simple" où la ligne changée dans les deux branches est la même au départ. C'est "simple" pour un humain parce que c'est "la même" visuellement et on se dit "pffff git est con", mais :

    • il ne peut pas déterminer que fonctionnellement c'est la même (si dans une branche je change 'bar' en 'boo' puis re en 'bar', c'est toujours la même ? Par quelle règle non écrite qui assure que ce n'est pas une coïncidence ?
    • et donc comment votre outil magique résout le problème si malheureusement je sors de votre exemple contrit et je modifie la ligne des deux côtés ?

    Ta deuxième image est carrément malhonnête. Tu ajoutes un original qu'il n'y avait pas et qui comme par hasard renforce l'effet visuel de "j'ai juste ajouté une ligne" (sauf que dans la réalité ce n'est qu'un cas particulier simple pour un humain qui comprend le fonctionnel des sources). Si toi et ta femme aviez changé "work" pour une ligne différente chacun de votre côté ?

    Par ailleurs le merge final (ainsi que sa généralisation dans la 3ème image) est simplement un merge déterministe, ce qui :

    • est parfaitement possible avec git en choisissant une stratégie de merge déterministe
    • ne fonctionne pas en réalité : d'accord tu as résolu le merge technique, mais qui te dit que le code fait ce que tu veux (y a même des chances que ça ne compile juste pas) ? Si tu as la réponse, félicitations, tu as trouvé le programme qui prouve tous les autres programmes, tu vas être maître du monde.