Je connais certaines personnes qui utilisent git pull --rebase
par défaut et d'autres qui insistent pour ne jamais l'utiliser. Je crois que je comprends la différence entre fusionner et rebaser, mais j'essaie de mettre cela dans le contexte de git pull
. S'agit-il simplement de ne pas vouloir voir beaucoup de messages de validation de fusion, ou y a-t-il d'autres problèmes?
806
Réponses:
Vous devez utiliser
git pull --rebase
lorsqueEn effet - pourquoi pas alors? C'est plus clair et n'impose pas de regroupement logique à vos commits.
Ok, je suppose qu'il a besoin de quelques éclaircissements. Dans Git, comme vous le savez probablement, vous êtes encouragé à créer des succursales et à fusionner. Votre branche locale, dans laquelle vous tirez les modifications, et la branche distante sont, en fait, des branches différentes, et il
git pull
s'agit de les fusionner. C'est raisonnable, car vous ne poussez pas très souvent et accumulez généralement un certain nombre de modifications avant qu'elles ne constituent une fonctionnalité terminée.Cependant, parfois - pour quelque raison que ce soit - vous pensez qu'il serait en fait préférable que ces deux - distant et local - soient une seule branche. Comme dans SVN. C'est ici
git pull --rebase
qu'intervient le jeu. Vous ne fusionnez plus - vous vous engagez réellement au-dessus de la branche distante . C'est de cela qu'il s'agit réellement.Que ce soit dangereux ou non est la question de savoir si vous traitez les succursales locales et distantes comme une chose inséparable. Parfois, c'est raisonnable (lorsque vos modifications sont petites, ou si vous êtes au début d'un développement robuste, lorsque des modifications importantes sont apportées par de petits commits). Parfois, ce n'est pas le cas (lorsque vous créez normalement une autre branche, mais que vous êtes trop paresseux pour le faire). Mais c'est une question différente.
la source
git config --global pull.rebase preserve
(préserver dit en plus d'activer le rebasage, pour essayer de conserver les fusions si vous en avez fait localement).Je voudrais apporter une perspective différente sur ce que signifie réellement «git pull --rebase», car il semble parfois se perdre.
Si vous avez déjà utilisé Subversion (ou CVS), vous pouvez être habitué au comportement de "svn update". Si vous avez des modifications à valider et que la validation échoue parce que des modifications ont été apportées en amont, vous "mettez à jour svn". Subversion procède en fusionnant les modifications en amont avec les vôtres, ce qui peut entraîner des conflits.
Ce que Subversion vient de faire, c'était essentiellement du «pull --rebase». Le fait de reformuler vos modifications locales pour qu'elles soient relatives à la version la plus récente en est la partie "rebasage". Si vous aviez fait "svn diff" avant la tentative de validation échouée et comparez le diff résultant avec la sortie de "svn diff" après, la différence entre les deux diff est ce que l'opération de rebasage a fait.
La différence majeure entre Git et Subversion dans ce cas est que dans Subversion, "vos" modifications n'existent qu'en tant que modifications non validées dans votre copie de travail, tandis que dans Git vous avez des validations réelles localement. En d'autres termes, dans Git, vous avez bifurqué l'histoire; votre histoire et l'histoire en amont ont divergé, mais vous avez un ancêtre commun.
À mon avis, dans le cas normal d'avoir votre branche locale reflète simplement la branche en amont et en faire un développement continu sur elle, la bonne chose à faire est toujours « --rebase », parce que c'est ce que vous sémantiquement réellement faites . Vous et d'autres piratez l'histoire linéaire voulue d'une branche. Le fait que quelqu'un d'autre ait poussé légèrement avant votre tentative de poussée n'est pas pertinent, et il semble contre-productif que chaque accident de ce type entraîne des fusions dans l'histoire.
Si vous ressentez réellement le besoin que quelque chose soit une succursale pour une raison quelconque, c'est une préoccupation différente à mon avis. Mais à moins que vous n'ayez un désir spécifique et actif de représenter vos modifications sous la forme d'une fusion, le comportement par défaut devrait, à mon avis, être "git pull --rebase".
Veuillez considérer d'autres personnes qui ont besoin d'observer et de comprendre l'histoire de votre projet. Voulez-vous que l'histoire soit jonchée de centaines de fusions partout, ou voulez-vous seulement les quelques fusions sélectionnées qui représentent de véritables fusions d'efforts de développement divergents intentionnels?
la source
git config --global branch.autosetupmerge always
?Peut-être que la meilleure façon de l'expliquer est avec un exemple:
git checkout master && git pull
. Le Maître est déjà à jour.git checkout master && git pull
. Le Maître est déjà à jour.git merge topic-branch-A
git merge topic-branch-B
git push origin master
avant Alicegit push origin master
, ce qui est rejeté car il ne s'agit pas d'une fusion rapide.git pull --rebase origin master
git push origin master
, et tout le monde est heureux de ne pas avoir à lire un commit de fusion inutile lorsqu'ils consulteront les journaux à l'avenir.Notez que la branche spécifique fusionnée n'est pas pertinente pour l'exemple. Dans cet exemple, Master pourrait tout aussi bien être une branche de publication ou une branche de développement. Le point clé est qu'Alice & Bob fusionnent simultanément leurs branches locales en une branche distante partagée.
la source
git co master && git pull; git checkout topic-branch-A; git rebase master; git checkout master; git merge topic-branch-A; git push origin master
répéter si la poussée d'un autre à maîtriser s'est produite avant la mienne. Bien que je puisse voir les avantages succincts de votre recette.Je pense que vous devriez utiliser
git pull --rebase
lorsque vous collaborez avec d'autres sur la même branche. Vous êtes dans votre travail → validation → travail → cycle de validation, et lorsque vous décidez de pousser votre travail, votre poussée est rejetée, car il y a eu un travail parallèle sur la même branche. À ce stade, je fais toujours unpull --rebase
. Je n'utilise pas de squash (pour aplatir les commits), mais je rebase pour éviter les commits de fusion supplémentaires.Au fur et à mesure que votre connaissance de Git augmente, vous vous retrouvez beaucoup plus dans l'histoire qu'avec n'importe quel autre système de contrôle de version que j'ai utilisé. Si vous avez une tonne de petits commits de fusion, il est facile de perdre de vue la vue d'ensemble qui se passe dans votre histoire.
C'est en fait la seule fois où je rebase (*), et le reste de mon flux de travail est basé sur la fusion. Mais aussi longtemps que vos committers les plus fréquents le font, l'histoire semble bien meilleure à la fin.
(*) Pendant que j'enseignais un cours Git, un étudiant m'a arrêté à ce sujet, car j'ai également préconisé le rebasage des branches de fonctionnalités dans certaines circonstances. Et il avait lu cette réponse;) Un tel changement de base est également possible, mais il doit toujours être conforme à un système pré-arrangé / convenu, et en tant que tel ne devrait pas "toujours" être appliqué. Et à ce moment-là, je ne fais généralement pas non
pull --rebase
plus, ce qui est la question;)la source
Je ne pense pas qu'il y ait jamais de raison de ne pas utiliser
pull --rebase
- j'ai ajouté du code à Git spécifiquement pour permettre à magit pull
commande de toujours rebaser contre les commits en amont.Lorsque vous parcourez l'histoire, il n'est tout simplement jamais intéressant de savoir quand le gars / la fille travaillant sur la fonctionnalité s'est arrêté pour se synchroniser. Cela pourrait être utile pour le gars / la fille pendant qu'il / elle le fait, mais c'est pour ça
reflog
. C'est juste ajouter du bruit pour tout le monde.la source
pull --rebase
doit toujours être utilisé, pourquoi ne lepull
fait-il pas par défaut?.gitconfig
pour que certaines des options fassent ce qu'il faut. Je pense que git rebase fait la mauvaise chose par défaut, tout comme git tag, etc ... Si vous n'êtes pas d'accord, vous n'avez pas besoin de justifier votre opinion.master
, et si la branche dans laquelle vous vous arrêtez n'est pas encore devenue publique. Si vous tirez d'autre part d'une branche de fonctionnalité dansmaster
c'est plus comme l'inverse: il n'y a jamais de raison d'utiliser--rebase
, non? C'est peut-être la raison pour laquelle ce n'est pas par défaut. J'ai trouvé que les rebases sont la façon dont les changements doivent passer du haut de la hiérarchie vers le bas et les fusions sont la façon dont ils remontent. derekgourlay.com/blog/git-when-to-merge-vs-when-to-rebaseRappelez-vous juste:
Alors, choisissez la façon dont vous voulez gérer votre branche.
Vous feriez mieux de connaître la différence entre fusionner et rebaser :)
la source
Je pense que cela se résume à une préférence personnelle.
Voulez-vous cacher vos erreurs idiotes avant de pousser vos changements? Si oui,
git pull --rebase
c'est parfait. Il vous permet de compresser ultérieurement vos commits en quelques (ou un) commits. Si vous avez fusionné dans votre historique (non poussé), il n'est pas si facile d'en faire ungit rebase
plus tard.Personnellement, cela ne me dérange pas de publier toutes mes erreurs stupides, j'ai donc tendance à fusionner au lieu de rebaser.
la source
git pull --rebase
peut masquer la réécriture d'un historique à un collaborateurgit push --force
. Je recommande de n'utilisergit pull --rebase
que si vous savez que vous avez oublié de pousser vos commits avant que quelqu'un d'autre ne fasse de même.Si vous n'avez rien commis, mais votre espace de travail n'est pas propre, juste
git stash
avantgit pull
. De cette façon, vous ne réécrivez pas en silence votre historique (ce qui pourrait supprimer en silence une partie de votre travail).la source