web-dev-qa-db-fra.com

Schéma de workflow git approprié avec plusieurs développeurs travaillant sur la même tâche

Je suis chef d'équipe dans notre société de développement Web et j'aimerais implémenter le flux de travail Git dans notre équipe. En lisant la documentation et les articles, j'ai trouvé la structure suivante bonne pour nous:

Nous avons un référentiel dans un Bitbucket. Master la branche est considérée comme contenant uniquement du code stable. Chaque développeur doit créer sa propre branche et implémenter des fonctionnalités/corrections de bugs dans sa branche propre. Une fois qu'il décide que son code est prêt, il crée un historique de branche Nice (utilisant rebase, amende, cherry-pick etc.) et le pousse vers Bitbucket, où crée une demande de pull vers la branche master. Le contrôle qualité vérifie les fonctionnalités et les approuve (ou les désapprouve), puis je vérifie le code et si cela est correct, je fusionne son travail dans master (en avance rapide ou en rebasant pour un meilleur historique des validations).

Mais ce schéma n'est bon que dans un cas où un seul développeur travaille sur une branche. Dans notre cas, nous avons presque toujours deux développeurs pour une branche, puisqu'un développeur travaille sur côté serveur (PHP), et un autre - côté client (HTML/CSS/JS). Comment ces deux devraient collaborer en quelque sorte, que l'historique de validation dans master reste propre?

Le développement du serveur crée une structure de base des fichiers HTML et le développement du client doit obtenir cette structure. Logiquement, le serveur dev créerait une branche et le client dev créerait sa propre branche, basée sur la branche serveur dev. Mais cela signifie que le serveur dev doit publier sa branche dans Bitbucket, ce qui rendra impossible pour lui rebaser ou modifier les commits déjà publiés.

Une autre option consiste à attendre que le développeur du serveur termine son travail, publie une branche avec Nice valide l'historique et l'oublie, et seulement après que le développeur du client commence à travailler dans cette branche, mais cela entraînera des retards, ce qui est encore pire.

Comment gérez-vous une telle collaboration dans vos workflows?

41
Viktor Livakivskyi

Je ne peux pas vraiment parler des mérites des méthodes décrites dans votre article, mais je peux décrire comment nous avons résolu le codage collaboratif dans le flux de travail que nous utilisons au travail.

Le flux de travail que nous utilisons est l'une des nombreuses branches. Notre structure est donc:

Le maître est doré; seul le fusion master le touche (plus à ce sujet dans un peu).

Il y a une branche de développement, prise initialement par master, sur laquelle tous les développeurs fonctionnent. Au lieu d'avoir une branche par développeur, nous créons des fonctionnalités ou des tickets à partir de dev.

Pour chaque fonctionnalité discrète (bug, amélioration, etc.), une nouvelle branche locale est créée à partir de dev. Les développeurs n'ont pas à travailler sur la même branche, car chaque branche de fonctionnalité est limitée à ce sur quoi travaille ce développeur unique. C'est là que la branche bon marché de git est utile.

Une fois que la fonctionnalité est prête, elle est fusionnée localement en dev et poussée vers le cloud (Bitbucket, Github, etc.). Tout le monde reste synchronisé en tirant souvent sur les développeurs.

Nous sommes sur un calendrier de publication hebdomadaire, donc chaque semaine, après que QA a approuvé la branche de développement, une branche de publication est créée avec la date dans le nom. C'est la branche utilisée dans la production, remplaçant la branche de sortie de la semaine dernière.

Une fois que la branche de version est vérifiée par QA en production, la branche de version est fusionnée à nouveau dans master (et dev, juste pour être sûr). C'est la seule fois où nous touchons le maître, en veillant à ce qu'il soit aussi propre que possible.

Cela fonctionne bien pour nous avec une équipe de 12. J'espère que cela a été utile. Bonne chance!

58
bronzehedwick

Nous avons un référentiel principal et chaque développeur en a une fourchette.

Une branche est créée principal/some_project, le même nom de branche est ensuite créé sur chaque fork des développeurs, fork/some_project.

(Nous utilisons smartgit et nous avons également une politique selon laquelle les télécommandes sont nommées "principal" et "fork" plutôt que "Origin" et "upstream", ce qui ne fait que confondre les nouveaux utilisateurs).

Chaque développeur possède également une branche locale nommée some_project.

