Comment et / ou pourquoi la fusion dans Git est meilleure que dans SVN?


400

J'ai entendu à quelques endroits que l'une des principales raisons pour lesquelles les systèmes de contrôle de version distribués brillent est la fusion bien meilleure que dans les outils traditionnels comme SVN. Est-ce réellement dû à des différences inhérentes au fonctionnement des deux systèmes, ou les implémentations DVCS spécifiques comme Git / Mercurial ont-elles simplement des algorithmes de fusion plus intelligents que SVN?


Je n'ai toujours pas obtenu de réponse complète en lisant les bonnes réponses ici. Republié - stackoverflow.com/questions/6172037/…
ripper234


cela dépend de votre modèle. dans des cas plus simples, svn est souvent meilleur car il n'appelle pas accidentellement des fusions à deux voies des fusions à trois voies comme git peut le faire si vous poussez / fusionnez / tirez / poussez sur une seule branche de développement. voir: svnvsgit.com
Erik Aronesty

Réponses:


556

L'affirmation de la raison pour laquelle la fusion est meilleure dans un DVCS que dans Subversion était largement basée sur la façon dont la branche et la fusion fonctionnaient dans Subversion il y a quelque temps. Subversion antérieure à 1.5.0 ne stockait aucune information sur la fusion des branches, donc lorsque vous vouliez fusionner, vous deviez spécifier la plage de révisions à fusionner.

Alors pourquoi les fusions de Subversion sont-elles nulles ?

Méditez sur cet exemple:

      1   2   4     6     8
trunk o-->o-->o---->o---->o
       \
        \   3     5     7
b1       +->o---->o---->o

Lorsque nous voulons fusionner les modifications de b1 dans le tronc, nous émettons la commande suivante, tout en se tenant sur un dossier dont le tronc a été extrait:

svn merge -r 2:7 {link to branch b1}

… Qui tentera de fusionner les modifications de b1dans votre répertoire de travail local. Et puis vous validez les modifications après avoir résolu tous les conflits et testé le résultat. Lorsque vous validez, l'arbre de révision ressemblerait à ceci:

      1   2   4     6     8   9
trunk o-->o-->o---->o---->o-->o      "the merge commit is at r9"
       \
        \   3     5     7
b1       +->o---->o---->o

Cependant, cette façon de spécifier les plages de révisions devient rapidement incontrôlable lorsque l'arborescence des versions se développe, car subversion n'avait pas de métadonnées sur le moment et les révisions fusionnées. Réfléchissez à ce qui se passera plus tard:

           12        14
trunk  …-->o-------->o
                                     "Okay, so when did we merge last time?"
              13        15
b1     …----->o-------->o

C'est en grande partie un problème lié à la conception du référentiel de Subversion, afin de créer une branche, vous devez créer un nouveau répertoire virtuel dans le référentiel qui hébergera une copie du tronc mais il ne stocke aucune information concernant quand et quoi les choses ont de nouveau fusionné. Cela conduira parfois à de mauvais conflits de fusion. Ce qui était encore pire, c'est que Subversion a utilisé la fusion bidirectionnelle par défaut, ce qui présente certaines limitations paralysantes dans la fusion automatique lorsque deux têtes de branche ne sont pas comparées à leur ancêtre commun.

Pour atténuer cette Subversion stocke désormais les métadonnées pour la branche et la fusion. Cela résoudrait tous les problèmes, non?

Et oh, au fait, Subversion est toujours nul…

Sur un système centralisé, comme la subversion, les répertoires virtuels sont nuls. Pourquoi? Parce que tout le monde a accès pour les voir… même les déchets expérimentaux. La ramification est bonne si vous voulez expérimenter mais vous ne voulez pas voir l'expérimentation de tout le monde et de ses tantes . Il s'agit d'un grave bruit cognitif. Plus vous ajoutez de branches, plus vous verrez de conneries.

Plus vous avez de branches publiques dans un référentiel, plus il sera difficile de garder une trace de toutes les différentes branches. Donc, la question que vous vous posez est de savoir si la branche est toujours en développement ou si elle est vraiment morte, ce qui est difficile à dire dans un système de contrôle de version centralisé.

La plupart du temps, d'après ce que j'ai vu, une organisation utilisera par défaut une grande branche de toute façon. Ce qui est dommage car à son tour, il sera difficile de garder une trace des versions de test et de sortie, et tout ce qui est bon vient de la branche.

