Voici le scénario qui me gêne un peu.
Jack travaille dans une entreprise de logiciels, Jack est un Programmeur actif , il aime coder et s’engage fréquemment. Paul, le responsable de Jack, lui dit que nous allons commencer à utiliser un nouvel outil de révision de code, le phabricator. Jack se conforme, Jack crée une branche locale et commence à travailler. Il ajoute des fonctionnalités et s'engage très souvent dans sa branche locale. En fin de journée, il envoie une demande de phabricator.
arc diff development
John, membre de l'équipe Jacks, examine son code et accepte ses modifications. Maintenant, Jack ouvre le terminal et passe dans son répertoire de référentiel. Jack tape la commande suivante pour fermer la révision et fusionner son code avec la branche de développement.
arc land --onto development
Il voit le message suivant
Landing current branch 'feature-awesome-features'.
Switched to branch development. Updating branch...
The following commit(s) will be landed:
b2ff76e Added the foo to bar
33f33ba Added a really important check which can destroy the project or save it
31a4c9a Added that new awesome feature
8cae3bf rewrote that awful code john wrote
bc54afb bug fixes
Switched to branch feature-awesome-features. Identifying and merging...
Landing revision 'D1067: Added the awesome feature'...
Rebasing feature-awesome-features onto development
Already up-to-date.
Pushing change...
Maintenant, Jack ouvre Github pour voir son code, sa belle commet. mais ce qu'il voit est une horreur pure, tous ses commets ont été remplacés par un seul commet
Summary: Added the awesome feature
Test Plan: do foo bar testing
Reviewers: John
Reviewed By: John
CC: Paul
Differential Revision: http://phabricator.foobar.com/D1067
Maintenant, Jack est triste, car il veut voir tous ses commits. Jack pense que cela lui donne l'air de The Hoarder qu'il n'est pas. Il veut résoudre ce problème alors il va poser une question sur stackoverflow.
That how may he prevent phabricator from eating his commit history.
Vous devez utiliser le flux git natif tel que git merge
et git Push
directement à la place. De phabricator documentation d'arc :
Une fois les modifications acceptées, vous devez généralement les pousser et fermer La révision. arc a plusieurs workflows qui aident à cela, par:
* squashing or merging changes from a feature branch into a master branch * formatting a good commit message with all the information from Differential * and automatically closing the revision.
Vous n'avez besoin d'aucun de ces workflows: vous pouvez simplement exécuter git Push, hg Push ou svn commit, puis fermer manuellement la révision à partir de Sur le Web.
arc
écrase volontairement vos commits.
la réponse de asherkin explique la raison de ce comportement et explique pourquoi il s'agit du comportement par défaut.
Si vous ne trouvez pas cet argument convaincant, vous pouvez utiliser l'indicateur --merge
pour arc land
afin d'effectuer la fusion --no-ff
au lieu de la fusion --squash
. Ces fusions ne détruiront pas les commits locaux.
Si vous définissez history.immutable
sur true dans votre .arcconfig
, arc land
fusionnera --no-ff
par défaut.
Vous pouvez également utiliser des commandes brutes git
si vous n'aimez pas le comportement de arc land
; il est fourni uniquement pour votre commodité.
Dans votre exemple, nous vous recommandons de créer cinq analyses distinctes - de nombreuses idées différentes sont mises en œuvre. Elles ne sont pas liées et semblent facilement séparables. Voir Écrire un code révisable . Combinaison de corrections de bugs, de changements de style et de nouvelles fonctionnalités en un seul changement is thésaurisation.
Il existe de la documentation qui explique pourquoi il s’agit de la configuration par défaut pour arc land
.
Une stratégie dans laquelle une idée est un engagement ne présente aucun avantage réel par rapport à une autre stratégie tant que votre référentiel n’atteint pas une vitesse critique. En particulier:
- Toutes les opérations sur le référentiel maître/distant concernent essentiellement les idées et non les validations. Quand une idée compte plusieurs commits, tout ce que vous faites est plus compliqué car vous devez déterminer lequel des commets représente une idée ("le widget foo est brisé, de quoi ai-je besoin pour revenir?") Ou quelle idée est finalement représentée par un commit ("commit af3291029 n'a aucun sens, quel objectif ce changement tente-t-il d'accomplir?").
- L'ingénierie de publication est grandement simplifiée. Les ingénieurs de publication peuvent facilement sélectionner ou supprimer des idées lorsque chaque idée correspond à un engagement. Lorsqu'une idée comporte plusieurs commits, il devient plus facile de sélectionner ou de supprimer accidentellement la moitié d'une idée et de se retrouver dans un état qui est pratiquement garanti être faux.
- Les tests automatisés sont grandement simplifiés. Si chaque idée est une validation, vous pouvez exécuter des tests automatisés pour chaque validation et les échecs de test indiquent un problème sérieux. Si chaque idée est composée de plusieurs commits, la plupart de ces commits représentent un état cassé connu de la base de code (par exemple, un point de contrôle avec une erreur de syntaxe qui a été corrigée dans le point de contrôle suivant ou avec une idée à moitié implémentée).
- Comprendre les changements est grandement simplifié. Vous pouvez diviser en deux une pause et identifier toute l’idée de manière triviale, sans avoir à chercher dans le journal pour aller chercher l’extension de l’idée. Et vous pouvez avoir confiance en ce que vous devez revenir pour supprimer toute l'idée.
- Avoir des validations de point de contrôle (certaines d'entre elles sont connues pour être des versions brisées du référentiel) n'a pas de valeur claire et persiste dans le distant. Prenons un VCS théorique qui crée automatiquement une validation de point de contrôle pour chaque frappe. Ce VCS serait évidemment inutilisable. Mais beaucoup de commits de points de contrôle ne sont pas très différents et représentent conceptuellement un point relativement arbitraire dans la séquence de frappes au clavier utilisée pour écrire une idée plus large. Éliminez-les ou créez une couche d'abstraction (fusions) qui vous permet de les ignorer lorsque vous essayez de comprendre le référentiel en termes d'idées (ce qui est presque toujours le cas).
Tout cela ne devient un problème qu’à grande échelle. Chaque jour, Facebook pousse des dizaines d'idées sur des dizaines d'idées, sans pouvoir choisir une stratégie de référentiel où une seule idée est un engagement.
Pour git, la solution recommandée consiste à insérer des branches de fonctionnalités dans l'amont, puis à les fusionner plutôt que de les baser sur le maître - si vous êtes d'accord avec les points ci-dessus mais que vous souhaitez tout de même que votre point de contrôle se valide dans l'amont.
Si cela ne concerne que la révision (comme le dit votre question - mais cela ressemble également à une révision de code ou à une révision de code post-Push avec Audit), notez que Differential affiche déjà tous vos commits locaux avec l'original. message de validation pour le relecteur.
arc land
est conçu pour être utilisé uniquement pour pousser vers la branche "finale" d'un référentiel (c'est-à-dire la production ou une branche représentant les modifications en attente de publication). Si vous effectuez une révision de validation post-Push (c'est-à-dire sur les fusions du développement vers le maître), vous pouvez simplement ignorer arc land
(et il est généralement accepté que vous en avez besoin dans de nombreux cas) et git Push
directement vos modifications.
history.immutable: configure arc pour qu'il utilise des flux de travail qui ne réécrivent jamais l'historique dans la copie de travail. Par défaut, arc procédera à une réécriture de l'historique non publié (modification des messages de validation, fusion de squash) sur certains flux de travail dans Git. Les distinctions sont détaillées ci-dessous.
il suffit donc d'ajouter une ligne dans votre .arcconfig
"history.immutable": true
--merge ne fonctionne pas car il crée un commit de fusion. .