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

Dans le but d’atteindre git nirvana, je passe la journée à apprendre à tirer parti de rebase pour des situations où je fusionnent actuellement.

En parcourant ce que je considère être un stream git 101 (que j’épelle ci-dessous), je dois push --force en repoussant mes modifications à l’origine.

Je ne suis pas le seul – je sais que c’est un terrain couvert (voir 1 , 2 , 3 , 4 , 5 ), et je comprends les raisons techniques pour lesquelles une force est nécessaire. Mon problème est le suivant: il y a beaucoup (beaucoup) d’entrées de blog qui chantent les éloges de rebase et comment cela a changé leur vie (voir 1 , 2 , 3 , 4 pour en énumérer quelques-unes) push --force fait partie de leur stream. Cependant, presque toutes les réponses aux questions existantes sur le stackoverflow indiquent des choses comme “Ouais, si tu veux rebaser, tu dois utiliser push --force “.

Compte tenu du nombre et de la religiosité des défenseurs de la rebase, je dois croire que l’utilisation de «push -force» ne fait pas partie intégrante d’un stream de rebase, et que si l’on doit souvent forcer, on fait quelque chose de mal .

push --force est une mauvaise chose .

Alors voici mon stream. Comment pourrais-je obtenir les mêmes résultats sans force?

Exemple simple

Deux twigs:

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

J’ai quelques commits et quelques commits pour la prochaine version.

prémunir

J’aimerais intégrer les correctifs dans mon master afin qu’ils ne soient pas perdus pour la prochaine version. Pré-illumination 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 ici:

entrer la description de l'image ici

Temps pour:

 git push 

Pas de dé.

Le rebasing est un excellent outil, mais il fonctionne mieux lorsque vous l’utilisez pour créer des fusions rapides dans les twigs de sujets sur le master. Par exemple, vous pouvez rebaser votre twig add-new-widget sur master:

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

avant d’effectuer une fusion rapide de la twig dans master. 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 validations de fusion ou de conflits de fusion complexes, car toutes vos modifications seront converties à la pointe du maître avant la fusion. Un autre avantage est que vous avez rebasé, mais vous n’avez pas à utiliser git push --force parce que vous ne détruisez pas l’historique sur la twig principale.

Ce n’est certainement pas le seul cas d’utilisation de rebase, ou le seul workflow, mais c’est l’une des utilisations les plus judicieuses que j’ai vues. YMMV.

@CodeGnome a raison. Vous ne devez pas rebaser master sur la twig v1.0 mais la twig v1.0 sur master, ce qui 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 twig qui pointe vers la version 1.0, déplacez cette nouvelle twig au-dessus de la version principale, puis intégrez la nouvelle version des correctifs V1.0 à la twig principale. Vous allez vous retrouver 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 devriez l’utiliser que si vous avez fait une erreur et que vous avez poussé quelque chose que vous ne vouliez pas.

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

J’utilise rebase un tas de choses, mais je publie sur quelque chose de privé où une force push n’a pas d’importance (par exemple: mon propre clone sur GitHub, dans le cadre d’une requête pull), ou je rebase avant de lancer pour la première fois.

C’est le cœur du workflow où vous utilisez rebase, mais ne forcez pas beaucoup: ne publiez pas les choses tant qu’elles ne sont pas prêtes, ne les rebase pas après avoir poussé.

Je pense qu’il existe un bon exemple d’utilisation de ce modèle rebase-then-force-push qui ne résulte pas d’un push erroné: travailler par vous-même sur une twig technique à partir de plusieurs emplacements (ordinateurs). Je le fais souvent, car je travaille parfois au bureau sur mon bureau et parfois à partir de mon ordinateur portable. Je dois me rebobiner de temps en temps pour suivre la twig principale et / ou pour rendre les fusions plus propres, mais je dois aussi forcer lorsque je quitte une machine pour aller travailler sur une autre (là où je tire). Fonctionne comme un charme, tant que je suis le seul à travailler sur la twig.

Voici ce que j’utilise (en supposant que votre nom de twig 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