Question

Ma question porte sur la façon dont les branches gère Git: chaque fois que vous branche d'engager, cette branche ne recevra pas toujours des changements de la branche mère, sauf si vous la force avec une fusion <. / p>

Mais dans d'autres systèmes tels nous Clearcase ou AccuRev, vous pouvez spécifier la façon dont les branches se remplissent de une sorte de mécanisme d'héritage : Je veux dire, avec Clearcase, en utilisant un config_spec, vous pouvez dire « obtenir tous les fichiers modifiés sur la branche / main / issue001 puis continuer avec ceux sur / principal ou avec cette ligne de base spécifique ».

Dans AccuRev vous avez également un mécanisme similaire qui flux de changements permettent de recevoir de branches supérieures (cours d'eau comment ils les appellent) sans la fusion ou la création d'une nouvelle COMMIT la branche.

Ne regrettez-vous pas cela en utilisant Git? Pouvez-vous énumérer les scénarios dans lesquels cette héritage est un must?

Merci

Mise à jour S'il vous plaît lire ci-dessous pour répondre VonC concentrer effectivement ma question. Une fois que nous sommes d'accord « stockage linéaire » et DAG ont différentes en fonction des ajouts cimentaires capacités, ma question est: qui sont les scénarios de la vie réelle (en particulier pour les entreprises de plus de logiciels libres) où linéaire peut faire des choses pas possible pour DAG? Sont-ils la peine?

Était-ce utile?

La solution

Pour comprendre pourquoi Git ne propose pas une sorte de ce que vous faites référence comme un « mécanisme d'héritage » (ne comportant pas un commettras), vous devez d'abord comprendre l'un des core de ces ajouts cimentaires (Git vs. ClearCase par exemple)

  • ClearCase utilise un stockage linéaire version : chaque version d'un élément (fichier ou répertoire) est lié d'une manière directe linear relation avec la version précédente de le même élément.

  • Git utilise un DAG - graphe acyclique orienté : chaque « version » d'un fichier est en fait partie d'un ensemble global de changements dans un arbre qui est lui-même partie d'un engagement. La version précédente de ce doit être trouvée dans un commettras précédent, accessible par un chemin de graphe orienté acyclique.

Dans un système linéaire, une spécification de configuration peut spécifier plusieurs règles pour atteindre le « héritage » que vous voyez (pour un fichier donné, sélectionnez d'abord une certaine version, sinon présente, puis sélectionnez une autre version, et si pas présent, puis sélectionnez un troisième, et ainsi de suite).

La branche est une dans un linear l'histoire une version donnée pour une règle de sélection donnée (toutes les autres règles de sélection avant que l'on applique encore, d'où l'effet « héritage »)

Dans un DAG, un commit représente tout le « héritage » que vous aurez jamais obtenir; il n'y a pas de sélection « cumulatif » des versions. Il n'y a qu'un seul chemin dans ce graphique pour sélectionner tous les fichiers que vous verrez à ce moment précis (commit).
Une branche est juste un nouveau chemin dans ce graphique.

Pour appliquer, dans Git, d'autres versions, vous devez soit:

Mais puisque Git est un SCM basé DAG, il sera toujours le résultat dans un commit.

Ce que vous « perdre » avec Git est une sorte de « composition » (lorsque vous sélectionnez différentes versions avec différentes règles de sélection successives), mais ce ne serait pas pratique dans un D VCS ( comme dans « distribué »): lorsque vous faites une branche avec Git, vous devez le faire avec un point de départ et un contenu clairement définis et facilement être dupliquée à d'autres référentiels

.

Dans un VCS purement central, vous pouvez définir votre espace de travail (dans ClearCase, votre « vue », que ce soit instantané ou dynamique) avec toutes les règles que vous voulez.


inconnu-google ajoute dans le commentaire (et dans sa question ci-dessus):

  

Alors, une fois que nous voyons les deux modèles peuvent réaliser des choses différentes (linéaire vs DAG), ma question est: quels sont les véritables scénarios de vie (en particulier pour les entreprises de plus de logiciels libres) où linéaire peut faire des choses pas possible pour DAG? Sont-ils la peine?

En ce qui concerne « le scénario de la vie réelle » en terme de règles de sélection, ce que vous pouvez faire dans un modèle linéaire est d'avoir plusieurs règles de sélection pour le même ensemble de fichiers .

Considérez ceci ( "spécification de configuration" à-dire des règles de sélection avec ClearCase) "spécification de configuration":

element /aPath/... aLabel3 -mkbranch myNewBranch
element /aPath/... aLabel2 -mkbranch myNewBranch

Il sélectionne tous les fichiers étiquetés « aLabel2 » (et la branche à partir de là), à l'exception de ceux portant la mention « aLabel3 » - et la branche à partir de là - (parce que la règle précède ee une mention 'aLabel2').

Est-il utile?

Non.

En fait, la saveur UCM de ClearCase (le « Configuration unifiée gestion » méthodologie inclus avec le produit ClearCase, et représentant toutes les « meilleures pratiques » déduites de l'utilisation ClearCase de base) ne permet pas, pour des raisons de simplificity . Un ensemble de fichiers est appelé un « composant », et si vous voulez branche pour une étiquette donnée (dite « de référence »), qui serait traduit comme cette spécification de configuration suivante:

element /aPath/... .../myNewBranch
element /aPath/... aLabel3 -mkbranch myNewBranch
element /aPath/... /main/0 -mkbranch myNewBranch

Vous devez choisir un point de départ (ici, 'aLabel3') et aller de là. Si vous souhaitez également les fichiers de « aLabel2 », vous allez faire une fusion de tous les fichiers « aLabel2 » à ceux de « myNewBranch ».

C'est une « simplification » vous ne pas faire avec un DAG, où chaque noeud du graphe représente un « point de départ » définie de manière unique pour une branche, quel que soit l'ensemble des fichiers.

Fusionner et rebasage suffisent à combiner ce point de départ avec d'autres versions d'un ensemble de fichiers, afin d'obtenir la « composition » souhaitée, tout en gardant cette histoire particulière dans l'isolement dans une branche .

L'objectif général est de raisonner en " cohérente opérations de contrôle Version appliquée à une cohérente composante". Un ensemble « cohérent » de fichiers est un dans un état cohérent bien défini:

  • si marqué, tous les fichiers sont étiquetés
  • si ramifiés, tous ses fichiers ramifier à partir du point de départ même uniques

Ce fait facilement dans un système de DAG; il peut être plus difficile dans un système linéaire (en particulier avec « Base ClearCase » où la « spécification de configuration » peut être difficile), mais elle est appliquée avec la méthode UCM de ce même outil linéaire.

Au lieu de réaliser que la « composition » par un « truc privé règle de sélection » (avec ClearCase, une règle de sélection commande), vous obtenez seulement des opérations VCS (rebasage ou de fusion), qui laissent une trace claire pour tout le monde à suivre (par opposition à une spécification de configuration privée à un développeur, ou partagé entre certains, mais pas tous les développeurs). Encore une fois, il applique un sens de cohérence , par opposition à une « flexibilité dynamique », que vous pouvez avoir un moment difficile à reproduire plus tard .

Cela vous permet de quitter le royaume de VCS (Version Control System) et entrez dans la domaine de la SCM (gestion de configuration logicielle) de , qui est principalement concerné par « reproductibilité ». Et que (caractéristiques SCM) peuvent être obtenus avec une base linéaire ou d'un VCS à base DAG.

Autres conseils

Il ressemble à ce que vous cherchez peut-être git rebase . Rebasage une branche sur laquelle elle se détache sur le plan conceptuel de son point de branche d'origine et il reconnecte à un autre point. (En réalité, le rebasage est mis en œuvre par l'application de chaque parcelle de la branche en séquence au nouveau point de branchement, la création d'une nouvelle série de patches.) Dans votre exemple, vous pouvez changer la base d'une branche à l'extrémité actuelle d'une branche supérieure, qui sera essentiellement « hériter » de toutes les modifications apportées à l'autre branche.

Je ne suis pas tout à fait clair sur ce que votre demande pour mais il semble que ce connard la sémantique de suivi sont ce que vous voulez. Lorsque vous branche d'origine am vous pouvez faire quelque chose comme:

git -t -b my_branch origine / de maître

Et puis l'avenir « git pull » s seront automatiquement fusion origine / maître dans votre branche de travail. Vous pouvez ensuite utiliser « l'origine de la cerise git / maître » pour voir quelle est la différence. Vous pouvez utiliser « rebasage git » avant de publier votre changements pour nettoyer l'histoire, mais vous ne devriez pas utiliser rebasage fois votre histoire est publique (à savoir d'autres personnes suivent cette branche).

En ce qui concerne le système d'héritage utilisé par AccuRev: les utilisateurs git probablement « obtenir » la chose quand le regard sur git-débit (voir aussi: http://github.com/nvie/gitflow et http://jeffkreeftmeijer.com/2010/why-arent- vous-utilisant-git flux / )

Ce modèle de branchement GIT plus ou moins fait (manuellement / avec l'aide de l'outil flux git) ce AccuRev fait hors de la boîte automatique et avec grande Prise en charge de l'interface graphique.

il semble GIT peut faire ce que AccuRev fait. Depuis que je ne ai utilisé git / git-flux au jour le jour, je ne peux pas vraiment dire comment ça marche, mais il ne semble prometteur. (Moins bon support GUI: -)

Je vais essayer de répondre à la question que vous. (Je dois dire ici que je ne l'ai pas utilisé GIT lu seulement, donc si quelque chose que je mentionne ci-dessous est faux, s'il vous plaît me corriger)

"Pouvez-vous énumérer les scénarios dans lesquels cet héritage est un must?"

Je ne vais pas dire qu'il est un must, parce que vous pouvez résoudre un problème avec l'outil que vous avez, et peut-être une solution valable pour votre environnement. Je suppose qu'il est plus une question de processus que l'outil lui-même. Veiller à ce que votre processus est cohérent et vous permet également de revenir en arrière dans le temps pour reproduire toute étape / état intermédiaire est l'objectif et le plus est que l'outil vous permet d'exécuter vos processus et SCMP aussi indolore que possible

Le seul scénario que je peux voir, il est utile d'avoir cette « héritage » comportement et utiliser la puissance de la spécification de configuration, est quand vous voulez que votre ensemble de modifications « isolé » mis en correspondance avec une tâche (devtask, CR, SR, ou tout autre définit le but / la portée de votre jeu de changement)

En utilisant cette composition vous permet d'avoir votre propre et toujours branche de développement utiliser différentes combinaisons (composition à l'aide) du reste du code, et encore que ce qui est pertinent pour la tâche isolé dans un branche au cours de la ensemble cycle de vie de la tâche, jusqu'à ce que la phase d'intégration.

