web-dev-qa-db-fra.com

Comment puis-je utiliser git rebase sans nécessiter une poussée forcée?

Dans une tentative pour atteindre le git nirvana, je passe la journée à apprendre à tirer parti de rebase pour les situations où je fusionne actuellement.

Lors de l'exécution de ce que je considère comme un flux git 101 (que j'explique ci-dessous), je dois Push --force lorsque je repousse mes modifications vers l'origine.

Je ne suis pas le seul - je sais que c'est un terrain couvert (voir 1 , 2 , , 4 , 5 ), et je comprends les raisons techniques pourquoi une force est nécessaire. Mon problème est le suivant --- il y a beaucoup (de nombreux) articles de blog chantant les louanges du rebase et comment il a changé leur vie (voir 1 , 2 , , 4 pour en énumérer quelques-uns), mais aucun ne mentionne que Push --force fait partie de leur flux. Cependant, presque toutes les réponses aux questions de stackoverflow existantes disent des choses comme "ouais, si tu vas rebaser, tu dois utiliser Push --force ".

Étant donné le nombre et la religiosité des partisans du rebase, je dois croire que l'utilisation de 'Push --force' n'est pas une partie inhérente d'un flux de rebase, et que si l'on doit souvent forcer ses poussées , ils font quelque chose de mal .

Push --force est un mauvaise chose .

Voici donc mon flux. De quelle manière pourrais-je obtenir les mêmes résultats sans force?

Exemple simple

Deux branches:

  • v1.0 - une branche de publication, ne contient que des correctifs
  • master - tout pour la prochaine version majeure.

J'ai quelques validations de correctifs et quelques validations pour la prochaine version.

premerge

Je voudrais incorporer les correctifs dans mon master afin qu'ils ne soient pas perdus pour la prochaine version. Avant les Lumières, je voudrais simplement:

git checkout master
git merge v1.0

Mais maintenant j'essaye

git checkout master
git rebase v1.0

Alors maintenant je suis là:

enter image description here

Temps pour:

git Push

Pas de dé.

78
Roy Truelove

La recomposition est un excellent outil, mais elle fonctionne mieux lorsque vous l'utilisez pour créer des fusions rapides pour les branches de sujet sur le masque. Par exemple, vous pouvez rebaser votre branche add-new-widget contre master:

git checkout add-new-widget
git rebase -i master

avant d'effectuer une fusion rapide de la branche en maître. Par exemple:

git checkout master
git merge --ff-only add-new-widget

L'avantage de ceci est que votre historique n'aura pas beaucoup de commits de fusion complexes ou de conflits de fusion, car toutes vos modifications seront rebasées sur la pointe du maître avant la fusion. Un avantage secondaire est que vous avez rebasé, mais vous n'avez pas besoin d'utiliser git Push --force parce que vous n'encombrez pas l'historique sur la branche principale.

Ce n'est certainement pas le seul cas d'utilisation pour le rebase ou le seul flux de travail, mais c'est l'une des utilisations les plus sensées que j'ai vues. YMMV.

38
Todd A. Jacobs

@CodeGnome a raison. Vous ne devriez pas rebaser le master sur la branche v1.0 mais la branche v1.0 sur le master, cela fera toute la différence.

git checkout -b integrate_patches v1.0
git rebase master
git checkout master
git merge integrate_patches

Créez une nouvelle branche qui pointe vers la v1.0, déplacez cette nouvelle branche au-dessus du maître, puis intégrez la nouvelle version des correctifs V1.0 à la branche principale. Vous vous retrouverez avec quelque chose comme:

o [master] [integrate_patches] Another patch on v1.0
o A patch on v1.0
o Another change for the next major release
o Working on the next major release
|  o [v1.0] Another path on v1.0
|  o A patch on v1.0
| /
o Time for the release

Cette façon d'utiliser rebase est recommandée par la documentation officielle de git .

Je pense que vous avez raison sur git Push --force: vous ne devez l'utiliser que si vous avez fait une erreur et poussé quelque chose que vous ne vouliez pas.

22
Fabien Quatravaux

Vous devez forcer Push si vous rebase, et vous avez déjà publié vos modifications, non?

J'utilise rebase tout un tas, mais je publie sur quelque chose de privé où une poussée forcée n'a pas d'importance (par exemple: mon propre clone sur GitHub, dans le cadre d'une demande de tirage), ou je rebase avant de pousser pour la première fois.

C'est le cœur du flux de travail où vous utilisez le rebase, mais ne forcez pas trop Push: ne publiez pas les choses avant qu'elles ne soient prêtes, ne rebase pas après avoir poussé.

14
Daniel Pittman

Je pense qu'il y a un bon cas d'utilisation pour ce modèle de rebase-puis-force-Push qui n'est pas le résultat d'un Push erroné: travailler sur une branche de fonctionnalité par vous-même à partir de plusieurs emplacements (ordinateurs). Je le fais souvent, car je travaille parfois au bureau sur mon bureau, et parfois à la maison/sur le site client sur mon ordinateur portable. J'ai besoin de rebaser de temps en temps pour suivre la branche principale et/ou pour rendre les fusions plus propres, mais j'ai également besoin de forcer-Push lorsque je quitte une machine pour aller travailler sur une autre (où je tire juste). Fonctionne comme un charme, tant que je suis le seul à travailler sur la branche.

5
8forty

Voici ce que j'utilise (en supposant que le nom de votre branche est foobar):

git checkout master              # switch to master
git rebase   foobar              # rebase with branch
git merge -s ours Origin/master  # do a basic merge -- but this should be empty
git Push Origin master           # aaand this should work
2
redolent