Alors pourquoi les DVCS, tels que Git, Mercurial et Bazaar, sont-ils meilleurs que Subversion pour créer des branches et fusionner?

Il y a une raison très simple: la ramification est un concept de première classe . Il n'y a pas de répertoires virtuels de par leur conception et les branches sont des objets durs dans DVCS qui doivent être tels pour fonctionner simplement avec la synchronisation des référentiels (c'est -à- dire pousser et tirer ).

La première chose que vous faites lorsque vous travaillez avec un DVCS est de cloner des référentiels (git clone, hg cloneet bzr branch). Le clonage est conceptuellement la même chose que la création d'une branche dans le contrôle de version. Certains appellent cela une fourche ou une ramification (bien que cette dernière soit souvent utilisée pour désigner des branches colocalisées), mais c'est la même chose. Chaque utilisateur exécute son propre référentiel, ce qui signifie que vous avez une branche par utilisateur en cours.

La structure de la version n'est pas un arbre , mais plutôt un graphique à la place. Plus précisément un graphe acyclique dirigé (DAG, c'est-à-dire un graphe sans cycle). Vous n'avez vraiment pas besoin de vous attarder sur les spécificités d'un DAG autre que chaque commit a une ou plusieurs références parentes (sur lesquelles était basé le commit). Les graphiques suivants montreront donc les flèches entre les révisions à l'envers à cause de cela.

Un exemple très simple de fusion serait celui-ci; imaginez un référentiel central appelé originet un utilisateur, Alice, clonant le référentiel sur sa machine.

         a…   b…   c…
origin   o<---o<---o
                   ^master
         |
         | clone
         v

         a…   b…   c…
alice    o<---o<---o
                   ^master
                   ^origin/master

Ce qui se passe pendant un clone est que chaque révision est copiée dans Alice exactement comme elle était (ce qui est validé par les identifiants de hachage identifiables de manière unique), et marque où se trouvent les branches de l'origine.

Alice travaille ensuite sur son dépôt, s'engageant dans son propre référentiel et décide de pousser ses modifications:

         a…   b…   c…
origin   o<---o<---o
                   ^ master

              "what'll happen after a push?"


         a…   b…   c…   d…   e…
alice    o<---o<---o<---o<---o
                             ^master
                   ^origin/master

La solution est plutôt simple, la seule chose que le originréférentiel doit faire est de prendre en compte toutes les nouvelles révisions et de déplacer sa branche vers la dernière révision (que git appelle "fast-forward"):

         a…   b…   c…   d…   e…
origin   o<---o<---o<---o<---o
                             ^ master

         a…   b…   c…   d…   e…
alice    o<---o<---o<---o<---o
                             ^master
                             ^origin/master

Le cas d'utilisation, que j'ai illustré ci-dessus, n'a même pas besoin de fusionner quoi que ce soit . Le problème n'est donc pas vraiment lié à la fusion des algorithmes, car l'algorithme de fusion à trois voies est à peu près le même entre tous les systèmes de contrôle de version. Le problème concerne plus la structure qu'autre chose .

Alors que diriez-vous de me montrer un exemple qui a une vraie fusion?

Certes, l'exemple ci-dessus est un cas d'utilisation très simple, alors faisons-en un bien plus tordu bien que plus courant. Rappelez-vous que cela a origincommencé avec trois révisions? Eh bien, le gars qui les a fait, appelons-le Bob , a travaillé seul et a fait un commit sur son propre référentiel:

         a…   b…   c…   f…
bob      o<---o<---o<---o
                        ^ master
                   ^ origin/master

                   "can Bob push his changes?" 

         a…   b…   c…   d…   e…
origin   o<---o<---o<---o<---o
                             ^ master

Maintenant, Bob ne peut pas pousser ses modifications directement vers le originréférentiel. La façon dont le système le détecte consiste à vérifier si les révisions de Bob descendent directement de celles originde, ce qui n'est pas le cas dans ce cas. Toute tentative de poussée entraînera dans le système quelque chose qui s'apparente à " Euh ... je crains que je ne puisse pas vous laisser faire ça Bob ."

