Comment git aide-t-il à gérer le scénario ci-dessous:
J'ai une tâche en deux parties: la tâche principale et la tâche principale. Je fais une demande d'extraction pour fusionner les modifications du backend et j'attends sa fusion (et le retour d'adresse). En attendant, je ne peux pas vraiment travailler sur les modifications du front-end, car cela dépend des modifications apportées au backend et celles-ci ne sont pas encore disponibles sur la branche principale.
Quel est le meilleur moyen d’obtenir les modifications apportées à la branche de modifications frontale à partir de la branche de modifications d’arrière-plan pendant son examen?
Réponses:
J'ai aussi ce problème parfois. Git est très flexible. Voici une façon de le faire.
Votre première branche
featureA
est en révision.Votre deuxième branche
featureB
est en développement et dépend du code de lafeatureA
branche.Fusionner la
featureA
branche dans lafeatureB
branche.Si vous apportez des modifications à la
featureA
branche, vous devez à nouveau la fusionnerfeatureA
dans lafeatureB
branche pour intégrer les modifications.Vous devez également vous assurer de fusionner d'abord
featureA
dans le coffre principal, sinon, lorsque vous fusionnerezfeatureB
dans le coffre principal, vous fusionnerez également par inadvertancefeatureA
. Une fois quefeatureA
vous avez fusionné avec le coffre principal, vous pouvez vous en débarrasserfeatureA
, car celafeatureB
ne dépend plus que du coffre principal.Je le préfère lorsque mes branches de fonctionnalités ne dépendent pas les unes des autres, mais parfois et si vous devez les suivre.
la source
featureA
surfeatureB
si besoin est?featureA
si vous deviez recommencer. Il est bon de penser que les branches Git sont jetables. Ils sont économiques et faciles, vous pouvez toujours créer une nouvelle branche. Vous pouvez même créer une branche test hors de votrefeatureB
branche si vous souhaitez jouer avec quelque chose dont vous n’êtes pas sûr, puis la supprimer si cela ne fonctionne pas ou la fusionner avec votrefeatureB
branche s’il le faisait.Tenez bon, sautez la fusion
Pour cette approche, vous ne pas vouloir fusionner votre
feature_a
enfeature_b
plusieurs reprises.Le remaniement a été mentionné dans d'autres réponses, mais uniquement pour le rebasement
master
. Ce que vous voulez faire dans votre cas, c'est:Commencez votre à
feature_b
partir defeature_a
, à savoir:Chaque fois
feature_a
quemaster
vous changezfeature_b
en attendant d'être fusionné , vous vous basez dessus:Enfin,
feature_a
une fois fusionnémaster
, vous obtenez simplement le nouveaumaster
et vous rebasefeature_a
une dernière fois:Cette dernière rebase va greffer tous les commits qui sont en suspens
feature_a
(ce qui n’est plus pertinent maintenant car il a été fusionnémaster
)master
. Votrefeature_b
est maintenant une simple branche standard allant demaster
.EDIT: inspiré des commentaires, un petit avertissement: si vous devez apporter des modifications qui affectent les deux fonctionnalités, veillez à les intégrer
feature_a
(puis à rebaser comme indiqué). Ne pas le faire dans deux commits différentes dans les deux branches, même si peut être tentant; Comme celafeature_a
fait partie de l’histoire defeature_b
, le fait de changer un seul changement dans deux commits différents sera sémantiquement faux et pourra éventuellement donner lieu à des conflits ou à des "résurrections" de code non désiré, plus tard.la source
feature_a
plusieurs fois, vous risquez par la suite de rencontrer des problèmes,feature_a
même s’il a été refondu entre-temps. À la suite degit checkout feature_b; git rebase feature_a
votre exécution, vous pouvez avoir des conflits ou des commits amusants contenant des commits qui annulent les nouvelles modifications defeature_a
. Cela peut généralement être résolu en utilisant--interactive
et en ignorant les commits pris dans l'ancienne version de l'autre branche (j'ai dû le faire plusieurs fois récemment).rebase
beaucoup plus de démarches individuelles qu’une simplemerge
, il ya sûrement une chance visiblement plus grande de créer des conflits; par contre, ilmerge
serait tout à fait sémantiquement très faux de le faire dans ce cas.merge
aurions des problèmes similaires ou pires (un conflit n’est pas aussi grave que de provoquer un changement indésirable). Je considère une branche comme une séquence de modifications souhaitées précédées de nombreuses modifications indépendantes (appartenant logiquement à une autre branche). Lorsque je modifie à plusieurs reprises avec la même branche, je supprime toujours les modifications non liées car je sais qu'elles entreront de toute façon (éventuellement sous une forme mise à jour) et cela fonctionne bien.git rebase --onto
FTW: DVous avez déjà une branche dont dépend chacune de vos branches principales et qui ne cesse de changer. Ça s'appelle
master
.Pour rester en phase avec une branche de fonctionnalité, le moyen typique
master
est de rester au top . Lorsque desmaster
modifications sont apportées, vous vous trouvez normalementgit fetch origin master:master && git rebase master
dans le répertoire de travail de votre branche.Vous pouvez faire la même chose avec une autre branche de fonctionnalité: continuez à la récupérer et à la rebaser par-dessus.
Si, pour une raison quelconque, vous devez déplacer vos modifications vers une autre branche, vous pouvez sélectionner vos commits, qui ne sont jamais mélangés avec les commits des autres branches.
la source
feature-b
surfeature-a
, et faire un rebase à chaquefeature-a
changement, en fonction de l'évolution. C'est un moyen typique de faire un grand changement observable: divisez-le enpart-A
(basé surmaster
),part-B
(en fonctionpart-A
), et plus si nécessaire. Faites ensuite une demande de tirage pour chaque partie, et les réviseurs auront plus de facilité à regarder des morceaux plus petits et logiquement groupés.Dans le cas où la tâche frontale a une dépendance critique vis-à-vis du code d’arrière-plan et que vous souhaitez commencer à travailler sur ce dernier avant que celui-ci ne soit finalisé et accepté sur le maître, je démarrerais simplement la tâche en tant que branche de fonctionnalité issue du backend branche, plutôt que de brancher le frontend sur le maître.
Une branche de fonctionnalité qui vit assez longtemps doit fusionner de manière occasionnelle dans les modifications apportées au maître (pour vous assurer de concilier tout conflit de fusion ou sémantique dans le cadre du travail de développement de la branche de fonctionnalité, plutôt que dans le cadre de la révision, de la fusion, de la fusion, etc.). à "maîtriser"). Donc, vous le faites sur votre branche front-end, et lorsque le travail d’arrière-plan a été accepté, vous obtiendrez toutes les modifications mineures qui ont été apportées au back-end dans le cadre de son examen / acceptation automatiquement, par le même itinéraire que celui que vous aviez. obtenir tout autre changement de code sur le maître.
S'il s'avère que la branche dorsale a besoin de beaucoup plus de travail et qu'elle continue à changer sur une période de temps avant d' être fusionnée pour maîtriser (par exemple, si des problèmes majeurs sont détectés lors de la révision), vous voudrez probablement effectuer directement des fusions périodiques. de la branche dorsale à la branche frontale (afin que vous ne continuiez pas à baser tout votre travail frontal sur du code backend obsolète). C'est facile si vous êtes le seul développeur à utiliser les deux fonctionnalités (puisque vous savez si vous apportez vous-même des modifications majeures), mais même si les deux fonctionnalités finissent par être utilisées en parallèle par différents développeurs, tout devrait bien se passer. vous devez simplement rester en communication (ce dont vous auriez besoin de toute façon, si vous travaillez sur des tâches en parallèle où l'une a une dépendance critique à l'autre).
S'il s'avère que toute la branche dorsale doit être abandonnée et ne sera jamais fusionnée (il semblerait que ce serait un accord assez important qui se produirait rarement), vous pouvez alors sélectionner vos modifications dans une nouvelle branche à venir du maître sans le travail d'arrière-plan, ou vous appliquez des validations inverses qui suppriment tout le code d’arrière-plan de la branche frontale. Mais comme je peux le voir, il serait plus probable de suspendre le travail en amont jusqu'à ce que vous sachiez ce qui allait remplacer le backend que vous jetez, puis que vous décidiez quoi faire.
la source
Je ne vois pas le problème ici.
Vous en avez déjà à chaque fois avec votre
master
branche, qui change continuellement pendant que les fonctionnalités sont développées puis fusionnées.Ainsi, dans votre exemple concret, vous créez d'abord la
feature_xxx_backend
branche et développez les modifications d’arrière-plan. Lorsque cela est fait, la branche est prête à réviser et sera fusionnéemaster
une fois la révision terminée.Alors, commencez simplement une autre branche,
feature_yyy_frontend
. Vous voudrez probablementfeature_xxx_backend
créer une branche directement à partir de , pour que ces modifications soient déjà dans votre branche. Ensuite, développez simplement la fonctionnalité frontend comme si la branche l’étaitmaster
.Lorsque la
feature_xxx_backend
branche change, par exemple parce qu’il faut tenir compte de certains points soulevés lors de la révision, faites simplement ces modifications et fusionnez-les dans lafeature_yyy_frontend
branche. Continuez ensuite sur la branche frontale.Une fois la révision de la branche principale terminée, elle est fusionnée
master
. À ce stade, il serait sage de rebaser lafeature_yyy_frontend
branche surmaster
, de sorte que les réviseurs n’aient besoin que d’examiner les nouvelles modifications apportées par cette branchemaster
, sans avoir à réexaminer les modifications apportées au backend (qui ont déjà été approuvées). )Cela peut également être fait lorsque vous avez deux, trois ou plusieurs branches dépendantes. Si vous comptez sur deux branches d’entités sur lesquelles vous dépendez, créez simplement une branche dérivée dans laquelle les deux entités sont fusionnées. À partir de là, développez la troisième entité, puis fusionnez les deux en même temps. Lorsque les deux fonctionnalités sont terminées et fusionnées dans la branche dérivée, reposez-vous dessus, ou si elles sont fusionnées dans maître, rebasez-les sur maître.
Le changement de base (comme suggéré ci-dessus) est très puissant et permet de garder un journal clair des modifications, ce qui facilite les révisions.
la source
Comme Polygnome l'a mentionné, vous pouvez fusionner votre branche frontale avec votre branche backend au lieu des maîtres. Même avec la configuration actuelle de votre branche, vous pouvez simplement faire:
ou simplement
Gardez toutefois à l'esprit que si les modifications apportées au back-end ne sont pas acceptées et que davantage de travail est nécessaire, vous devrez fusionner les mises à jour depuis le back-end dans l'interface pour éviter les conflits. Une fois les modifications acceptées dans le maître, vous pouvez redéfinir votre interface sur le maître pour supprimer les commits de fusion d’arrière-plan.
Techniquement, vous pouvez également tout faire avec rebase, mais cela gâchera l’historique des validations de votre branche frontale. D'où je viens, c'est considéré comme une mauvaise pratique. YMMV
la source
La plupart des réponses ici décrivent correctement le processus de fusion des modifications de la deuxième branche à la première, mais elles n'indiquent pas comment réduire au minimum le nombre de conflits que vous devrez peut-être résoudre.
Lorsque vous souhaitez examiner individuellement deux ensembles de modifications importantes (comme
featureA
etfeatureB
), créez un PR qui ne doit PAS être fusionné, mais pour recueillir les premières réactions sur une PoC defeatureA
.Les gens pourront l'examiner rapidement (il ne s'agit que d'une PoC) et l'objectif est de valider la conception ou l'approche générale.
Ensuite, vous pouvez continuer à travailler sur la fonctionnalité A, créer une demande d'extraction pour celle-ci, créer une branche et travailler sur la fonctionnalité B.
La grande différence est que maintenant vous pouvez vous attendre
featureA
à ne pas changer radicalement: la conception et l'approche ont déjà été validées. La révision du code et les modifications requises peuvent être subtiles et locales plutôt qu’un «woops, vous avez besoin d’une approche différente». Cela réduira la quantité de travail que vous devez faire pour plus tard fusionnerfeatureB
lefeatureA
« code s, quelle que soit la méthode que vous avez choisi.la source