La branche locale du développeur some_project suit le principal de la branche distante/some_project.

Les développeurs font leur travail local sur la branche some_project et Push-to vers leur fork/some_project, de temps en temps ils créent des requêtes pull, c'est ainsi que le travail de chaque développeur est fusionné dans principal/some_project.

De cette façon, les développeurs sont libres de tirer/rebaser localement et de pousser vers leurs fourches - c'est à peu près le flux de travail de fourche standard. De cette façon, ils obtiennent les validations des autres développeurs et peuvent de temps en temps devoir résoudre le conflit étrange.

C'est très bien et tout ce qui est nécessaire maintenant est un moyen de fusionner les mises à jour en cours qui apparaissent dans principal/master (par exemple des correctifs urgents ou d'autres projets qui sont livrés avant la fin de some_project).

Pour y parvenir, nous désignons un "responsable de branche" dont le rôle est de fusionner localement les mises à jour du maître dans un_projet à l'aide de la fusion (pas de pull, rebase) dans SmartGit. Cela aussi peut parfois générer des conflits et ceux-ci doivent être résolus. Une fois cela fait, le développeur (le responsable de la branche) pousse la force vers sa branche fork/some_project, puis crée une demande d'extraction pour fusionner dans principal/some_project.

Une fois cette demande d'extraction fusionnée, toutes les nouvelles validations qui étaient sur principal/master sont maintenant présentes sur la branche principal/some_project (et rien n'a été rebasé).

Par conséquent, la prochaine fois que chaque développeur est sur some_project et tire (rappelez-vous, leur branche suivie est principal/some_project), ils obtiendront toutes les mises à jour qui incluront les éléments fusionnés de principal/master.

Cela peut sembler long mais c'est en fait assez simple et robuste (chaque développeur peut également fusionner localement à partir du principal/maître, mais c'est plus propre si une personne le fait, le reste de l'équipe vit dans un monde simple un peu comme le flux de travail d'un développeur unique) .

5
Hugh

Je pense que personne n'a encore répondu à la question initiale de savoir comment collaborer dans les branches thématiques en maintenant une histoire propre.

La bonne réponse est désolé, vous ne pouvez pas avoir tout cela ensemble. Vous ne pouvez améliorer votre historique local privé qu'après avoir publié quelque chose pour les autres, vous devez travailler en plus.

Le mieux que vous puissiez faire dans votre cas particulier où le développement du serveur ne se soucie pas des changements de développement du client est de dériver localement les branches clientes de celles de développement/fonctionnalité et de rebaser cette partie au-dessus du travail du serveur juste avant de terminer la fonctionnalité - ou assouplissez vos contraintes et passez à un autre workflow, comme vous l'avez fait;)

5
Diego V
3
saket

ce qui ne lui permettra pas de rebaser ou de modifier les commits déjà publiés.

Cela dépend de votre public. "Dev serveur" peut pousser la "structure de base" vers Bitbucket pour que "client dev" y ait accès. Oui, cela signifie potentiellement que d'autres auront accès à ces commits "temporaires".

Cependant, cela ne serait un problème que si un autre utilisateur se connectait à l'une de ces validations avant d'être rebasé. Sur un projet plus petit/une base d'utilisateurs plus petite, ces validations temporaires pourraient ne jamais être remarquées avant même le rebase, annulant ainsi le risque.

La décision vous appartient si le risque de dérivation de quelqu'un de ces validations temporaires est trop grand. Si c'est le cas, vous devrez peut-être créer un deuxième référentiel Bitbucket privé pour ces modifications privées. Une autre option serait de faire fusionner les commits au lieu de rebaser, mais ce n'est pas non plus idéal.

2
Steven Penny

Permettez-moi de vous dire ce que nous faisons ici pendant que plusieurs développeurs travaillent sur le même projet (travaillant même parfois sur les mêmes contrôleurs/modèles/vues).

