Pourquoi chaque dépôt Github sérieux que je fais génère-t-il des demandes de désincarcération en un seul commit?
Je pensais que le journal git était là pour que vous puissiez examiner tout votre historique et voir exactement quels changements se sont produits où, mais le supprimer le retire de l’historique et le regroupe en un seul commit. Dans quel but?
Cela semble également aller à l’encontre du mantra "commettez tôt et commettez souvent".
Réponses:
Pour que vous ayez un historique git clair et concis qui documente clairement et facilement les modifications apportées et les raisons.
Par exemple, un journal git typique «non épilé» pourrait ressembler à ceci:
Quel bordel!
Considérant qu'un journal git mieux géré et fusionné avec un peu plus d’attention sur les messages pourrait ressembler à ceci:
Je pense que vous pouvez voir l’intérêt d’écraser les commits et le même principe s’applique aux demandes d’extraction: lisibilité de l’historique. Vous pouvez également ajouter des informations à un journal de validation qui contient déjà des centaines, voire des milliers, de modifications, ce qui contribuera à la brièveté de l’historique croissant.
Vous voulez vous engager tôt et souvent. C'est une bonne pratique pour plusieurs raisons. Je trouve que cela m'amène à avoir fréquemment des commits "wip" (travaux en cours), "partie A terminée" ou "faute de frappe, correction mineure", où j'utilise git pour m'aider à travailler et me donner des points de travail qui Je peux revenir à si le code suivant ne fonctionne pas alors que je progresse pour que les choses fonctionnent. Cependant, je n'ai pas besoin ou ne souhaite pas que cette histoire fasse partie de la version finale de l'histoire de git afin d'écraser mes commits - mais reportez-vous aux notes ci-dessous pour en savoir ce que cela signifie sur une branche de développement par rapport à maître.
S'il existe des jalons importants représentant des étapes de travail distinctes, il est toujours possible d'avoir plus d'un commit par fonctionnalité / tâche / bogue. Cependant, cela peut souvent mettre en évidence le fait que le ticket en cours de développement est "trop gros" et doit être décomposé en éléments plus petits pouvant être autonomes, par exemple:
semble être "1 morceau de travail". Ou ils existent ou ils n'existent pas! Ne semble pas avoir de sens pour le sortir. Cependant, l'expérience m'a montré que (selon la taille et la complexité de l'organisation), un chemin plus granulaire pourrait être:
Les petites pièces signifient des révisions de code plus faciles, des tests unitaires plus faciles, une meilleure opportunité de qa, un meilleur alignement sur le principe de responsabilité unique, etc.
Pour des raisons pratiques de savoir quand faire de telles courges, il existe essentiellement deux étapes distinctes qui ont leur propre flux de travail
Au cours de votre développement, vous vous engagez «tôt et souvent» et avec des messages rapides «jetables». Vous voudrez peut-être écraser ici parfois, par exemple écraser dans les messages wip et todo. Il est normal, au sein de la branche, de conserver plusieurs commits qui représentent des étapes distinctes du développement. La plupart des courges que vous choisissez de faire doivent se trouver dans ces branches, pendant leur développement et avant leur fusion.
Lors de l'ajout à la branche principale, vous voulez que les commits soient concis et correctement formatés en fonction de l'historique existant de la ligne principale. Cela peut inclure l'ID du système Ticket Tracker, par exemple JIRA, comme indiqué dans les exemples. La compression ne s'applique pas vraiment ici à moins que vous ne souhaitiez «cumuler» plusieurs commits distincts sur le maître. Normalement vous ne le faites pas.
Utiliser
--no-ff
lors de la fusion avec master utilisera un commit pour la fusion et préservera également l'historique (dans la branche). Certaines organisations considèrent qu'il s'agit d'une pratique exemplaire. Voir plus à https://stackoverflow.com/q/9069061/631619 Vous verrez également l'effet pratiquegit log
où--no-ff
commettras sera la dernière commettras, au sommet de la tête (quand tout fait), alors que sans--no-ff
qu'il soit plus loin dans l’histoire, en fonction des dates et des autres commits.la source
Parce que, souvent, la personne qui rédige un PR se soucie de l'effet net des validations "fonctionnalité ajoutée X", et non des "modèles de base, fonction de correction X, fonction d'ajout de correction Y, correction des fautes de frappe dans les commentaires, paramètres de mise à l'échelle des données ajustés, hashmap fonctionne mieux que list "... niveau de détail
Si vous pensez que vos 16 commits sont mieux représentés par 2 commits que par 1 "Ajout de la fonctionnalité X, ré-factorisé Z pour utiliser X", alors c'est probablement bien de proposer un pr avec 2 commits, mais alors il serait peut-être préférable de proposer 2 prs séparés dans ce cas (si le repo insiste toujours sur des prs à engagement unique)
Cela ne va pas à l’encontre du mantra "engagez-vous tôt et engagez-vous souvent", comme dans votre référant, tandis que vous développez, vous avez toujours les détails granulaires, de sorte que vous avez une chance minime de perdre du travail, et que d’autres personnes puissent examiner / tirer / proposer prs contre ton travail pendant que le nouveau pr est en cours de développement.
la source
La principale raison de ce que je peux voir est la suivante:
Merge pull request #123 from joebloggs/fix-snafoo
--first-parent
point de vue.--first-parent
point de vue (notez que cela n’a été corrigé que dans Git 2.6.2, nous pourrions donc pardonner à GitHub de ne pas avoir ce message. disponible)Ainsi, lorsque vous combinez les trois situations ci-dessus, vous obtenez une situation dans laquelle les modifications inconditionnelles en cours de fusion sont laides à partir de l'interface utilisateur de GitHub.
Votre histoire avec les commits écrasés ressemblera à quelque chose comme
Considérant que sans commets écrasés l'histoire ressemblera à quelque chose comme
Lorsque vous avez beaucoup de commits dans un suivi de relations publiques où un changement est intervenu, cela peut devenir un peu un cauchemar si vous vous limitez à utiliser l'interface utilisateur de GitHub .
Par exemple, vous trouvez qu'un pointeur null est dé-référencé quelque part dans un fichier ... vous dites donc "qui a fait cela, et quand? Quelles versions de version sont affectées?". Ensuite, vous vous dirigez vers la vue des responsables dans l'interface utilisateur de GitHub et vous constatez que la ligne a été modifiée dans
789fdfffdf
... "oh, mais attendez une seconde, l'indentation de cette ligne venait juste d'être modifiée pour s'inscrire dans le reste du code"; la page de blâme ... finalement vous trouvez le commit ... c'est un commit d'il y a 6 mois ... "oh **** cela pourrait affecter les utilisateurs depuis 6 mois" dites-vous ... ah mais attendez, ce commit était en fait dans une requête Pull et n’a été fusionné qu’hier et personne n’a encore publié de communiqué à ce sujet ... "Bon sang pour avoir fusionné des commits sans avoir écrasé l’histoire" UI GitHubVoyons maintenant comment cela fonctionne si vous utilisez la ligne de commande Git (et le super-génial 2.6.2 qui a le correctif pour
git blame --first-parent
)Donc, notre histoire de commit ressemblerait à
Mais on peut aussi faire
(En d'autres termes: la CLI Git vous permet de prendre votre gâteau et de le manger aussi)
Maintenant, lorsque nous abordons le problème du pointeur null ... eh bien, nous utilisons simplement
git blame --first-parent -w dodgy-file.c
et nous recevons immédiatement le commit exact où la dé-référence du pointeur null a été introduite dans la branche principale en ignorant les simples changements d'espaces.Bien sûr, si vous effectuez des fusions à l'aide de l'interface utilisateur de GitHub, alors
git log --first-parent
c'est vraiment merdique, car GitHub a forcé la première ligne du message de validation de fusion:Donc, pour résumer une longue histoire:
L'interface utilisateur de GitHub (octobre 2015) présente un certain nombre d'inconvénients en ce qui concerne la fusion des demandes d'extraction, la présentation de l'historique des validations et l'attribution des informations de responsabilité. Le meilleur moyen actuel de corriger ces défauts dans l'interface utilisateur de GitHub est de demander aux personnes d'écraser leurs commits avant de procéder à la fusion.
La CLI Git ne présente pas ces problèmes et vous pouvez facilement choisir la vue à afficher afin de découvrir à la fois la raison pour laquelle une modification particulière a été apportée de cette façon (en consultant l'historique des commits non annulés), ainsi que voir les commits effectivement écrasés.
Post script
La dernière raison souvent invoquée pour écraser les commits est de faciliter le portage en arrière… Si vous n'avez qu'un seul commit à sauvegarder (c.-à-d. Le commit écrasé), il est facile de choisir les cerises…
Eh bien, si vous regardez l’histoire de git avec,
git log --first-parent
vous pouvez simplement choisir les modifications de fusion. La plupart des gens sont confus, car ils doivent spécifier l’-m N
option mais si vous recevez le commit,git log --first-parent
vous savez que c’est le premier parent que vous souhaitez suivre, ce sera donc le cas.git cherry-pick -m 1 ...
la source
--first-parent
me réparer afin de gagner un argument contre les écrasements ;-)Je suis d'accord avec les sentiments exprimés dans les autres réponses de ce fil pour montrer un historique clair et concis des fonctionnalités ajoutées et des bugs corrigés. Cependant, je voulais aborder un autre aspect auquel votre question a échappé mais n’a pas été explicitement énoncé. Une partie du problème que vous avez peut-être avec certaines des méthodes de travail de git est que git vous permet de réécrire l’histoire, ce qui semble étrange lorsqu’on le présente à git après avoir utilisé d’autres formes de contrôle de source où de telles actions sont impossibles. En outre, cela va également à l’encontre du principe généralement accepté du contrôle de source selon lequel, une fois que quelque chose est validé / enregistré dans le contrôle de source, vous devriez pouvoir revenir à cet état, quels que soient les changements que vous avez apportés à la suite de ce commit. Comme vous l'avez laissé entendre dans votre question, il s'agit d'une de ces situations. Je pense que Git est un excellent système de contrôle de version. Cependant, pour le comprendre, vous devez comprendre certains détails de la mise en œuvre et des décisions de conception, ce qui entraîne une courbe d'apprentissage plus abrupte. Gardez à l'esprit que git était destiné à être un système de contrôle de version distribué, ce qui aidera à expliquer pourquoi les concepteurs autorisent la réécriture de l'historique de git avec des validations de squash.
la source
git gc
été exécuté pour supprimer des objets non référencés.À cause de la perspective ... La meilleure pratique consiste à avoir un seul commit par
<<issue-management-system>>
problème, si possible.Vous pouvez avoir autant d’engagements que vous le souhaitez dans votre propre branche / rapport d’activité, mais c’est votre histoire qui est pertinente pour ce que vous faites maintenant pour VOTRE perspective ... ce n’est pas l’HISTOIRE de l’ensemble de l’ÉQUIPE / PROJET ou de l’application de leur perspective à conserver dans quelques mois ...
Ainsi, chaque fois que vous souhaitez valider un correctif ou une fonctionnalité dans un référentiel commun (cet exemple concerne la branche develop), procédez comme suit:
comment rebaser votre branche de fonctionnalités pour développer rapidement
la source
Je verrais si le code est rendu public ou non.
Quand les projets restent privés:
Je recommanderais de ne pas écraser et de voir la fabrication de la saucisse. Si vous utilisez de bons et de petits commits, des outils tels que git bisect sont extrêmement pratiques et les utilisateurs peuvent rapidement localiser les commits de régression et voir pourquoi vous l'avez fait (à cause du message de validation).
Quand les projets deviennent publics:
Tout écraser parce que certains commits peuvent contenir des fuites de sécurité. Par exemple, un mot de passe qui a été validé et supprimé à nouveau.
la source