Pourquoi ne pas commettre des changements non résolus?


15

Dans un VCS traditionnel, je peux comprendre pourquoi vous ne valideriez pas les fichiers non résolus car vous pourriez casser la construction. Cependant, je ne comprends pas pourquoi vous ne devriez pas valider des fichiers non résolus dans un DVCS (certains d'entre eux vous empêcheront en fait de valider les fichiers).

Au lieu de cela, je pense que votre référentiel doit être verrouillé contre les poussées et les tirages , mais pas dans la validation.

La possibilité de s'engager pendant le processus de fusion présente plusieurs avantages (comme je le vois):

  • Les changements de fusion réels sont dans l'histoire.
  • Si la fusion était très importante, vous pouvez effectuer des validations périodiques.
  • Si vous avez fait une erreur, il serait beaucoup plus facile de revenir en arrière (sans avoir à refaire toute la fusion).
  • Les fichiers peuvent rester marqués comme non résolus jusqu'à ce qu'ils soient marqués comme résolus. Cela empêcherait de pousser / tirer.

Vous pouvez également avoir potentiellement un ensemble de changements comme fusion au lieu d'un seul. Cela vous permettrait d'utiliser toujours des outils tels que git rerere.

Alors, pourquoi commettre avec des fichiers non résolus est-il mal vu / empêché? Y a-t-il une raison autre que la tradition?


1
Par qui est-il mal vu ou empêché?
pdr

@pdr Certains développeurs avec qui j'ai travaillé ont mal vu. Au moins hg 1.6après une fusion, les fichiers sont marqués comme non résolus. hgne pas vous laisser engager jusqu'à ce que vous les avez marqués comme résolu (n'avez - vous signifie pas nécessairement fait pour les résoudre, mais je suppose que l'idée est).
Pilules d'explosion

1
Donc, par «fichiers non résolus», voulez-vous réellement dire «fusions non résolues»?
pdr

@pdr no, hgconserve en fait une liste de fichiers qui ont été ou non marqués comme "résolus" (en utilisanthg resolve ). S'il y a des Ufichiers sur cette liste, cela ne vous laissera pas vous engager.
Pilules d'explosion

1
hg resolveest utilisé spécifiquement pour les fusions avec conflits; voir selenic.com/mercurial/hg.1.html#resolve .Note that Mercurial will not let you commit files with unresolved merge conflicts. You must use hg resolve -m ... before you can commit after a conflicting merge.
Mike Partridge du

Réponses:


6

Le plus gros problème que je peux voir est qu'il crée une fenêtre de commits où les choses sont à moitié fusionnées et (probablement) ne fonctionnent pas correctement. Lorsque vous appuyez sur l'ensemble final de validations locales, toutes ces validations intermédiaires apparaissent également pour tout le monde. Dans un monde idéal, je devrais être capable de tirer n'importe quel commit et le code devrait fonctionner. Si vous commencez à valider au milieu des fusions, l'état du code n'est pas bien défini.

Une chose que vous pourriez faire est de faire des validations locales pour votre fusion, puis de les regrouper en une seule grande validation lorsque vous poussez (bien que je ne sais pas comment (si?) Les vcs prennent en charge cela). Bien que cela puisse produire certains des avantages que vous avez mentionnés, je ne suis pas sûr que cela vaut la complexité supplémentaire (nous avons déjà affaire à un domaine assez confus et complexe).


5
Je ne sais pas si je suis d'accord avec la possibilité de tirer n'importe quel commit et de le faire fonctionner .. la plupart du temps de s'engager dans un DVCS est de valider votre progression , donc les choses sont forcément cassées ou incomplètes la plupart du temps .
Pilules d'explosion

2
Toujours avoir des commits de travail a de beaux avantages. Par exemple, si vous essayez de retrouver le moment où un bogue a été introduit, il est utile de pouvoir parcourir l'historique pour voir quand quelque chose s'est cassé (les vcs ont même des commandes pour faire une recherche binaire sur l'historique). Si vous n'avez pas de commit valide, vous ne pourrez pas suivre les bogues aussi efficacement.
Oleksi

1
Git prend en charge les validations groupées.
deltree

3

Je connais très bien Git, je vais donc répondre pour cette perspective.

Je ne vois pas de raison pour laquelle vous ou tout bon VCS voudriez autoriser la validation d'un fichier non fusionné, en particulier s'il s'agissait de code. Vous devez conserver le référentiel dans un état cohérent, et ce que vous proposez violerait l'atomicité de la validation. De nombreux VCS modifient physiquement le fichier pour montrer où sont les conflits - Git, SVN et CVS utilisent des marqueurs de type >>>> <<<<. Dans un VCS avec des validations et des fusions atomiques au niveau du référentiel, vous auriez simplement créé un nœud qui n'a de sens que pour vous. En développement logiciel, votre projet n'a pas pu être construit. Dans le document d'un groupe, personne ne sait quels changements sont corrects.

Maintenant, Git fournit quelques outils qui pourraient faciliter cela, si le type de validation que vous proposez était autorisé. Par exemple, vous pouvez écraser tous les validations de fusion avant de pousser. Cela se termine comme un commit de fusion typique.

Préoccupations spécifiques concernant votre liste d'avantages:

  1. Les changements de fusion réels sont dans l'histoire. Pourquoi avez-vous besoin d'informations supplémentaires? Les DVCS sont très bons pour limiter les conflits aux zones confinées. Une fois que vous avez choisi l'ensemble de modifications à conserver, la comparaison de la copie du nœud de validation de fusion avec la copie précédente vous donnera exactement cela.
  2. Si la fusion était très importante, vous pouvez effectuer des validations périodiques. C'est une préoccupation valable, mais vous ne devriez jamais arriver ici en premier lieu. Les succursales devraient constamment apporter des changements en amont pour que cela ne se produise jamais. Des outils tels que rebaseou un cerf-volant sur un commit à la fois peuvent également vous aider ici dans certaines situations.
  3. Si vous avez fait une erreur, il serait beaucoup plus facile de revenir en arrière (sans avoir à refaire toute la fusion). Voir ci-dessus - vos conflits ne devraient pas devenir aussi ingérables.

La seule façon dont cette suggestion pourrait fonctionner est si la branche était si la fusion entière était atomique - vous pouviez voir une série de validations, mais ce ne seraient que des étapes dans une plus grande validation de fusion qui devait être traitée comme un nœud dans l'arborescence de validation. . Je ne pense pas qu'un VCS actuel prenne en charge ce type de workflow, et je ne pense pas que ce soit nécessaire.


Les conflits ne devraient probablement pas devenir aussi ingérables, mais le sont souvent (du moins d'après mon expérience). Je pense que toute la fusion devrait être atomique; c'est ce que je propose. Ce n'est peut-être pas nécessaire, je me demande simplement pourquoi cela n'a pas été fait. Vous ne pouvez pas non plus nécessairement choisir l'une ou l'autre option dans un conflit; parfois, c'est une combinaison des deux changements. C'est particulièrement déroutant.
Pilules d'explosion

"Vous devez garder le référentiel dans un état cohérent". Je ne pense pas que ce soit vrai. Un référentiel local est un espace de travail , pas un sanctuaire. Si cela aide à s'engager au milieu d'une fusion, faites-le à mon humble avis. Si vous faites cela parce que vous ne savez pas mieux, je vous suggère de ne pas le faire. Si vous êtes un programmeur expérimenté, cependant, vous devriez faire ce qui vous convient le mieux. Ne soyez pas dogmatique à propos de garder votre référentiel local vierge.
Bryan Oakley

1

Mon expérience principale réside avec Mercurial, bien que j'utilise aussi git de façon sporadique.

Mercurial ne vous interdit pas de valider des fichiers non résolus, il vous décourage simplement . Même chose avec pousser avant de tirer des changements que vous n'avez pas.

Tout ce que vous devez faire dans Mercurial est, une fois que vous avez les fichiers comme vous voulez les valider:

hg resolve --mark --all
hg commit -m "I'm such a rebel"

--mark va ... marquer les fichiers comme résolus sans vous inviter avec l'outil de fusion. --all se chargera de sélectionner tous les fichiers marqués par des conflits.

Si vous voulez pousser sans tirer (et par conséquent avoir à fusionner les autres modifications), faites comme un Jedi :

hg push --force

Le prochain gars qui tire recevra +1 tête (sans jeu de mots)

Je suis sûr qu'il existe un moyen de faire la même chose avec Git (bien que ce soit probablement plus compliqué).


1

Lorsque je fusionne dans git, je valide immédiatement toutes les modifications (y compris les conflits de fusion). Ensuite, dans mes prochains commit (s), je résous les conflits de fusion via un éditeur de texte. Une fois les conflits résolus, je pousse ensuite si vous le souhaitez.

Honnêtement, je ne comprends pas pourquoi les autres ne le font pas de cette façon, ou git ne l'applique pas.

  • Le «commit de fusion» est désormais un historique clair de ce qui devait être fusionné.
  • Les validations suivantes indiquent exactement ce que vous avez fait pour résoudre les conflits de fusion.
  • Lorsque vous poussez, les conflits sont alors résolus et la construction ininterrompue à l'extrémité de la branche.
  • À tout moment, si vous bousillez la résolution du conflit, vous pouvez simplement revenir à l'un des commits "post fusion" et réessayer.

Un énorme inconvénient du flux de travail standard de résolution des conflits avant de valider est que les modifications de votre copie locale peuvent se faufiler. Les ajouts sont cachés de la révision du code par le diff de fusion massive, de sorte que vous ne remarquez pas que vous avez accidentellement validé une API clé ou etc.

Mon flux de travail décrit ci-dessus évite ce problème de copie locale et permet également aux réviseurs de code d'examiner (uniquement) les détails de votre résolution de fusion dans un diff de validation qui ressemble exactement à un diff de validation standard.


0

Je pense qu'il vaut mieux pousser de petits changements et pousser souvent, quand c'est possible (et bien sûr ce n'est pas toujours), et ne pas commettre de code qui ne se construit pas ou qui est à moitié complet (nous faisons tous des erreurs, mais ne ne le faites pas exprès). Je viens également de git, et l'une des meilleures choses que je pense est le fait que vous pouvez avoir une copie réalisable du dépôt sur votre bureau ... que vous pouvez ensuite modifier à votre guise. Lorsque vos gros changements sont terminés, renvoyez-le.

Faire beaucoup d'open source avec git, la plus grande frustration pour moi était de faire du code à moitié fait dans le repo, et d'essayer de faire une construction, mais ne pouvait pas, parce que le gars a fait la moitié du travail et a dit "je suis occupé maintenant , Je vais le finir dans une semaine ". Je finirais donc par devoir le supprimer (ce qui gênerait le gars), ou prendre le temps de le terminer et de l'intégrer complètement.

Je suppose que de mon point de vue, gardez les trucs de demi-cul localement, envoyez les bonnes choses sur le fil.


0

Ne soyez pas esclave de vos outils.

Le but d'un VCS est de vous permettre de faire votre travail. Votre travail n'est pas de conserver un référentiel local vierge, votre travail consiste à écrire du code. Si vous vous engagez tôt et souvent localement vous permet de mieux travailler, faites-le.

Cependant, vous ne devriez pas pousser le code cassé en amont.


0

Parce que fondamentalement, c'est une mauvaise idée - cela vous mènera à un référentiel qui est dans un état précaire (et il est imprudent de supposer que vous pousserez jamais n'importe où, bien que l'on dirait que vous devriez toujours avoir au moins une copie).

Je peux voir que dans le cas d'une fusion importante / complexe, vous voudrez peut-être enregistrer votre travail en cours et établir un point de référence, mais vous laisserez toujours le système dans un état foiré qui doit être résolu.

Et il existe des alternatives - vous avez la possibilité de fusionner plus tôt que la tête - qui pourraient bien vous donner la possibilité de vous adapter aux changements sans fusion épique (ou au moins avec des fusions plus grandes et plus faciles à comprendre).

C'est le cas, je trouve que le rebase de git est particulièrement utile (sous réserve des mises en garde habituelles concernant le rebasage) car vous rejouez vos modifications au-dessus de l'état actuel que vous obtenez pour résoudre les conflits en petits morceaux.

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.