Le git «Golden Rule of Rebasing» est-il si essentiel?

22

J'ai eu une discussion récemment avec des gens absolument opposés à une stratégie de rebase des branches de fonctionnalités sur GIT. Cela semble être un modèle accepté d'utiliser uniquement le rebasage pour les branches locales et privées, mais ne l'utilisez jamais lorsqu'il y a plusieurs personnes travaillant sur une même fonctionnalité et branche, selon cette soi-disant "règle d'or de la refondation" (comme expliqué ici: https : //www.atlassian.com/git/tutorials/merging-vs-rebasing/conceptual-overview )

Je suis juste surpris qu'il y ait un consensus à ce sujet. J'ai travaillé 3 ans avec une stratégie de rebasage complète, avec environ 20 développeurs travaillant ensemble et devinez quoi, cela a fonctionné.

Le processus est essentiellement:

  • Vous créez votre branche de fonctionnalité, appelons-la "myfeature" et poussez-la vers origin / myfeature
  • D'autres personnes peuvent le vérifier et y travailler
  • Vous pouvez parfois le rebaser depuis master: depuis "myfeature", git rebase origin / master ; et puis, oui, vous devez pousser la force.
  • Que se passe-t-il lorsque d'autres personnes veulent pousser leurs commits? Ils le rebasent simplement: git rebase origin / myfeature . Ils sont donc maintenant en avance rapide et peuvent le pousser sans forcer.

Le seul principe à respecter est que la branche de fonctionnalité appartient à quelqu'un . Le propriétaire est le seul à pouvoir pousser.

Donc, j'avoue: dès qu'il y a une force de poussée, il y a un risque de faire des erreurs. C'est vrai. Mais il y a aussi de nombreuses façons de se remettre des erreurs, et vraiment, en 3 ans de développement, je n'ai pas vu beaucoup d'erreurs poussant la force, et quand cela se produisait, nous avons toujours trouvé un moyen de récupérer correctement.

Alors, pourquoi cette "règle d'or du rebase" est-elle si largement acceptée? Y a-t-il autre chose que j'ai manqué avec ça? Je comprends que cela nécessite un minimum d'organisation (chaque stratégie nécessite une certaine organisation), mais cela fonctionne.

Joel
la source
Quelque chose que j'ai oublié de dire, mais cela a son importance: dans mon expérience précédente, nous utilisions gerrit comme outil de révision de code. Cela signifie que si quelqu'un pousse un commit pendant que le propriétaire de la branche effectue un rebase, il n'y a aucun risque que le commit soit perdu, car il est poussé à gerrit au lieu de directement dans le référentiel d'origine. Et comme le propriétaire de la succursale est le seul à pouvoir soumettre des commits de gerrit, le risque de faire des erreurs était très faible.
Joel
que faire si je fusionne la branche de fonctionnalité de quelqu'un d'autre dans la mienne?
Winston Ewert
Si votre fonctionnalité dépend d'une autre, je suppose que vous pouvez rebaser la vôtre de l'autre: git rebase origin / otherFeature (je dis rebaser plutôt que fusionner, car le but est de garder l'historique linéaire). J'avoue que la complexité de tout cela augmente beaucoup lorsque l'on introduit de plus en plus de dépendances entre branches.
Joel

Réponses:

10

Le problème avec la poussée forcée ne concerne pas votre branche de fonctionnalité et votre maître, mais le fait de pousser votre maître vers le maître de quelqu'un d'autre - cette synchronisation va écraser leur maître avec vos modifications, ignorant tout ce qui est sur leur astuce.

Compte tenu de ce danger, il y a une raison pour laquelle vous ne devriez pas l'utiliser du tout, sauf si les choses ont mal tourné et que vous devez absolument, totalement l'utiliser pour effectuer des réparations. Un système SCM ne devrait jamais avoir besoin d'être forcé comme ça, s'il le fait parce que quelque chose a horriblement mal tourné (et ma première approche dans de tels cas serait de restaurer les sauvegardes et de répéter les opérations pour garder l'historique intact).

Alors peut-être que la question est: pourquoi rebasez-vous du tout? Pour une histoire `` propre '' lors du retour des fonctionnalités au maître? Si oui, vous jetez toute la bonne histoire concernant la ramification pour des raisons purement de style. La fusion rapide à mon humble avis n'est pas non plus une meilleure pratique non plus, vous devriez garder toute l'histoire afin de pouvoir voir ce que vous avez vraiment fait, pas une version aseptisée par la suite.

gbjbaanb
la source
Vous pouvez, bien sûr, tirer sur maître, rebaser, puis forcer, mais ce n'est pas atomique.
Kevin
@gbjbaanb vous avez tout à fait raison, la stratégie de rebasage est une question de style / d'histoire plus lisible. Je n'essaie pas de dire que c'est mieux ou non. Mais c'est possible, et c'est le point que je veux soulever. Bien sûr, je ne parlais pas de forcer le maître, mais seulement sur les branches de fonctionnalités.
Joel
4
À mon humble avis, la fonction de conception des rebases et des fusions rapides était une erreur. SCM consiste à conserver l'historique afin que vous puissiez voir ce qui s'est passé lorsque vous en avez besoin et prendre des instantanés pour les points pertinents dans le temps. Du moins, c'est ce que la plupart des gens veulent, je suppose que Linus voulait que l'histoire soit aussi simple à lire que possible et donc à les mettre à son profit. À mon humble avis, il aurait dû mettre plus d'efforts pour rendre les différences entre 2 révisions plus gérables à la place (c'est-à-dire permettre à la vue d'être plus simple, pas à l'historique sous-jacent)
gbjbaanb
2
Lorsque vous publiez un article, publiez-vous le premier projet? Existe-t-il une loi qui stipule que les outils que vous utilisez pour rédiger le premier projet ne peuvent pas être utilisés pour le modifier en vue de sa publication? Git est un outil de développement. Si vous souhaitez préserver de manière fiable et vérifiable une série, conservez-la. Si vous souhaitez plutôt le modifier pour publication, modifiez-le. Git est stellaire dans les deux tâches.
2017
5

Le rebase n'est pas essentiel, car vous dites que c'est principalement cosmétique. Parfois, c'est beaucoup plus simple qu'une fusion. Il peut donc avoir une valeur "réelle", mais seulement "parfois"

Une mauvaise utilisation de rebase peut être coûteuse. Il est peu probable que vous perdiez des données si vous en savez assez pour ne pas paniquer et rechercher les procédures de récupération, mais "hé personne ne pousse pendant un certain temps, je dois réparer ..." n'est pas génial. Il n'y a pas non plus de temps à consacrer à la récupération et aux tests de recherche alors qu'il aurait pu ajouter des fonctionnalités ou éliminer des bugs (ou rentrer chez lui en famille).

Avec ce compromis, les résultats de "très peu de gens font un rebase et une poussée forcée" ne sont pas très surprenants.

Certains workflows peuvent réduire le risque, par exemple le réduire à «zéro tant que vous vous souvenez des branches que vous êtes autorisé à forcer et que vous ne pouvez pas». En réalité, ils peuvent être suffisamment sûrs pour justifier le risque, mais les gens font souvent des choix basés sur un folklore plus large. Là encore, en réalité, les avantages sont assez faibles, alors à quel point le risque doit-il vraiment être minime?

Rayures
la source
3
"Hé, personne ne pousse pendant un certain temps, je dois corriger ..." .. sonne comme l'ancien temps d'utilisation de Visual Source Safe. Je pensais que git était mieux que ça.
gbjbaanb
Oui, donc les gens font des règles comme "ne jouez pas avec les outils tranchants! (Force push)" afin qu'ils puissent éviter de soigner les blessures évitables!
Stripes
2
@gbjbaanb Oui, Git est meilleur que cela - lorsque vous l'utilisez correctement. Se plaindre de l'incapacité de Git à gérer avec élégance le développement simultané lorsque vous rebasez et modifiez constamment les hachages de validation de tout, c'est comme se plaindre que les voitures sont inférieures aux voitures car elles sont beaucoup plus lourdes à tirer pour le cheval. Ce n'est pas la faute de l'outil si les gens insistent pour l'utiliser à mauvais
escient
4
Eh bien, c'est en quelque sorte la faute de l'outil. Git expose BEAUCOUP d'arêtes vives, et même si parfois il note qu'elles sont nettes, ce n'est souvent pas le cas. Si vous le comparez pour dire CVS où tous les bits tranchants se trouvent dans une sous-commande SINGLE ("cvs admin"? Cela a un certain temps ...) qui sort du chemin pour dire "cela peut vous couper mal, ne le faites pas l'utiliser sauf si vous en avez un besoin urgent ". Ou d'autres systèmes de contrôle de version qui omettent des capacités qui peuvent être nuisibles.
Stripes
4
Cela ne veut pas dire que git n'a pas fait de choix de conception valides (fonctions liées au groupe par sous-commande, et préfère permettre à git de résoudre des choses plus complexes entre de bonnes mains) ... mais ce sont des CHOIX, et on peut être critique envers le le choix d'avoir autant d'arêtes vives, un peu comme on peut critiquer le choix d'autres VCS de laisser de côté autant de fonctionnalités utiles "juste parce que quelqu'un peut se blesser".
Stripes
2

Pour ajouter une voix différente:

Oui, si vous travaillez comme vous le décrivez, il n'y a aucun problème avec l'utilisation rebaseet la poussée forcée. Le point critique est: vous avez un accord dans votre équipe.

Les avertissements rebaseet amis sont pour le cas où il n'y a pas d'accord spécial. Normalement, git vous protège automatiquement, par exemple en ne permettant pas une poussée non rapide. L'utilisation rebaseet la poussée forcée annulent cette sécurité. C'est ok si vous avez autre chose en place.

Dans mon équipe, nous rebasons aussi parfois les branches de fonctionnalités si l'historique est devenu désordonné. Nous supprimons l'ancienne branche et en créons une nouvelle avec un nouveau nom, ou nous nous coordonnons simplement de manière informelle (ce qui est possible car nous sommes une petite équipe et personne d'autre ne travaille dans notre référentiel).


Notez que le projet git lui-même fait aussi quelque chose de similaire: ils ont une branche d'intégration régulièrement recréée, appelée "pu" ("mises à jour proposées"). Il est documenté que cette branche est recréée régulièrement et que vous ne devez pas baser de nouveaux travaux dessus.

sleske
la source
1

Donc, j'avoue: dès qu'il y a une force de poussée, il y a un risque de faire des erreurs. C'est vrai. Mais il y a aussi de nombreuses façons de se remettre des erreurs, et vraiment, en 3 ans de développement, je n'ai pas vu beaucoup d'erreurs poussant la force, et quand cela se produisait, nous avons toujours trouvé un moyen de récupérer correctement.

La raison pour laquelle les utilisateurs de Git ont tendance à éviter l'historique mutable partagé est qu'il n'y a pas d'évitement ou de réparation automatique de ces problèmes. Vous devez savoir ce que vous faites et vous devez tout réparer manuellement si vous vous trompez. Autoriser exactement une personne à effectuer une poussée forcée n'est pas intuitif et contraire à la conception distribuée de Git. Que se passe-t-il si cette personne part en vacances? Est-ce que quelqu'un d'autre possède temporairement la succursale? Comment savez-vous qu'ils ne marcheront pas partout quoi que le propriétaire d'origine faisait? Et dans le monde de l'open source, que se passe-t-il si le propriétaire de l'agence s'éloigne progressivement de la communauté, sans partir officiellement? Vous pourriez perdre beaucoup de temps à attendre de céder la propriété de la succursale à quelqu'un d'autre.

Mais le vrai problème est le suivant: si vous vous trompez et que vous ne le réalisez pas immédiatement, les anciens commits disparaîtront finalement après suffisamment de temps. À ce stade, le problème peut être irrécupérable (ou au moins, potentiellement très difficile à récupérer, selon l'apparence de votre sauvegarde - sauvegardez-vous d'anciennes copies de votre référentiel Git, c'est-à-dire pas seulement des clones?).

Comparez cela avec le travail d'évolution de l'ensemble de modifications de Mercurial (qui, je dois le noter, n'est pas encore terminé ou stable). Tout le monde peut apporter les modifications à l'historique qu'il souhaite, à condition que les ensembles de modifications ne soient pas marqués comme publics. Ces modifications et rebases peuvent être poussées et tirées en toute impunité, sans avoir besoin d'un propriétaire de succursale. Aucune donnée n'est jamais supprimée; l'ensemble du référentiel local est uniquement en annexe. Les ensembles de modifications qui ne sont plus nécessaires sont marqués comme obsolètes, mais conservés indéfiniment. Enfin, lorsque vous gâchez votre historique (qui est traité comme une partie normale de votre flux de travail quotidien), il y a une commande astucieuse pour le nettoyer automatiquement pour vous. C'est le genre d'UX que les gens attendent avant de modifier l'historique partagé.

Kevin
la source
Je suis d'accord avec cette "philosophie git" et je pense aussi que les philosophies peuvent parfois être piratées :). Plus sérieusement, comme je l'ai dit dans les commentaires, il y a maintenant 3 ans, j'étais dans le cas particulier d'avoir gerrit comme outil de révision de code qui agissait comme un outil de sauvegarde de facto, empêchant une telle perte dramatique potentielle. Maintenant, je pense toujours que rebaser est OK lorsque vous êtes sûr de "contrôler" une branche. Même dans un projet open source, si je développe une fonctionnalité et ouvre une pull request, je "possède" ce PR, je considère que j'ai le droit de rebaser sa branche, c'est à moi de ne pas foutre mon propre travail lors du rebasage ... (1/2)
Joel
..., et si certaines personnes veulent apporter des modifications à ce PR, je considère qu'elles devraient me le dire en premier, et c'est une question de communication. (2/2)
Joel
PS: merci pour le lien d'évolution Changeset, c'est intéressant
Joel
En fait, rebaser, c'est comme dire: "réécrivons tout mon travail à partir de zéro (du dernier maître), en supprimant tout mon travail précédent.". Si vous êtes d'accord pour le faire, vous pouvez rebaser.
Joel