3 votes

Git merge équivalent de git rebase --onto

Je me retrouve souvent dans un flux de travail où je fais ce qui suit :

  • Créer une branche de fonctionnalité ("foo") à partir de notre branche develop ("master")
  • Travailler, travailler, travailler...
  • Soumettre une demande de tirage pour foo
  • En attendant l'approbation, commencer le travail sur une fonctionnalité connexe... :
  • Créer une autre branche de fonctionnalité ("bar") à partir de ma précédente branche foo
  • ...parce que le travail est si étroitement lié que je ne pouvais pas progresser directement depuis develop + je ne peux pas attendre les examens -- ils prennent parfois plus d'une semaine
  • Soumettre une demande de tirage pour bar
  • Obtenir l'approbation pour foo et la fusionner dans develop
  • [nous utilisons des fusions écrasées]
  • Les gens examinent bar, il y a des commentaires, peut-être que bar est déjà approuvé à ce stade
  • Maintenant je rébase bar comme suit :
  • git checkout bar
  • git rebase --onto develop foo
  • git push --force origin bar
  • Obtenir l'approbation pour bar si ce n'est pas déjà approuvé à ce stade, et le fusionner dans develop

Cela fonctionne comme prévu, mais il réécrit l'historique, et est mal vu parce que des personnes ont déjà regardé bar, et il n'y a aucun moyen de savoir vraiment ce que j'ai fait lorsque j'ai effectué un push forcé.

Si j'essaie de fusionner sans rebaser, j'obtiens toutes sortes de conflits de fusion. C'est comme si develop essayait de "annuler" mes changements dans bar.

Ma question est :

Y a-t-il un flux de travail équivalent à git merge pour git rebase --onto ??? Quelque chose comme :

  • git checkout bar
  • git merge ??? develop ??? foo

Y a-t-il un truc comme... peut-être que je fusionne foo de nouveau sur bar, ou un truc en définissant la montée en amont ? Je tâtonne ici...

Merci !

MODIFIER : Une autre chose... même ce processus peut être pénible si j'ai plusieurs validations dans bar. J'ai généralement à fusionner foo dans bar à la fin, donc il n'y a certainement pas de conflits entre eux. Mais il pourrait y avoir un conflit entre une validation précoce de bar et la dernière foo. Alors je dois faire un git rebase -i bar sur bar et l'aplatir en une seule validation avant de faire le git rebase --onto develop foo... Pas génial pour conserver l'historique... parce que maintenant j'aplati les validations de commentaire, et ainsi de suite. Donc parfois j'utilise une autre alternative :

  • git checkout bar
  • git reset foo
  • git add trucs
  • git commit -m "Une validation de l'écart foo-bar"

Encore une fois, crasseux -- tout l'historique des validations de commentaires est perdu...

2voto

VonC Points 414372

Cela fonctionne comme prévu, mais cela réécrit l'historique, et est mal vu car les gens ont déjà regardé bar, et il n'y a aucun moyen de savoir vraiment ce que j'ai fait quand j'ai forcé le push.

GitHub marquerait clairement les commits précédents référencés dans la page PR comme obsolètes, mais vous avez raison : il est compliqué de détecter les changements que vous avez dû apporter lors de votre rebase sur develop avant de forcer le push de bar.

Je considérerais de le pousser en "bar2", et faire un nouveau PR à partir de bar2, avec une référence au PR original de bar.
Cela permettrait à un examinateur de comparer ces deux branches de PR et de déterminer rapidement si quelque chose de significatif a changé entre :

  • le PR original de bar, qui a déjà été approuvé
  • le nouveau PR de bar2, qui doit être rebasé sur develop afin de faciliter sa fusion en PR vers develop.

2voto

Sean Points 283

Voici ce que j'ai choisi de faire...:

git merge -X ours develop

Et puisque git n'est parfois pas très intelligent sur les options qu'il propose lorsqu'il y a un conflit de fusion, j'ai vérifié le résultat avec :

diff <(git diff Foo origin/Bar) <(git diff develop Bar)

Heureusement, je n'avais pas élagué (je le fais rarement). S'il y a une meilleure façon, je suis toujours ouvert à d'autres réponses - je vais laisser cette question sans réponse pour l'instant.

Il serait bien s'il y avait une solution qui préserve l'historique de Bar, ne montre pas l'historique des commits de Foo (comme le fait git rebase --onto), et ne nécessite aucune intervention pour fusionner les commits individuels de Bar lorsqu'ils sont rejoués sur develop... Mais plus j'y pense, je ne suis pas sûr que ce soit théoriquement possible. Donc, je pense que je peux vivre avec les commits superflus de Foo qui sont montrés dans l'historique de Bar. Ce qui précède répond à toutes les autres exigences.

EDIT : Je n'ai pas encore eu l'occasion d'essayer, mais je pense que c'est à cela que sert rerere.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X