Tout d'abord, notre chef d'équipe a créé git-project avec deux branches

  1. Maître (il est protégé, personne ne peut pousser ici sauf le chef d'équipe)
  2. Développement (tous les développeurs peuvent pousser ici)

Ils nous ont dit de travailler sur notre environnement local et de créer des commits chaque fois que nous terminions l'une des tâches assignées.

Maintenant, le soir (ou disons heure de fermeture - départ), nous faisons ceci:

  1. Git Pull

Tous les développeurs qui travaillent sur le même projet Tirez la branche de développement actuelle vers leur section locale (faites de même le matin - en commençant pour la journée).

Ensuite, le chef d'équipe a dit au développeur de valider tous les codes et de pousser un par un suivi d'un tirage.

Par exemple.

  • dev1 crée un commit et envoie au serveur
  • dev2 tire à nouveau et crée un commit et Push
  • dev3 tire à nouveau et crée un commit et Push
  • etc..

Maintenant, le problème est les conflits:

  • Parfois, en tirant le code de la branche de développement, git notifie que nous avons fusionné tous les conflits automatiquement --- cela signifie que git a automatiquement appliqué les nouvelles modifications apportées par un autre développeur
  • Mais parfois, le MEME git indique que la fusion automatique a échoué et affiche certains noms de fichiers
  • puis le rôle de chef d'équipe entre en scène - ce qu'il fait est: "Il examine tous les fichiers répertoriés (pendant le processus d'échec de la fusion automatique) et fusionne les conflits manuellement et crée une validation et une transmission au serveur.

Maintenant, comment fusionner manuellement: GIT met simplement à jour les fichiers de conflit avec tout le contenu comme ceci:

<<< HEAD
New lines from server that you don't have is here shown
=====
Your current changes....
>>> [commit id]

Le chef d'équipe met à jour ce fichier après avoir analysé ceci:

 New lines from server that you don't have is here shown
 Your current changes

et crée commit et Push.

Encore une fois le matin, nous tirons (juste pour nous assurer que nous n'avons rien oublié de la veille), c'est ainsi que nous travaillons ici.

2
Mohan Sharma

Les règles à retenir sont:

  • Avoir 1 master et 1 develop branche
  • Faire en sorte que les branches de fonctionnalité apparaissent à partir de la branche develop
  • Chaque fois que vous avez une version prête pour [~ # ~] qa [~ # ~] à tester, fusionnez dans develop
  • Faire en sorte que les branches de publication apparaissent à partir de la branche develop
  • Faire des corrections de bugs dans les branches de publication
  • Lorsque vous avez une version prête pour [~ # ~] qa [~ # ~] à tester, fusionnez dans develop
  • Lorsque vous avez une version prête pour [~ # ~] production [~ # ~] , fusionnez dans master et créez une balise pour il

Le diagramme suivant est la stratégie de l'oeil de boeuf suivie dans les équipes à travers le monde (Crédit: tiré de ici ):

enter image description here

2
Nirav Bhatt

Pour la question exacte, plusieurs développeurs sur la même tâche, la réponse courte est que la tâche est effectuée dans une branche d'intégration pour cette tâche. Cette branche "tâche" est traitée comme les branches "maître" ou "dev" dans les flux de travail Git habituels (comme la plupart des réponses fournies ici). Cette branche d'intégration est traitée dans le "flux de travail de la branche de fonctionnalités Git" élaboré ailleurs.

Cette branche de tâches est l'endroit où les développeurs travaillant sur ce code de partage de tâches à l'aide des commandes Git normales.

Exemple

Pour développer le nouvel écran de démarrage, le développeur principal (ou quelqu'un) ne

git co master
git co -b feature-splash
git Push Origin feature-splash

Chaque développeur travaillant sur cette fonctionnalité:

git co master
git pull
git co feature-splash
git co -b my-feature-splash  // they can name their branch whatever

Désormais, chaque développeur se développera sur sa branche et créera des demandes de tirage vers des fusions sur la fonctionnalité-splash sur le serveur de dépôt Git central comme GitHub. Tout comme pour la branche sacro-sainte "maître".

Une fois la fonction terminée, la fonction-splash est fusionnée dans master. Bien sûr, cette fonctionnalité doit être mise à jour avec un nouveau code sur le maître. Le splash de fonctionnalité pourrait-il utiliser le rebasage sur le maître?

Ce n'est pas mon idée originale. J'ai lu à ce sujet à divers endroits. Notez que dans de nombreux articles de workflow, cette branche spécifique à une tâche n'est pas vraiment un concept. Par exemple, dans un article, nous avons "Les branches de fonctionnalités n'existent généralement que dans les dépôts de développeurs, pas dans Origin." Peut-être qu'une tâche qui nécessite plus d'un développeur est toujours décomposée en sous-tâches? Je suppose que si vous connaissez l'avenir et savez ce qui est requis.

1
Josef.B