Permettez-moi de répondre à vos points directement et clairement:
Notre problème concerne les branches secondaires à long terme - du genre où vous avez quelques personnes qui travaillent dans une branche qui se sépare de master, nous développons pendant quelques mois et lorsque nous atteignons un jalon, nous synchronisons les deux.
Vous ne voulez généralement pas laisser vos branches non synchronisées pendant des mois.
Votre branche de fonctionnalité a dérivé de quelque chose en fonction de votre flux de travail; appelons-le simplement master
pour des raisons de simplicité. Maintenant, chaque fois que vous vous engagez à maîtriser, vous pouvez et devriez git checkout long_running_feature ; git rebase master
. Cela signifie que vos branches sont, de par leur conception, toujours synchronisées.
git rebase
C'est aussi la bonne chose à faire ici. Ce n'est pas un hack ou quelque chose d'étrange ou de dangereux, mais complètement naturel. Vous perdez une information, qui correspond à "l'anniversaire" de la branche de fonctionnalité, mais c'est tout. Si quelqu'un trouve cela important, vous pouvez le faire en le conservant ailleurs (dans votre système de billetterie ou, si le besoin se fait sentir, dans un git tag
...).
Maintenant, à mon humble avis, la façon naturelle de gérer cela est d’écraser la branche latérale en un seul commit.
Non, vous ne voulez absolument pas cela, vous voulez un commit de fusion. Une validation de fusion est également une "validation unique". En quelque sorte, il n’insère pas tous les commits de branche individuels "dans" le maître. Il s’agit d’un simple commit avec deux parents - le master
chef et le chef de succursale au moment de la fusion.
Assurez-vous de spécifier l' --no-ff
option, bien sûr; la fusion sans --no-ff
devrait, dans votre scénario, être strictement interdite. Malheureusement, ce --no-ff
n'est pas la valeur par défaut; mais je crois qu’il existe une option que vous pouvez définir pour le rendre tel. Voir git help merge
pour quoi --no-ff
fait (en bref: il active le comportement que j'ai décrit dans le paragraphe précédent), il est crucial.
Nous ne sommes pas en train de jeter rétroactivement des mois de développement parallèle dans l'histoire de Master.
Absolument pas - vous ne dormez jamais quelque chose "dans l'historique" d'une branche, surtout pas avec un commit de fusion.
Et si quelqu'un a besoin d'une meilleure résolution de l'histoire de la branche secondaire, eh bien, tout est toujours là - ce n'est tout simplement pas dans le fichier maître, c'est dans la branche latérale.
Avec un commit de fusion, il est toujours là. Pas en maître, mais dans la branche latérale, clairement visible en tant que l’un des parents du groupe fusionné et conservé pour l’éternité, comme il se doit.
Tu vois ce que j'ai fait? Toutes les choses que vous décrivez pour votre commit squash sont exactement là avec le --no-ff
commit de fusion .
Voici le problème: je travaille exclusivement avec la ligne de commande, mais le reste de mon équipe utilise GUIS.
(Remarque: je travaille presque exclusivement avec la ligne de commande également (eh bien, c’est un mensonge, j’utilise habituellement emacs magit, mais c’est une autre histoire - si je ne suis pas dans un endroit pratique avec ma configuration individuelle emacs, je préfère la commande mais faites-vous plaisir et essayez au moins git gui
une fois. C’est tellement plus efficace pour choisir des lignes, des mecs, etc. pour ajouter / annuler des ajouts.)
Et j’ai découvert que les GUIS n’ont pas une option raisonnable pour afficher l’historique des autres branches.
C'est parce que ce que vous essayez de faire est totalement contraire à l'esprit de git
. git
construit à partir du noyau d’un "graphe acyclique dirigé", ce qui signifie que beaucoup d’informations se trouvent dans la relation parent-enfant des commits. Et, pour les fusions, cela signifie de véritables commits de fusion avec deux parents et un enfant. Les interfaces graphiques de vos collègues iront très bien dès que vous utiliserez des no-ff
commits de fusion.
Donc, si vous atteignez un engagement au squash en disant "ce développement est écrasé de la branche XYZ", il est très pénible d'aller voir ce qu'il y a dans XYZ.
Oui, mais ce n’est pas un problème de l’interface graphique, mais du commit squash. L'utilisation d'un squash signifie que vous laissez la tête de la branche fonctionnelle pendante et que vous créez un nouveau commit dans master
. Cela casse la structure à deux niveaux, créant un gros désordre.
Ils veulent donc que ces grandes et longues branches axées sur le développement soient fusionnées, toujours avec un engagement de fusion.
Et ils ont absolument raison. Mais ils ne sont pas « fusionnés dans », ils sont tout simplement fusionnés. Une fusion est une chose vraiment équilibrée, elle n’a aucun côté préféré qui soit fusionné "dans" l’autre ( git checkout A ; git merge B
exactement la même chose que git checkout B ; git merge A
pour les différences visuelles mineures telles que les branches échangées, git log
etc.).
Ils ne veulent pas d’historique qui ne soit pas immédiatement accessible depuis la branche principale.
Ce qui est complètement correct. À une époque où il n’existait aucune fonctionnalité non fusionnée, une seule branche master
avec une histoire riche encapsulait toutes les lignes de validation des fonctionnalités qui existaient, remontant à la git init
validation depuis le début des temps (notez que j’ai évité précisément d’utiliser le terme " branches "dans la dernière partie de ce paragraphe car l'historique à ce moment-là n'est plus" des branches ", bien que le graphe de commit soit assez ramifié).
Je déteste cette idée;
Ensuite, vous souffrez un peu, car vous travaillez contre l’outil que vous utilisez. L' git
approche est très élégante et puissante, en particulier dans le domaine des branches / fusions; si vous le faites correctement (comme mentionné ci-dessus, en particulier avec --no-ff
), c'est par sauts et limites supérieur à d'autres approches (par exemple, le désordre de subversion d'avoir des structures de répertoires parallèles pour les branches).
cela signifie un enchevêtrement sans fin et non navigable dans l’histoire du développement parallèle.
Sans fin, parallèle - oui.
Inavigable, enchevêtrement - non.
Mais je ne vois pas quelle alternative nous avons.
Pourquoi ne pas travailler comme l'inventeur de git
, vos collègues et le reste du monde, tous les jours?
Avons-nous une option ici en dehors de la fusion constante de branches secondaires en maître avec des commits de fusion? Ou bien, y a-t-il une raison pour laquelle l'utilisation constante de fusions par fusion n'est pas aussi mauvaise que je le crains?
Pas d'autres options pas aussi mauvais.