Commit de code¶
Cette section s’adresse aux fusionneurs et à quiconque est intéressé à savoir comment le code est commité dans Django. Si vous êtes un membre de la communauté désirant contribuer du code à Django, consultez plutôt Travailler avec Git et GitHub.
Gestion des requêtes de contribution¶
Comme Django est hébergé sur GitHub, les correctifs sont fournis sous la forme de requêtes de contribution (« pull request »).
En commitant une requête de contribution, vérifiez que chaque commit individuel corresponde aux lignes de conduite présentées ci-dessous. On attend des contributeurs qu’ils fournissent les meilleurs requêtes de contribution possibles. En pratique, c’est aux fusionneurs, plus familiers avec les exigences de qualité des commits, que revient la décision de parachever eux-mêmes un commit pour qu’il satisfasse aux exigences posées.
Il peut être souhaitable de demander à Jenkins ou aux actions GitHub de tester la requête de contribution à l’aide d’un des constructeurs qui ne se lance pas automatiquement, tel que Oracle ou Selenium. Voir la page de Wiki CI pour plus d’instructions.
S’il se trouve que vous deviez fréquemment récupérer localement des requêtes de contribution, cet alias git vous sera utile :
[alias]
pr = !sh -c \"git fetch upstream pull/${1}/head:pr/${1} && git checkout pr/${1}\"
Ajoutez-le à votre fichier ~/.gitconfig
et définissez upstream
à django/django
. Vous pouvez alors exécuter git pr ####
pour récupérer en local la requête de contribution correspondante.
À ce stade, vous pouvez travailler sur le code. Utilisez git rebase -i
et git commit --amend
pour vous assurer que les commits présentent le niveau de qualité requis. Quand vous êtes prêt :
$ # Pull in the latest changes from main.
$ git checkout main
$ git pull upstream main
$ # Rebase the pull request on main.
$ git checkout pr/####
$ git rebase main
$ git checkout main
$ # Merge the work as "fast-forward" to main to avoid a merge commit.
$ # (in practice, you can omit "--ff-only" since you just rebased)
$ git merge --ff-only pr/XXXX
$ # If you're not sure if you did things correctly, check that only the
$ # changes you expect will be pushed to upstream.
$ git push --dry-run upstream main
$ # Push!
$ git push upstream main
$ # Delete the pull request branch.
$ git branch -d pr/xxxx
...\> REM Pull in the latest changes from main.
...\> git checkout main
...\> git pull upstream main
...\> REM Rebase the pull request on main.
...\> git checkout pr/####
...\> git rebase main
...\> git checkout main
...\> REM Merge the work as "fast-forward" to main to avoid a merge commit.
...\> REM (in practice, you can omit "--ff-only" since you just rebased)
...\> git merge --ff-only pr/XXXX
...\> REM If you're not sure if you did things correctly, check that only the
...\> REM changes you expect will be pushed to upstream.
...\> git push --dry-run upstream main
...\> REM Push!
...\> git push upstream main
...\> REM Delete the pull request branch.
...\> git branch -d pr/xxxx
Poussez de force dans la branche après un « rebase » sur main, mais avant de fusionner et de pousser vers le dépôt amont. Cela permet d’harmoniser les empreintes de commit sur main et sur la branche ce qui va automatiquement fermer la requête de contribution.
Si une requête de contribution ne doit pas être fusionnée avec plusieurs commits différents, il est possible d’utiliser le bouton «Squash and merge» du site Web. Modifiez le message de commit afin qu’il corresponde aux :ref:lignes directrices <committing-guidelines>` et enlevez le numéro de la requête de contribution qui est automatiquement ajouté à la première ligne du message.
Lorsque vous réécrivez l’historique des commits dans une requête de contribution, l’objectif est de rendre l’historique des commits de Django le plus propre possible:
- Si un correctif a été effectué sur plusieurs commits, réécrivez-le en un seul. Par exemple, si un commit ajoute du code et qu’un second ne fait qu’améliorer son écriture, ces commits devraient être compressés en un seul avant d’être fusionné dans le projet.
- Regroupez les changements de façon logique dans plusieurs commits. Si vous faites des changements cosmétiques en même temps que des modifications de code dans un autre fichier, le faire en deux commits distincts aide à relire l’historique des changements.
- Évitez les fusions de branches amont dans les requêtes de contribution.
- Les tests et la documentation devraient être validés et ne pas émettre d’avertissements ou d’erreurs après chaque commit.
- Les petits correctifs triviaux devraient être fait dans un seul commit. Les contributions plus importantes peuvent être fait en plusieurs commits si cela est plus claire.
Conformément au concept « pratique vaut mieux que pureté », c’est à chaque fusionneur de décider de la manipulation d’historique nécessaire pour une requête de contribution. Les points essentiels sont l’engagement de la communauté, le travail bien fait et un historique de commit utilisable.
Lignes directrices pour les commits¶
En plus, veuillez suivre les lignes directrices suivantes lorsque vous envoyez des commits dans le dépôt Git de Django :
Ne modifiez jamais l’historique publié des branches
django/django
en poussant (push) de force. Si vous devez absolument le faire (par exemple pour des raisons de sécurité), discutez d’abord de la situation avec l’équipe principale.Pour toute modification moyenne à importante, où « moyenne à importante » dépend de votre jugement, présentez la situation sur le forum Django ou la liste de diffusion django-developers avant de procéder au changement.
SI vous exposez quelque chose et que personne ne répond, ne considérez pas que cela signifie que votre idée est géniale et qu’elle doit être mise en œuvre immédiatement car personne ne la contestée. Tout le monde n’a pas toujours beaucoup de temps pour lire immédiatement les discussions des listes de diffusion, il se peut donc que vous deviez attendre un certain nombre de jours avant d’obtenir une réponse.
Écrivez les messages de commit détaillés au passé, pas au présent.
- Juste : « Fixed Unicode bug in RSS API. »
- Faux : « Fixes Unicode bug in RSS API. »
- Faux : « Fixing Unicode bug in RSS API. »
Le message de commit doit comporter des lignes de maximum 72 caractères. Il doit y avoir une ligne de sujet, suivi d’une ligne vierge et de paragraphes de lignes à 72 caractères (limites douces). Pour la ligne de sujet, le plus court est le mieux. Dans le corps du message de commit, plus il y a de détails, mieux c’est :
Fixed #18307 -- Added git workflow guidelines. Refactored the Django's documentation to remove mentions of SVN specific tasks. Added guidelines of how to use Git, GitHub, and how to use pull request together with Trac instead.
Remerciez les contributeurs dans le message de commit : «Merci A pour le rapport et B pour la relecture ». Utilisez la balise Co-Authored-By de git lorsque c’est approprié.
Pour des commits d’une branche, préfixez le message de commit avec le nom de branche. Par exemple : « [1.4.x] Fixed #xxxxx – Added support for mind reading. »
Limitez les commits à la plus petite granularité qui garde du sens. Cela signifie qu’il est préférable d’avoir plusieurs petits commits fréquents plutôt que de gros commits ponctuels. Par exemple, si l’implémentation de la fonctionnalité X requiert une petite modification à la bibliothèque Y, alors faites le commit de la fonctionnalité X séparément. Cela aide grandement toutes les personnes qui suivent vos modifications.
Séparez les corrections de bogues des nouvelles fonctionnalités. Les corrections de bogues peuvent nécessiter un rétroportage vers la branche stable, en accord avec Versions prises en charge.
Si un commit ferme un ticket dans le système de suivi de Django, commencez le message de commit par le texte « Fixed #xxxxx », où « xxxxx » est le numéro du ticket résolu par le commit. Example : « Fixed #123 – Added whizbang feature. ». Nous avons adapté Trac pour que tout message de commit respectant ce format ferme automatiquement le ticket référencé et écrive un message sur le ticket contenant le message de commit complet.
Pour les curieux, nous utilisons un greffon Trac pour cela.
Note
Notez que l’intégration Trac ne sait pas tout sur les requêtes de contribution. AInsi si vous essayez de fermer une requête de contribution avec la phrase « closes #400 » dans le message de commit, GitHub fermera la requête, mais le greffon Trac ne fermera pas le ticket ayant le même numéro dans Trac.
Si votre commit fait référence à un ticket dans le suivi des tickets de Django mais ne résoud pas le ticket, incluez l’expression « Refs #xxxxx », où « xxxxx » est le numéro de ticket référencé par votre commit. Cela enverra automatiquement un commentaire dans le ticket concerné.
Écrivez les messages de commit pour les rétroportages en utilisant ce modèle :
[<Django version>] Fixed <ticket> -- <description> Backport of <revision> from <branch>.
Par exemple :
[1.3.x] Fixed #17028 -- Changed diveintopython.org -> diveintopython.net. Backport of 80c0cbf1c97047daed2c5b41b296bbc56fe1d7e3 from main.
Il existe un script dans le wiki <https://code.djangoproject.com/wiki/MergerTips#AutomatingBackports>`_ pour automatiser cela.
Si le commit corrige une régression, incluez ceci dans le message de commit :
Regression in 6ecccad711b52f9273b1acb07a57d3f806e93928.
(utilisez l’empreinte du commit où la régression a été introduite).
Annulation de commits¶
Personne n’est parfait ; des erreurs seront forcément commises.
Mais faites tout votre possible pour que de telles erreurs ne se produisent pas. Le fait d’avoir une politique d’annulation ne vous enlève pas la responsabilité de viser la plus haute qualité possible. Sérieusement, vérifiez votre travail autant de fois que nécessaire ou faites-le vérifier par un autre fusionneur avant de procéder au commit !
Lorsqu’un commit fautif est découvert, veuillez suivre les directives suivantes :
- Si possible, faites faire l’annulation d’un commit par son auteur.
- N’annulez pas les modifications d’un autre auteur sans la permission de celui-ci.
- Utilisez
git revert
– ce qui va produire un commit d’annulation, le commit original faisant toujours partie de l’historique des commits. - Si l’auteur d’origine ne peut pas être contacté (dans un espace de temps raisonnable, un à deux jours) et que le problème est sérieux (bogue de plantage, échecs de tests majeurs, etc.), demandez sur le forum Django ou la liste de diffusion django-developers s’il y a des oppositions puis procédez à l’annulation s’il n’y en a pas.
- Si le problème est mineur (par ex. un commit de fonctionnalité après le gel des fonctionnalités), attendez encore un peu.
- S’il y a désaccord entre le fusionneur et celui qui propose l’annulation, il s’agit de résoudre le conflit sur le forum Django ou la liste de diffusion django-developers. Si aucun accord n’est trouvé, la décision doit alors être soumise à un vote.
- Si le commit a introduit une vulnérabilité de sécurité confirmée et révélée, le commit peut être immédiatement annulé sans obtenir de permission supplémentaire.
- Le mainteneur de la branche versionnée peut annuler des commits de cette branche sans demander de permission si un commit casse cette branche versionnée.
- Si vous avez poussé par erreur une branche de travail vers
django/django
, supprimez-la. Par exemple, si vous avez écrit :git push upstream feature_antigravity
, procédez à la commande inverse :git push upstream :feature_antigravity
.