Cours
En tant que développeur, vous avez probablement déjà rencontré ce problème : Vous venez de vous rendre compte que votre code présentait un problème lors de votre dernière validation. Pour corriger cette erreur, veuillez exécuter certaines commandes et réécrire votre historique local. Lorsque vous exécutez « git push --force » pour tout nettoyer, vos coéquipiers vous informent que certaines validations sont manquantes ou que votre pipeline a des builds défectueux.
Dans cet article, je vais vous expliquer en détail ce que fait réellement l'git push --force, quand l'utiliser et comment éviter les erreurs. Si vous débutez avec Git, je vous recommande de suivre notre cours Introduction à Git sur afin d'apprendre les bases du contrôle de version. De plus, je trouve que le Git Cheat Sheet, que vous pouvez télécharger, est une référence utile car il contient tous les termes et commandes Git les plus courants.
Quand vous pensez avoir besoin de git push --force
Supposons que vous souhaitiez nettoyer l'historique des commits locaux avant de pousser votre travail. Pour organiser l'historique de vos commits avant la fusion, veuillez exécuter la commande « git rebase -i main ». Tout semble parfait localement, vous essayez donc de mettre à jour votre branche distante avecà l'aide d'une simple commande git push. Cependant, au lieu du message de réussite habituel, Git affiche une erreur.
Vous pourriez également vous retrouver dans une situation où vous commettez accidentellement des données sensibles , peut-être une clé API ou un mot de passe, et les envoyez à distance. Après avoir réécrit l'historique localement pour supprimer la validation incriminée, vous constatez qu'une poussée normale ne met pas à jour le référentiel distant et que les données sensibles sont toujours présentes. Vous obtenez un message d'erreur à la place.
! [rejected] main -> main (non-fast-forward)
error: failed to push some refs to 'origin'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.,
hint: 'git pull ...') before pushing again.
Cette erreur « non-fast-forward » est un dispositif de sécurité de Git qui vous avertit qu'un élément de votre historique ne correspond pas à ce qui se trouve sur le serveur. À ce stade, il est tentant d'exécuter l'git push --force pour contourner cette erreur.
Cela peut fonctionner si vous êtes le seul à travailler sur la branche. Cependant, les projets partagés peuvent facilement créer de la confusion ou supprimer le travail d'une autre personne.
Ce que fait réellement git push --force
En règle générale, Git vous permet uniquement de pousser vos modifications si votre branche locale contient tout ce qui se trouve déjà sur le distant, y compris vos nouveaux commits. Cependant, il peut arriver que vous souhaitiez réécrire l'historique de vos commits à l'aide de « git rebase », « » (squash) ou «» (suppression) des données sensibles. Lorsque vous effectuez cette opération, votre branche locale sera différente de la branche distante. Ensuite, lorsque vous essayez de pousser un nouveau commit, Git affiche l'erreur, qui protège la branche distante contre la perte de travail.
L'utilisation de « git push --force » indique à Git d'ignorer le contrôle de sécurité et de remplacer la branche distante par le contenu de votre branche locale.
Voici à quoi cela ressemble :
git push --force origin main
Cela mettra à jour la branche principale de la télécommande afin qu'elle corresponde à votre branche principale locale et supprimera tous les commits qui ne se trouvent pas dans votre branche locale.
Maintenant, imaginez votre branche Git comme un chapitre d'un livre partagé que votre équipe rédige ensemble. Une poussée standard est similaire à l'ajout de nouveaux paragraphes à la fin d'un chapitre. Cependant, une commande « git push --force » est plus puissante : elle supprime le chapitre actuel et le remplace entièrement par votre version.
Le risque lié à l'utilisation de l'option « git push --force » est que les collaborateurs risquent de perdre leur travail s'ils basent leurs modifications sur les commits que vous venez d'effacer. Dans la section suivante, nous examinerons les précautions à prendre lorsque vous utilisez la commande --force.
Pourquoi cela pourrait compromettre le travail de votre équipe
Si vous forcez la validation de vos modifications sur une branche partagée telle que main ou develop, vous risquez de rencontrer les problèmes suivants :
- Les autres succursales locales ne sont plus synchronisées : Si vos coéquipiers ont récupéré les anciens commits que vous avez supprimés du serveur distant, leurs historiques locaux ne correspondent plus à ceux du serveur. Leurs branches feront référence à des commits qui ont « disparu », ce qui créera de la confusion et
- Le fait de tirer entraîne des fusions confuses ou des erreurs : Lorsqu'un utilisateur tente d'effectuer une requête git pull après que vous ayez effectué un force push, Git ne saura pas comment réconcilier l'historique réécrit avec la séquence locale de commits . Cela conduit souvent à des commits de fusion inhabituels, à des erreurs cryptiques ou à des situations où les collaborateurs sont invités à intervenir manuellement avec git fetch, git reset, voire à recloner la branche.
- Les pipelines CI/CD peuvent échouer : Les pipelines dépendent souvent de hachages de validation cohérents et d'un historique linéaire. Une mise à jour forcée peut entraîner l'échec des tests, le déploiement d'un code incorrect ou un plantage lors de la reconstruction sur des commits obsolètes.
Veuillez consulter notre cours CI/CD pour le Machine Learning afin de comprendre comment créer des workflows CI/CD. Je vous recommande également de suivre notre cours Introduction au versionnage des données avec DVC afin de comprendre la différence entre le versionnage des données et le versionnage du code.
Permettez-moi d'illustrer cela : Vous êtes sur la branche feature avec un collègue. Veuillez effacer l'historique de votre navigateur, puis exécutez git push --force. Quelques minutes plus tard, votre collègue valide ses modifications. Ils identifient des erreurs dans Git. Lorsqu'ils effectuent une extraction, ils rencontrent des conflits de fusion et un historique des commits altéré. Entre-temps, votre pipeline CI échoue en raison de commits manquants. À présent, votre collègue perd du temps à démêler la branche, et le déploiement est retardé.
Une simple pression sur la touche Force déclenche tout cela.
L'option la plus sûre : git push --force-with-lease
Pour éviter ce genre de problèmes, je vous recommande d'utiliser git push --force-with-lease. Cette commande ajoute une vérification de sécurité lors de la poussée vers une branche distante afin d'éviter des commits inattendus.
git push --force-with-lease origin main
Considérez l'--force-with-lease comme le fait de « vérifier que la voie est libre avant de se lancer ». Avant toute action, il s'assure que personne d'autre n'a modifié la branche. Si tout est tel que vous l'avez laissé, votre historique a été mis à jour. Toutefois, si de nouveaux changements auxquels vous n'aviez pas connaissance surviennent, Git vous arrête et vous invite à examiner la situation avant de continuer. Ainsi, cette commande protégera toujours les collaborateurs contre tout écrasement involontaire.
Comment récupérer après une mauvaise mise à jour forcée
Si vous perdez des commits, ne vous inquiétez pas, vous pouvez toujours les récupérer. Git conserve toujours une trace des modifications apportées à la validation actuelle, y compris les réécritures, et les stocke dans le fichier reflog.
Voici comment récupérer des commits perdus :
Étape 1 : Utilisez git reflog pour retrouver les commits perdus.
Veuillez exécuter « git reflog » pour afficher l'historique de votre branche.
git reflog
Vos commits peuvent apparaître comme suit :
abc1234 HEAD@{1}: push: force push
def5678 HEAD@{2}: commit: add new feature
Étape 2 : Restaurer la validation perdue
Une fois que vous avez identifié le hachage de validation que vous souhaitez récupérer, utilisez la commande ci-dessous pour accéder à la branche spécifique.
git checkout def5678
Étape 3 : Créer une nouvelle branche
Pour récupérer les fichiers en toute sécurité, veuillez créer une nouvelle branche git.
git checkout -b recovery-branch
Étape 4 : Restaurer la branche distante
Maintenant, transférez les commits récupérés vers la branche :
git push origin recovery-branch
Veuillez noter que les données reflog n'existent que sur les machines locales. Par conséquent, vous ne pourrez pas récupérer les commits perdus si aucun de vos coéquipiers ne les a enregistrés dans l'environnement local.
Je vous recommande de suivre notre cours Git intermédiaire pour en savoir plus sur la collaboration et l'utilisation des branches dans Git.
Meilleures pratiques pour utiliser git push --force en toute sécurité
Afin de réduire le risque de casse, voici quelques bonnes habitudes à adopter :
-
Veuillez privilégier --force-with-lease plutôt que --force: Cette méthode est une option plus sûre qui vérifie si la branche distante n'a pas changé depuis votre dernière récupération. Je vous aiderai à protéger vos collègues contre les écrasements accidentels.
-
Évitez d'imposer des modifications aux branches partagées : Veuillez ne jamais effectuer de push forcé vers des branches partagées telles que
main,master,developourelease. Veuillez n'effectuer une poussée forcée que sur les branches de fonctionnalités dont vous êtes le seul contributeur afin d'éviter toute perturbation. -
Veuillez informer votre équipe avant de procéder à une mise à jour forcée : Si vous devez effectuer une poussée forcée vers une branche partagée, veuillez en informer votre équipe. Cela leur permettra de sauvegarder leur travail et d'éviter toute perte.
-
Veuillez utiliser des branches protégées : Vous pouvez également activer la protection de vos branches lorsque vous utilisez des plateformes telles que GitHub, GitLab et Bitbucket. Cela limite les modifications directes et empêche les poussées forcées accidentelles vers des branches importantes.
Si vous souhaitez en savoir plus sur la gestion des dépôts privés, veuillez consulternotre cours Introduction aux concepts GitHubafin de comprendre comment examiner les pull requests lorsque vous collaborez sur GitHub.
Conclusion
git push --force offre une méthode utile pour réécrire l'historique de votre dépôt, que vous souhaitiez nettoyer des commits ou supprimer des données sensibles. Veuillez toujours faire preuve de prudence lorsque vous utilisez cette commande afin de ne pas perturber le flux de travail de votre équipe.
Dans la mesure du possible, veuillez utiliser --force-with-lease à la place. Cela vous offre davantage de contrôle sans compromettre le travail d'autrui. Avec un peu de soin et de communication, vous pouvez conserver un historique Git propre sans causer de problèmes à votre équipe.
Je vous recommande de consulter nos cursus Git Fundamentals et GitHub Foundations pour devenir un expert en Git.
Apprenez les bases de Git dès aujourd'hui
Foire aux questions
Quels sont les risques liés à l'utilisation de git push --force ?
Cela peut écraser les commits sur la branche distante, ce qui peut entraîner la perte de travail pour vos collègues ou des conflits de fusion confus.
Comment puis-je utiliser git push --force-with-lease en toute sécurité ?
Veuillez utiliser « git push --force-with-lease » à la place de « --force » pour vous assurer que la branche distante n'a pas changé depuis votre dernière récupération et pour éviter tout écrasement accidentel.
Dans quels cas git push --force est-il nécessaire ?
git push --force Cela peut être nécessaire lorsque vous avez rebasé des commits locaux, supprimé des données sensibles de l'historique ou nettoyé l'historique des commits avant de fusionner une branche de fonctionnalité.
Comment puis-je annuler une commande git push --force que je regrette ?
Pour annuler l'git push --force, exécutez « git reflog » pour trouver le commit précédent, puis restaurez-le en vérifiant ce commit et en forçant la poussée de la branche corrigée.
Quelles sont les meilleures pratiques pour éviter les erreurs avec git push --force ?
Veuillez utiliser --force-with-lease, éviter de forcer la publication sur les branches partagées, communiquer avec votre équipe et protéger les branches importantes sur votre plateforme d'hébergement Git.
