Notre entreprise utilise actuellement un modèle de branchement simple tronc / version / correctifs et aimerait savoir quels modèles de branchement fonctionnent le mieux pour votre entreprise ou votre processus de développement.
Workflows / modèles de branchement
Voici les trois principales descriptions de ce que j'ai vu, mais elles se contredisent partiellement ou ne vont pas assez loin pour trier les problèmes ultérieurs que nous avons rencontrés (comme décrit ci-dessous). Ainsi, jusqu'à présent, notre équipe ne propose pas de solutions aussi géniales. Faites-vous quelque chose de mieux?
Fusion vs rebasage (enchevêtrement vs historique séquentiel)
Devrait-on
pull --rebase
ou attendre la fusion avec la ligne principale jusqu'à ce que votre tâche soit terminée? Personnellement, je penche pour la fusion car cela préserve une illustration visuelle de la base sur laquelle une tâche a été lancée et terminée, et je préfère mêmemerge --no-ff
à cet effet. Il présente cependant d'autres inconvénients. De plus, beaucoup n'ont pas réalisé la propriété utile de la fusion - qu'elle n'est pas commutative (fusionner une branche de sujet en maître ne signifie pas fusionner maître dans la branche de sujet).Je recherche un workflow naturel
Parfois, des erreurs se produisent parce que nos procédures ne capturent pas une situation spécifique avec des règles simples. Par exemple, un correctif nécessaire pour les versions antérieures devrait bien sûr être basé suffisamment en aval pour pouvoir fusionner en amont dans toutes les branches nécessaires (l'utilisation de ces termes est-elle suffisamment claire?). Cependant, il arrive qu'un correctif arrive dans le maître avant que le développeur ne se rende compte qu'il aurait dû être placé plus en aval, et si cela est déjà poussé (pire encore, fusionné ou quelque chose basé sur lui), l'option restante est la sélection des cerises, avec ses périls associés. Quelles règles simples comme celles-ci utilisez-vous?On y trouve également la maladresse d'une branche de sujet excluant nécessairement les autres branches de sujet (en supposant qu'elles sont ramifiées à partir d'une ligne de base commune). Les développeurs ne veulent pas terminer une fonctionnalité pour en démarrer une autre en ayant l'impression que le code qu'ils viennent d'écrire n'est plus là
Comment éviter de créer des conflits de fusion (à cause de la sélection)?
Ce qui semble être un moyen sûr de créer un conflit de fusion est de choisir entre les branches, elles ne pourront plus jamais être fusionnées? Est-ce que l'application du même commit dans revert (comment faire?) Dans l'une ou l'autre branche pourrait résoudre cette situation? C'est une des raisons pour lesquelles je n'ose pas pousser pour un workflow largement basé sur la fusion.
Comment se décomposer en branches topiques?
Nous nous rendons compte qu'il serait génial d'assembler une intégration terminée à partir de branches de sujet, mais souvent le travail de nos développeurs n'est pas clairement défini (parfois aussi simple que de "fouiner") et si du code est déjà entré dans un sujet "divers", il ne peut plus être retiré de là, selon la question ci-dessus? Comment travaillez-vous pour définir / approuver / graduer / publier vos branches thématiques?
Des procédures appropriées telles que la révision du code et l'obtention du diplôme seraient bien sûr très intéressantes.
Mais nous ne pouvons tout simplement pas garder les choses suffisamment intriquées pour gérer cela - des suggestions? branches d'intégration, illustrations?
Voici une liste de questions connexes:
- Quelles sont les bonnes stratégies pour permettre aux applications déployées d'être hotfixables?
- Description du flux de travail pour l'utilisation de Git pour le développement en interne
- Flux de travail Git pour le développement du noyau Linux d'entreprise
- Comment gérez-vous le code de développement et le code de production? (merci pour ce PDF!)
- git releases management
- Git Cherry-pick vs Merge Workflow
- Comment sélectionner plusieurs commits
- Comment fusionner des fichiers sélectifs avec git-merge?
- Comment choisir une gamme de validations et fusionner dans une autre branche
- Flux de travail ReinH Git
- flux de travail git pour effectuer des modifications que vous ne repousserez jamais à l'origine
- Choisissez une fusion
- Flux de travail Git approprié pour le système d'exploitation et le code privé combinés?
- Gérer le projet avec Git
- Pourquoi ne pouvez-vous pas modifier le fichier de fusion Git avec un parent / maître modifié.
- Bonnes pratiques de branchement / rebasage de Git
- Quand est-ce que "git pull --rebase" me causera des ennuis?
- Comment le DVCS est-il utilisé dans les grandes équipes?
Découvrez également ce que Plastic SCM écrit sur le développement axé sur les tâches , et si Plastic n'est pas votre choix, étudiez le modèle de branchement de nvie et ses scripts de support .
Réponses:
La fonctionnalité la plus troublante que les nouveaux développeurs de DVCS doivent réaliser concerne le processus de publication :
De là, vous pouvez respecter quelques règles pour faciliter vos questions:
Maintenant:
Workflows / modèles de branchement :
chaque flux de travail est là pour prendre en charge un processus de gestion des versions , et qui est adapté à chaque projet.
Ce que je peux ajouter au flux de travail que vous mentionnez est: chaque développeur ne doit pas créer une branche de fonctionnalité, seulement une branche "dev en cours", car la vérité est: le développeur ne sait souvent pas exactement ce que sa branche va produire: un fonctionnalité, plusieurs (car elle a fini par être trop complexe), aucune (car pas prête à temps pour la sortie), une autre fonctionnalité (parce que celle d'origine avait "morphé"), ...
Seul un «intégrateur» doit établir des branches de fonctionnalités officielles sur un référentiel «central», qui peuvent ensuite être récupérées par les développeurs pour rebaser / fusionner la partie de leur travail qui correspond à cette fonctionnalité.
Fusion vs rebasage (enchevêtrement vs historique séquentiel) :
J'aime ma réponse que vous mentionnez (" Description du flux de travail pour l'utilisation de git pour le développement en interne ")
Je recherche un workflow naturel :
pour les correctifs, il peut aider à associer chaque correctif à un ticket provenant d'un suivi des bogues, ce qui aide le développeur à se souvenir où (c'est-à-dire sur quelle branche, c'est-à-dire une branche dédiée "pour les correctifs") il / elle doit commettre de telles modifications.
Ensuite, les hooks peuvent aider à protéger un dépôt central contre les poussées de corrections de bogues non validées ou de branches à partir desquelles il ne faut pas pousser. (pas de solution spécifique ici, tout cela doit être adapté à votre environnement)
Comment éviter de créer des conflits de fusion (à cause de la sélection)?
Comme l'a déclaré Jakub Narębski dans sa réponse , la cueillette devrait être réservée aux rares situations où elle est requise.
Si votre configuration implique beaucoup de sélection de cerises (c'est-à-dire "ce n'est pas rare"), alors quelque chose ne fonctionne pas.
git revert
devrait prendre soin de cela, mais ce n'est pas idéal.Tant qu'une branche n'a pas encore été repoussée partout, un développeur doit réorganiser son historique de commits (une fois qu'il / elle voit enfin que le développement prend une forme plus définitive et stable) en:
Des procédures appropriées comme la révision du code et l'obtention du diplôme?
Le repo des branches d'intégration (dans une intégration dédiée) peut aider le développeur à:
la source
rebase --interactive --autosquash
qui déplaceront automatiquement toutes les validations avec le même début d'un autre message de validation. Si ces validations utilisent un numéro de ticket (par exemple), même si les correctifs liés à ce ticket n'ont pas été effectués de manière séquentielle à ce moment-là, l'autosquash permet une réorganisation rapide de ces validations.Je pense, et je me trompe peut-être, que l'une des choses les plus mal comprises à propos de git est sa nature distribuée. Cela rend très différent de dire la subversion dans la façon dont vous pouvez travailler, bien que vous puissiez imiter le comportement SVN si vous le souhaitez. Le problème est à peu près n'importe quel workflow, ce qui est génial mais aussi trompeur.
Si j'ai une bonne compréhension du développement du noyau (je vais me concentrer là-dessus), tout le monde a son propre dépôt git pour développer le noyau. Il y a un référentiel, linux-2.6.git, géré par Torvalds, qui sert de référentiel de publication. Les gens clonent d'ici s'ils souhaitent commencer à développer une fonctionnalité contre la branche "release".
D'autres référentiels font un peu de développement. L'idée est de cloner à partir de linux-2.6, de se ramifier autant de fois que vous le souhaitez jusqu'à ce que vous ayez une "nouvelle" fonctionnalité fonctionnelle. Ensuite, lorsque cela est prêt, vous pouvez le mettre à la disposition de quelqu'un considéré comme fiable, qui tirera cette branche de votre référentiel dans la leur et la fusionnera dans le courant dominant. Dans le noyau Linux, cela se produit à plusieurs niveaux (lieutenants de confiance) jusqu'à ce qu'il atteigne linux-2.6.git, auquel cas il devient "le noyau".
Voici maintenant où cela devient déroutant. Les noms de branche n'ont pas du tout besoin d'être cohérents entre les référentiels. Je peux donc
git pull origin master:vanilla-code
et obtenir une branche duorigin
maître de dans une branche de mon référentiel appeléevanilla-code
. Pourvu que je sache ce qui se passe, cela n'a pas vraiment d'importance - il est distribué dans le sens où tous les référentiels sont des pairs les uns des autres et pas seulement partagés entre plusieurs ordinateurs comme SVN.Donc, avec tout cela à l'esprit:
head
. Les versions peuvent être des balises ou des branches et les correctifs sont probablement des branches en soi. En fait, je ferais probablement des versions en tant que branches afin que vous puissiez continuer à les patcher.origin
vous devriez, dans votre référentiel, probablement créer une autre branche et fusionner la dernièremaster
enyourbranch
afin que quelqu'un d'autre puisse extraire vos modifications avec le moins d'effort possible. possible. Il y a très rarement un besoin de vraiment rebaser, selon mon expérience.git add .
puisgit commit
.J'espère que ça aide. Je me rends compte que VonC vient de publier une explication très similaire ... Je ne peux pas taper assez vite!
Modifiez quelques réflexions supplémentaires sur la façon d'utiliser git dans un cadre commercial, car cela semble pertinent pour l'OP dans les commentaires:
product.git
, est accessible par un certain nombre de programmeurs / techniciens principaux chargés de s'occuper réellement du produit lui-même. Ils sont analogues au rôle des mainteneurs dans OSS.Que se passe-t-il alors? Eh bien, tout le monde tire au début de chaque journée de la source "en amont", c'est-à-dire le référentiel des versions (qui contiendra également probablement les derniers éléments du développement des jours précédents). Tout le monde le fait directement. Cela ira sur une branche dans leur référentiel, probablement appelé "maître" ou peut-être si vous m'appelez "dernier". Le programmeur fera alors un peu de travail. Ce travail peut être quelque chose dont ils ne sont pas sûrs, alors ils font une branche, font le travail. Si cela ne fonctionne pas, ils peuvent supprimer la branche et revenir en arrière. Si c'est le cas, ils devront fusionner dans la branche principale sur laquelle ils travaillent actuellement. Nous dirons que c'est un programmeur d'interface utilisateur qui travaille
latest-ui
donc il le faitgit checkout latest-ui
suivi pargit merge abc-ui-mywhizzynewfeature
. Il dit ensuite à son responsable technique (le responsable de l'interface utilisateur) hé, j'ai terminé une telle tâche, retirez-vous de moi. C'est donc le cas pour l'interface utilisateurgit pull user-repo lastest-ui:lastest-ui-suchafeature-abc
. Le responsable de l'interface utilisateur le regarde ensuite sur cette branche et dit, en fait, c'est très bien, je vais le fusionnerui-latest
. Il pourrait alors dire à tout le monde en dessous de lui de tirer de lui sur leursui-latest
branches ou quel que soit le nom qu'ils leur ont donné, et ainsi la fonctionnalité est explorée par les développeurs. Si l'équipe est heureuse, le responsable de l'interface utilisateur peut demander au responsable des tests de se retirer de lui et de fusionner les modifications. Cela se propage à tout le monde (en aval du changement) qui le teste et soumet des rapports de bogues, etc. Enfin, si la fonctionnalité réussit les tests, etc., l'un des principaux responsables techniques pourrait la fusionner dans la copie de travail actuelle du programme, à quel moment toutes les modifications sont ensuite propagées vers le bas. Etc.Ce n'est pas une façon de travailler "traditionnelle" et est conçu pour être "piloté par les pairs" plutôt que "hiérarchique" comme SVN / CVS. En substance, tout le monde a un accès commit, mais uniquement localement. C'est l'accès au référentiel et au référentiel que vous désignez comme référentiel de version qui vous permet d'utiliser la hiérarchie.
la source
Un modèle que j'ai utilisé avec de bons résultats est le suivant:
Un dépôt "béni" que tout le monde pousse et tire vers / depuis, essentiellement une topologie client-serveur.
Il n'y a pas de branche principale, donc aucun développeur ne peut pousser de code dans la «ligne principale».
Tous les développements se produisent sur des branches thématiques. Nous avons des noms d'espaces de noms pour détecter facilement qui en est responsable: jn / newFeature ou jn / issue-1234
Il y a aussi un mappage quasi-direct entre les branches et les cartes kanban / scrum sur le tableau blanc.
Pour libérer une branche, elle est poussée vers le dépôt béni et la carte kanban est déplacée pour être prête à être examinée.
Ensuite, si la branche est acceptée par la revue, elle est candidate à une libération.
Une version se produit lorsqu'un ensemble de branches acceptées est fusionné et étiqueté avec un numéro de version.
En poussant la nouvelle étiquette vers le dépôt béni, il y a une nouvelle base possible pour de nouvelles fonctionnalités.
Pour éviter les conflits de fusion, les développeurs sont priés de mettre à jour (fusionner) leurs branches non publiées vers la dernière balise de version.
la source
Personnellement, j'essaie de ne garder que du code prêt à être publié dans la branche master.
Lorsque je travaille sur une nouvelle fonctionnalité ou un nouveau bug, je le fais dans une branche. Je fais aussi des tests unitaires dans la branche. Si tout fonctionne correctement, alors seulement je fusionne / rebase dans le maître.
J'essaie également d'utiliser des conventions de dénomination de branche communes, telles que:
la source