Donc, Bob doit faire un pull-in puis fusionner les modifications (avec git's pull, ou hg's pullet merge; or bzr's merge). Il s'agit d'un processus en deux étapes. Bob doit d'abord récupérer les nouvelles révisions, qui les copieront telles quelles depuis le originréférentiel. On voit maintenant que le graphique diverge:

                        v master
         a…   b…   c…   f…
bob      o<---o<---o<---o
                   ^
                   |    d…   e…
                   +----o<---o
                             ^ origin/master

         a…   b…   c…   d…   e…
origin   o<---o<---o<---o<---o
                             ^ master

La deuxième étape du processus d'extraction consiste à fusionner les conseils divergents et à valider le résultat:

                                 v master
         a…   b…   c…   f…       1…
bob      o<---o<---o<---o<-------o
                   ^             |
                   |    d…   e…  |
                   +----o<---o<--+
                             ^ origin/master

Espérons que la fusion ne rencontrera pas de conflits (si vous les anticipez, vous pouvez effectuer les deux étapes manuellement dans git avec fetchet merge). Ce qui doit être fait plus tard est de réintroduire ces modifications dans origin, ce qui entraînera une fusion rapide car la validation de la fusion est une descendante directe de la dernière du originréférentiel:

                                 v origin/master
                                 v master
         a…   b…   c…   f…       1…
bob      o<---o<---o<---o<-------o
                   ^             |
                   |    d…   e…  |
                   +----o<---o<--+

                                 v master
         a…   b…   c…   f…       1…
origin   o<---o<---o<---o<-------o
                   ^             |
                   |    d…   e…  |
                   +----o<---o<--+

Il existe une autre option pour fusionner dans git et hg, appelée rebase , qui déplacera les modifications de Bob après les dernières modifications. Comme je ne veux pas que cette réponse soit plus verbeuse, je vous laisse plutôt lire les documents git , mercurial ou bazaar à ce sujet.

En tant qu'exercice pour le lecteur, essayez de découvrir comment cela fonctionnera avec un autre utilisateur impliqué. Il en est de même pour l'exemple ci-dessus avec Bob. La fusion entre référentiels est plus facile que vous ne le pensez car toutes les révisions / validations sont identifiables de manière unique.

Il y a aussi le problème de l'envoi de correctifs entre chaque développeur, ce qui était un énorme problème dans Subversion qui est atténué dans git, hg et bzr par des révisions identifiables de manière unique. Une fois que quelqu'un a fusionné ses modifications (c'est-à-dire qu'il a effectué une validation de fusion) et l'envoie pour que tous les autres membres de l'équipe les consomment en les poussant vers un référentiel central ou en envoyant des correctifs, ils n'ont plus à se soucier de la fusion, car cela s'est déjà produit . Martin Fowler qualifie cette façon de travailler d' intégration de promiscuité .

Étant donné que la structure est différente de Subversion, en utilisant à la place un DAG, elle permet de créer des branchements et des fusions de manière plus simple non seulement pour le système mais aussi pour l'utilisateur.


6
Je ne suis pas d'accord avec vos branches == argument de bruit. Beaucoup de branches ne déroutent pas les gens car le développeur principal devrait dire aux gens quelle branche utiliser pour les grandes fonctionnalités ... donc deux développeurs pourraient travailler sur la branche X pour ajouter des "dinosaures volants", 3 pourraient travailler sur Y pour "vous laisser jeter voitures chez les gens "
M. Boy

16
John: Oui, pour un petit nombre de branches, il y a peu de bruit et est gérable. Mais revenez après avoir vu plus de 50 branches et balises ou plus en subversion ou en cas clair où la plupart d'entre elles ne peuvent pas dire si elles sont actives ou non. Problème d'utilisation des outils mis à part; pourquoi avoir toute cette litière dans votre dépôt? Au moins en p4 (puisque "l'espace de travail" d'un utilisateur est essentiellement une branche par utilisateur), git ou hg vous avez la possibilité de ne pas informer tout le monde des changements que vous effectuez jusqu'à ce que vous les poussiez en amont, ce qui est un coffre-fort- garde quand les changements sont pertinents pour les autres.
Spoike

24
Je n'obtiens pas non plus vos "trop ​​de branches expérimentales sont un argument de bruit, @Spoike. Nous avons un dossier" Utilisateurs "où chaque utilisateur a son propre dossier. Là, il peut créer des branches aussi souvent qu'il le souhaite. Les branches sont peu coûteuses dans Subversion et si vous ignorez les dossiers des autres utilisateurs (pourquoi devriez-vous vous en soucier de toute façon), alors vous ne voyez pas de bruit. Mais pour moi, la fusion dans SVN ne craint pas (et je le fais souvent, et non, ce n'est pas un petit Alors peut-être que je fais quelque chose de mal;) Néanmoins, la fusion de Git et Mercurial est supérieure et vous l'avez bien souligné.
John Smithers

11
Dans svn, il est facile de tuer les branches inactives, il suffit de les supprimer. Le fait que les gens ne suppriment pas les branches inutilisées, créant ainsi de l'encombrement, n'est qu'une question de ménage. Vous pouvez tout aussi bien vous retrouver avec de nombreuses succursales temporaires dans Git. Dans mon lieu de travail, nous utilisons un répertoire de niveau supérieur "branches temporaires" en plus des répertoires standard - les branches personnelles et les branches expérimentales y vont au lieu d'encombrer le répertoire des branches où sont conservées les lignes de code "officielles" (nous ne le faisons pas utiliser des branches de fonction).
Ken Liu

10
Cela signifie-t-il alors qu'à partir de la version 1.5, la subversion peut au moins fusionner aussi bien que git?
Sam

29

Historiquement, Subversion n'a pu effectuer une fusion bidirectionnelle que parce qu'elle ne stockait aucune information de fusion. Cela implique de prendre un ensemble de modifications et de les appliquer à un arbre. Même avec les informations de fusion, c'est toujours la stratégie de fusion la plus utilisée.

Git utilise un algorithme de fusion à 3 voies par défaut, ce qui implique de trouver un ancêtre commun aux têtes à fusionner et d'utiliser les connaissances qui existent des deux côtés de la fusion. Cela permet à Git d'être plus intelligent pour éviter les conflits.

Git a également du code de recherche de renommage sophistiqué, qui aide également. Il ne stocke pas les changements ni ne stocke aucune information de suivi - il stocke simplement l'état des fichiers à chaque validation et utilise des heuristiques pour localiser les renommages et les mouvements de code selon les besoins (le stockage sur disque est plus compliqué que cela, mais l'interface il présente à la couche logique n'expose aucun suivi).


4
Avez-vous un exemple que svn a un conflit de fusion mais pas git?
Gqqnbig

17

En termes simples, l'implémentation de la fusion se fait mieux dans Git que dans SVN . Avant la version 1.5, SVN n'enregistrait pas d'action de fusion, il était donc impossible d'effectuer de futures fusions sans l'aide de l'utilisateur qui devait fournir des informations que SVN n'enregistrait pas. Avec la version 1.5, cela s'est amélioré, et le modèle de stockage SVN est légèrement plus performant que le DAG de Git. Mais SVN a stocké les informations de fusion sous une forme plutôt compliquée qui permet aux fusions de prendre beaucoup plus de temps que dans Git - j'ai observé des facteurs de 300 dans le temps d'exécution.

En outre, SVN prétend suivre les renommages pour faciliter la fusion des fichiers déplacés. Mais en réalité, il les stocke toujours en tant que copie et action de suppression distincte, et l'algorithme de fusion bute toujours sur eux dans des situations de modification / renommage, c'est-à-dire, lorsqu'un fichier est modifié sur une branche et renommé sur l'autre, et ces branches sont à fusionner. De telles situations produiront toujours de faux conflits de fusion et, dans le cas de renommages de répertoires, cela entraînera même une perte silencieuse des modifications. (Les personnes SVN ont alors tendance à souligner que les modifications sont toujours dans l'histoire, mais cela n'aide pas beaucoup quand elles ne sont pas dans un résultat de fusion où elles devraient apparaître.

Git, d'autre part, ne suit même pas les renommages, mais les comprend après coup (au moment de la fusion), et le fait de manière assez magique.

La représentation de fusion SVN a également des problèmes; dans 1.5 / 1.6, vous pouviez fusionner de tronc à branche aussi souvent que vous le vouliez, automatiquement, mais une fusion dans l'autre sens devait être annoncée ( --reintegrate), et laissait la branche dans un état inutilisable. Beaucoup plus tard, ils ont découvert que ce n'était pas le cas et que a) le problème --reintegrate pouvait être déterminé automatiquement et b) des fusions répétées dans les deux sens étaient possibles.

Mais après tout cela (qui à mon humble avis montre un manque de compréhension de ce qu'ils font), je serais (OK, je suis) très prudent d'utiliser SVN dans tout scénario de branchement non trivial, et j'essaierais idéalement de voir ce que Git pense de le résultat de la fusion.

D'autres points soulevés dans les réponses, comme la visibilité globale forcée des branches dans SVN, ne sont pas pertinents pour les capacités de fusion (mais pour la convivialité). De plus, les 'Git stocke les changements tandis que les magasins SVN (quelque chose de différent)' sont généralement hors de propos. Git stocke conceptuellement chaque commit dans une arborescence distincte (comme un fichier tar ), puis utilise pas mal d'heuristiques pour le stocker efficacement. Le calcul des modifications entre deux validations est distinct de l'implémentation du stockage. Ce qui est vrai, c'est que Git stocke l'historique DAG sous une forme beaucoup plus simple que SVN fait son mergeinfo. Quiconque essaie de comprendre ce dernier saura ce que je veux dire.

En bref: Git utilise un modèle de données beaucoup plus simple pour stocker les révisions que SVN, et donc il pourrait mettre beaucoup d'énergie dans les algorithmes de fusion réels plutôt que d'essayer de faire face à la représentation => fusion pratiquement meilleure.


11

Une chose qui n'a pas été mentionnée dans les autres réponses, et qui est vraiment un gros avantage d'un DVCS, est que vous pouvez vous engager localement avant de pousser vos modifications. Dans SVN, lorsque j'ai eu quelques modifications, je voulais m'enregistrer, et que quelqu'un avait déjà fait un commit sur la même branche entre-temps, cela signifiait que je devais faire un svn updateavant de pouvoir valider. Cela signifie que mes modifications et les modifications de l'autre personne sont maintenant mélangées et qu'il n'y a aucun moyen d'annuler la fusion (comme avec git resetou hg update -C), car il n'y a pas de validation sur laquelle revenir. Si la fusion n'est pas anodine, cela signifie que vous ne pouvez pas continuer à travailler sur votre fonctionnalité avant d'avoir nettoyé le résultat de la fusion.

Mais alors, ce n'est peut-être qu'un avantage pour les gens qui sont trop stupides pour utiliser des branches distinctes (si je me souviens bien, nous n'avions qu'une seule branche qui était utilisée pour le développement dans l'entreprise où j'ai utilisé SVN).


10

EDIT: Cela répond principalement à cette partie de la question:
est-ce réellement dû à des différences inhérentes au fonctionnement des deux systèmes, ou les implémentations DVCS spécifiques comme Git / Mercurial ont-elles simplement des algorithmes de fusion plus intelligents que SVN?
TL; DR - Ces outils spécifiques ont de meilleurs algorithmes. La distribution présente certains avantages pour le flux de travail, mais elle est orthogonale aux avantages de la fusion.
FIN DE LA MODIFICATION

J'ai lu la réponse acceptée. C'est tout simplement faux.

La fusion de SVN peut être une douleur, mais elle peut également être lourde. Mais, ignorez comment cela fonctionne réellement pendant une minute. Il n'y a aucune information que Git conserve ou peut dériver que SVN ne conserve pas ou ne peut pas dériver. Plus important encore, il n'y a aucune raison pour que la conservation de copies séparées (parfois partielles) du système de contrôle de version vous fournisse des informations plus réelles. Les deux structures sont totalement équivalentes.

Supposons que vous vouliez faire "quelque chose d'intelligent" Git est "meilleur". Et votre chose est enregistrée dans SVN.

Convertissez votre SVN dans le formulaire Git équivalent, faites-le dans Git, puis vérifiez le résultat dans, peut-être en utilisant plusieurs validations, quelques branches supplémentaires. Si vous pouvez imaginer un moyen automatisé de transformer un problème SVN en un problème Git, alors Git n'a aucun avantage fondamental.

À la fin de la journée, tout système de contrôle de version me permettra

1. Generate a set of objects at a given branch/revision.
2. Provide the difference between a parent child branch/revisions.

De plus, pour la fusion, il est également utile (ou critique) de savoir

3. The set of changes have been merged into a given branch/revision.

Mercurial , Git et Subversion (maintenant nativement, utilisant auparavant svnmerge.py) peuvent tous fournir les trois informations. Afin de démontrer quelque chose de fondamentalement meilleur avec DVC, veuillez indiquer un quatrième élément d'information disponible dans Git / Mercurial / DVC non disponible dans SVN / VC centralisé.

Cela ne veut pas dire que ce ne sont pas de meilleurs outils!


1
Oui, j'ai répondu à la question dans les détails, pas dans le titre. svn et git ont accès aux mêmes informations (en fait généralement svn en a plus), donc svn pourrait faire tout ce que git fait. Mais, ils ont pris des décisions de conception différentes, et ce n'est donc pas le cas. La preuve sur le DVC / centralisé est que vous pouvez exécuter git en tant que VC centralisé (peut-être avec certaines règles imposées) et vous pouvez exécuter svn distribué (mais ça craint totalement). Cependant, c'est trop académique pour la plupart des gens - git et hg se ramifient et fusionnent mieux que svn. C'est vraiment ce qui compte lors du choix d'un outil :-).
Peter

5
Jusqu'à la version 1.5, Subversion ne stockait pas toutes les informations nécessaires. Avec le SVN post-1.5, les informations stockées sont différentes: Git stocke tous les parents d'un commit de fusion, tandis que Subversion stocke les révisions déjà fusionnées dans la branche.
Jakub Narębski

4
Un outil difficile à réimplémenter sur un référentiel svn est git merge-base. Avec git, vous pouvez dire "branches a et b divisées à la révision x". Mais svn stocke "les fichiers ont été copiés de foo vers bar", vous devez donc utiliser une heuristique pour déterminer que la copie dans la barre créait une nouvelle branche au lieu de copier des fichiers dans un projet. L'astuce est qu'une révision dans svn est définie par le numéro de révision et le chemin de base. Même s'il est possible de supposer la plupart du temps un «tronc», il mord s'il y a effectivement des branches.
Douglas

2
Re: "Il n'y a aucune information que git conserve ou puisse dériver que svn ne conserve pas ou ne puisse pas dériver." - J'ai trouvé que SVN ne se souvenait pas quand les choses avaient été fusionnées. Si vous aimez tirer du travail du tronc dans votre branche et faire des allers-retours, la fusion peut devenir difficile. Dans Git, chaque nœud de son graphe de révision sait d'où il vient. Il a jusqu'à deux parents et quelques changements locaux. Je ferais confiance à Git pour pouvoir fusionner plus que SVN. Si vous fusionnez dans SVN et supprimez la branche, l'historique de la branche est perdu. Si vous fusionnez dans GIT et supprimez la branche, le graphique reste, et avec lui le plugin "blâme".
Richard Corfield

1
N'est-il pas vrai que git et mercurial ont toutes les informations nécessaires localement, alors que svn doit regarder les données locales et centrales pour dériver les informations?
Warren Dew

8

SVN suit les fichiers tandis que Git suit les changements de contenu . Il est assez intelligent pour suivre un bloc de code qui a été refactorisé d'une classe / fichier à l'autre. Ils utilisent deux approches différentes et complètes pour suivre votre source.

J'utilise toujours beaucoup SVN, mais je suis très satisfait des quelques fois où j'ai utilisé Git.

Une bonne lecture si vous avez le temps: pourquoi j'ai choisi Git


C'est ce que je lis aussi, et c'est ce sur quoi je comptais, mais cela ne fonctionne pas, dans la pratique.
Rolf

Git suit le contenu des fichiers, il
n'affiche

6

Il suffit de lire un article sur le blog de Joel (malheureusement son dernier). Celui-ci concerne Mercurial, mais il parle en fait des avantages des systèmes VC distribués tels que Git.

Avec le contrôle de version distribué, la partie distribuée n'est en fait pas la partie la plus intéressante. La partie intéressante est que ces systèmes pensent en termes de changements, pas en termes de versions.

Lisez l'article ici .


5
C'était l'un des articles auxquels je pensais avant de poster ici. Mais «pense en termes de changements» est un terme très vague de marketing (rappelez-vous que la société de Joel vend des DVCS maintenant)
M. Boy

2
Je pensais aussi que c'était vague ... J'ai toujours pensé que les changesets faisaient partie intégrante des versions (ou plutôt des révisions), ce qui m'étonne que certains programmeurs ne pensent pas en termes de changements.
Spoike

Pour un système qui «pense vraiment en termes de changements», consultez Darcs
Max

@Max: bien sûr, mais quand le push arrive, Git livre où Darcs est fondamentalement aussi douloureux que Subversion quand il s'agit de fusionner.
tripleee

Les trois inconvénients de Git sont a) ce n'est pas si bon pour les binaires comme la gestion de documents où il est très peu probable que les gens veulent se ramifier et fusionner b) il suppose que vous voulez tout cloner c) il stocke même l'historique de tout dans le clone pour les changements fréquents de fichiers binaires provoquant une météorisation des clones. Je pense qu'un VCS centralisé est bien meilleur pour ces cas d'utilisation. Git est bien meilleur pour le développement régulier, en particulier pour la fusion et la ramification.
locka
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.