Être puriste avoir à engager / fusion / rebasage juste pour avoir un « point de départ défini », je suppose que ce serait « pollue votre branche et vous finirez vos modifications + autres changements dans votre ensemble branche / de changement.

Quand / Où cet isolement est utile? Les points ci-dessous pourraient ne font sens le contexte des sociétés poursuivant des CMM et des certifications ISO, et peut-être d'aucun intérêt pour d'autres types de sociétés ou OSS

  • Être vraiment pointilleux, vous voudrez peut-être compter avec précision les lignes de code (ajouté / modifié / supprimé) du jeu de changement correspondant à un seul développeur, plus tard utilisé comme une entrée pour les estimations de code et d'effort.

  • Il peut être plus facile à examiner le code à différentes étapes, juste après avoir votre code dans une seule branche (non collée avec d'autres modifications)

Sur les grands projets avec plusieurs équipes et +500 développeurs simultanément travaillent activement sur le même code de base, (où les arbres de la version d'élément individuel graphique ressemble à un écheveau désordonné avec plusieurs lignes de charge, un pour chaque gros client, ou un pour chaque technologie ) grandes spécifications de configuration en utilisant la composition de plusieurs degrés en profondeur fait cette quantité de personnes travaillent de façon transparente pour adapter le même produit / système (code de base) à des fins différentes. En utilisant cette spécification de configuration, a donné dynamiquement chaque équipe ou une équipe sous un point de vue différent de ce dont ils ont besoin et d'où ils ont besoin de branche de (en cascade sur plusieurs cas) sans qu'il soit nécessaire de créer des branches d'intégration intermédiaires, ou la fusion en permanence et rebasage tous les bits que vous avez besoin pour commencer. Code de la même tâche / but a été essaimer des étiquettes différentes, mais avait un sens. (Vous pouvez souligner ici les « référence connu » comme principe de l'Accord SMC, mais les étiquettes simples prévu dans un plan SMC écrit que le travail réalisé) Il doit être possible de le résoudre avec le GIT (je suppose que d'une manière non dynamique) mais je trouve vraiment difficile d'imaginer sans ce comportement « d'héritage ». Je suppose que le point mentionné par VonC « si ramifiés, tous ses fichiers branche du même point de départ unique » a été cassé, mais à côté de lui a été bien documenté sur le SCMP, je me souviens qu'il y avait de fortes raisons d'affaires pour le faire de cette façon.

Oui la construction de ces spécifications de configuration que je l'ai mentionné ci-dessus était pas libre, au début là où 4-5 personnes bien payées derrière le SCM, mais ont été réduits plus tard par des scripts automatisés que vous avez demandé ce que vous voulez des conditions d'étiquettes / branches / caractéristiques et écriront le CS pour vous.

La reproductibilité ici a été réalisée en enregistrant simplement la configuration Spec ainsi la tâche dans lasystème devTask, de sorte que chaque tâche en amont mis en correspondance avec les besoins, et en aval mis en correspondance avec une spécification de configuration, un un ensemble de modifications (fichiers de code, les documents de conception, documents de test, etc)

jusqu'à ici une conclusion ici est peut-être, que si votre projet est grand / assez compliqué (et vous pouvez vous permettre les gestionnaires de SC le long de la vie du projet :)) alors vous ne commencer à penser si vous avez besoin « héritage «comportement ou un outil vraiment polyvalent, sinon vous allez directement à aa outil qui est gratuit et déjà prendre soin de la cohérence de vous SCM ... mais il pourrait y avoir d'autres facteurs sur l'outil SMC qui pourrait vous faire coller à l'un ou à l'autre ... lire la suite ..

Quelques notes secondaires, qui pourraient être hors de sujet, mais je pense que dans certains cas comme le mien doivent être pris en considération.

Je dois ajouter que nous utilisons le « bon-ol CC » non UCM. Totalement d'accord avec VonC sur le une bonne méthode permet de « guider » la flexibilité vers une configuration plus cohérente . La bonne chose est que CC est assez flexible et vous pouvez trouver (non sans un certain effort) une bonne façon d'avoir chose cohérente tandis que dans d'autres SCM vous pourriez avoir gratuitement. Mais par exemple ici (et d'autres endroits que j'ai travaillé avec CC) pour les projets C / C ++, nous ne pouvons pas payer le prix de ne pas avoir la Winkin fonction (réutilisation des objets Derive), qui réduisent plusieurs X fois le temps de compilation. On peut faire valoir que d'avoir une meilleure conception, un code plus découplées et l'optimisation de Makefile peut réduire la nécessité de compiler le tout, mais il y a des cas que vous devez compiler toute bête plusieurs fois par jour, et le partage de la DO sauve des tas de temps / argent. Là où je suis maintenant, nous essayons d'utiliser autant outil gratuit que nous pouvons, et je pense que nous allons nous débarrasser de CC si nous pouvons trouver un outil moins cher ou gratuit qui met en œuvre le Winkin fonction.

Je vais finir avec quelque chose que Paul mentionne, différents outils sont mieux que d'autres à des fins différentes mais je vais ajouter que vous pouvez échapper à une certaine limitation de l'outil en ayant un processus cohérent et sans reproductibilité scarification, les points clés de l'Accord SMC En fin de compte, je suppose que la réponse à il vaut la peine? dépend de votre « problème », le SDLC vous exécutez, vos processus SCM, et s'il y a une fonctionnalité supplémentaire (comme Winkin) qui pourraient être utile dans votre environnement.

mes 2 cents

La théorie de côté, voici une sorte de prendre pratique évidente à ce sujet, de mon point de vue en utilisant AccuRev dans un environnement de production commerciale depuis plusieurs années: Le modèle d'héritage fonctionne très bien aussi longtemps que les flux d'enfants ne sont pas divergé trop de ancêtres qui sont encore en développement. Il se décompose lorsque les cours d'eau héritant sont trop différents.

L'héritage (versions ultérieures que les enfants des paiements antérieurs) permet des changements dans l'ancêtre des cours d'eau d'être actifs dans les flux enfant sans que personne ne rien faire (sauf si une fusion est nécessaire, dans ce cas, il apparaît aussi profond recouvrement, ce qui est bon d'être capable de voir).

Cela sonne bien, et dans la pratique, il est, lorsque tous les cours d'eau concernés sont relativement similaires. Nous utilisons ce modèle pour les flux au niveau du pack correctif et de service ci-dessous une version de production donné. (C'est en fait un peu plus compliqué que ça pour nous, mais c'est l'idée générale.)

Communiqués de production sont en parallèle, pas d'héritage, avec ces correctifs et service pack enfants de moins de chacun d'eux. Démarrage d'une nouvelle version signifie la création d'un nouveau flux de niveau de sortie, et en poussant manuellement tout le plus récent flux de maintenance pour la libération avant en elle. Après cela, les modifications aux versions antérieures applicables à ceux qui doivent être plus tard poussé manuellement dans chacun d'eux, ce qui nécessite plus de travail, mais qui permet un contrôle beaucoup plus.

Nous avons utilisé à l'origine du modèle d'héritage pour toutes les versions, où les enfants étaient plus tard des précédentes. Cela a bien fonctionné pendant un certain temps, mais nous avons eu ingérable au fil du temps. différences architecturales à travers les principaux communiqués diffusés héritant inéluctablement des changements d'une mauvaise idée. Oui, vous pouvez mettre un instantané entre l'héritage de bloc, mais tous les changements doivent être poussés manuellement, et la seule différence réelle entre les cours d'eau instantané parent-enfant et parallèle non-héritant est que l'ensemble de vue flux graphique pousse sans cesse vers le bas et à droite, qui est un PITA.

Une seule chose vraiment bien AccuRev est que vous avez ce choix, tout le temps. Ce n'est pas une contrainte inhérente à l'architecture de votre programme SMC.

Avez-vous remarqué que vous pouvez checkout versions de fichiers specfific avec GIT aussi?

Il suffit d'utiliser ceci:

git checkout [< tree-ish >] [--] < paths >

Comme par config spec une version existante d'un fichier (chemins) peuvent être chargés dans le worktree. Citation de docs-git checkout:

La séquence suivante vérifie la branche principale, revient à l'Makefile deux révisions en arrière, supprime hello.c par erreur, et il revient de l'index:

$ git checkout master             
$ git checkout master~2 Makefile             
$ rm -f hello.c            
$ git checkout hello.c            

ClearCase, sans multisite, est un référentiel unique, mais Git est distribué. ClearCase engage au niveau du fichier, mais commit Git au niveau du référentiel. (Cette dernière différence signifie que la question initiale est basée sur un malentendu, comme l'a souligné dans les autres postes ici.)

Si ce sont les différences dont nous parlons alors je pense que « linéaire » versus « DAG » est une manière confuse de distinguer ces systèmes SCM. Dans ClearCase toutes les versions d'un fichier sont appelés version « arbre » du fichier, mais vraiment il est un graphe orienté acyclique! La vraie différence à Git est que les DAG de ClearCase existent par fichier. Je pense donc qu'il est trompeur de se référer à ClearCase comme non-DAG et Git comme DAG.

(BTW Clearcase versions de ses répertoires d'une manière similaire à ses fichiers -. Mais c'est une autre histoire)

Je ne sais pas si vous demandez quoi que ce soit, mais vous démontrez que les flux AccuRev sont différents outils que les branches Git (ou SVN). (Je ne sais pas Clearcase.)

Par exemple, avec AccuRev vous êtes forcé , comme vous le dites, d'utiliser certains flux de travail, ce qui vous donne un historique auditable des changements qui ne sont pas pris en charge dans Git. L'héritage de AccuRev rend certains flux de travail plus efficace et d'autres impossibles.

Avec Git vous pouvez avoir d'exploration de codage ségrégation dans le repo local ou dans les branches de fonction, qui ne serait pas pris en charge très bien par AccuRev.

Différents outils sont bons pour des fins différentes; il est utile de demander à ce que chacun est bon pour .

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top