Accéder au contenu principal

Force de traction Git : Comment écraser une branche locale avec une branche distante ?

Apprenez pourquoi git pull --force n'est pas la meilleure façon d'écraser une branche locale avec la version distante, et découvrez la bonne méthode en utilisant git fetch et git reset.
Actualisé 15 janv. 2025

Dans certaines situations, nous pouvons souhaiter réinitialiser l'état d'un fichier local de Git pour l'aligner sur le référentiel distant, ce qui a pour effet d'annuler toutes les modifications locales. C'est ce que l'on appelle communément unetraction forcée .

Cela crée l'idée fausse que la manière d'archiver est d'utiliser l'option --force dans la commande git pull. Dans cet article, nous apprenons qu'il s'agit de deux choses différentes.

Si vous êtes novice en matière de Git, nous vous conseillons de lire d'abord notre tutoriel Git push et pull.

Nous pouvons remplacer notre état local par l'état distant en utilisant les commandes ci-dessous, en remplaçant par le nom de votre branche. Cette action supprimera définitivement toutes vos modifications locales dans cette branche.

git fetch
git reset --hard origin/<branch_name>

Cet article explique en détail le fonctionnement de ces commandes. Nous allons au-delà des solutions rapides pour comprendre les mécanismes sous-jacents, ce qui nous permet d'apprendre des méthodes plus efficaces pour atteindre le résultat souhaité sans risquer de perdre des changements importants. Nous dissipons également les idées fausses et apprenons ce que fait réellement l'option --force de git pull.

Devenez ingénieur en données

Développez vos compétences en Python pour devenir un ingénieur de données professionnel.
Commencez gratuitement

Quand faut-il envisager d'écraser les modifications locales ?

En général, l'écrasement des modifications locales de cette manière va à l'encontre de l'utilisation prévue de Git. Pour presque toutes les situations, il existe un flux de travail Git approprié pour les résoudre. Cependant, certaines d'entre elles nécessitent souvent une compréhension plus approfondie de Git et prennent plus de temps à mettre en œuvre. Même si ce n'est pas la meilleure pratique, l'écrasement des modifications locales peut parfois être le moyen le plus rapide d'effectuer le travail.

Pour moi, cela se produit généralement lorsque je travaille sur une fonctionnalité que je ne connais pas très bien. Je commence par créer une branche et faire quelques commits. Lorsque je suis bloqué, je demande de l'aide à un collègue. Ils partent d'un commit antérieur, avant que je ne commette l'erreur, résolvent le problème et transfèrent leurs modifications. À ce stade, je dois remplacer ma version locale par la version distante mise à jour, tout en abandonnant mes modifications locales, afin de pouvoir continuer à travailler sur la fonctionnalité.

Un autre exemple est celui d'un conflit, et j'ai le sentiment qu'il est plus difficile ou plus long de résoudre le conflit que de réimplémenter nos changements dans la dernière version du code.

Quelle que soit la raison, assurez-vous toujours que ces modifications ne sont pas vraiment nécessaires et qu'elles peuvent être supprimées en toute sécurité ou sauvegardez votre branche pour éviter de perdre un travail important.

Comment écraser correctement les modifications locales ?

La première étape consiste à récupérer (télécharger) le dernier contenu du dépôt distant sur notre machine locale. Cela se fait à l'aide de lacommande fetch de git:

git fetch

Par défaut, cela permet de récupérer le contenu de la branche courante, ce qui est généralement ce dont nous avons besoin. Nous pouvons optionnellement spécifier la branche que nous souhaitons télécharger (en remplaçant ci-dessous par le nom de la branche que nous souhaitons récupérer) :

git fetch origin/<branch_name>

Vous pouvez également utiliser l'option --all pour tout télécharger :

git fetch –all

La récupération des modifications du référentiel distant n'affectera pas les fichiers de votre répertoire de travail actuel. La commande fetch télécharge les modifications du référentiel distant mais ne les fusionne pas. Le référentiel local conserve une vue des fichiers locaux et des fichiers distants, et la récupération met à jour la vue des fichiers distants.

Après avoir téléchargé les modifications du dépôt distant, nous pouvons utiliser la commande reset de git pour réinitialiser la branche de travail actuelle dans un état donné :

git reset --hard origin/<branch_name>

L'option --hard est nécessaire pour s'assurer que les modifications locales sont écrasées par les modifications à distance. Dans la commande ci-dessus, nous avons choisi de remplacer la branche de travail actuelle par origin/ qui correspond à la version distante de cette branche qui vient d'être récupérée.

La commande git reset supprime les modifications locales, même si elles ont été validées. Il est donc recommandé de créer une sauvegarde locale de la branche actuelle avant d'exécuter cette commande. Vous pouvez le faire en utilisant :

git branch <name_of_the_backup_branck>

Remplacer par le nom que vous souhaitez donner à la branche de sauvegarde.

En mettant tout cela ensemble, nous pouvons remplacer toutes les modifications locales d'une branche donnée par la dernière version distante en procédant comme suit :

git fetch
git branch <name_of_the_backup_branch>
git reset --hard origin/<branch_name>

Si vous souhaitez approfondir vos connaissances sur le travail avec les branches dans Git, consultez le tutoriel Git Clone a Specific Branch (Cloner une branche spécifique).

Nettoyage complet en supprimant les fichiers non suivis

Git ne touchera pas aux fichiers non suivis (fichiers qui n'ont jamais été utilisés par git add). Si nous voulons également supprimer ces fichiers, nous pouvons le faire en utilisant :

git clean -fdx

Il s'agit d'une commande dangereuse utilisée pour supprimer les fichiers non suivis du répertoire de travail. Il est essentiel d'utiliser cette commande avec prudence car elle supprime définitivement ces fichiers, ce qui rend impossible leur récupération par Git. Voici un aperçu des options de commande :

  • -f: Cette option force la poursuite de l'opération de nettoyage. Git refusera de supprimer les fichiers non suivis du répertoire de travail sans ce drapeau comme mesure de sécurité pour éviter la perte accidentelle de données.
  • -d: Cela indique à git clean de supprimer non seulement les fichiers non suivis, mais aussi les répertoires non suivis. Par défaut, git clean ne cible que les fichiers non suivis et ignore les répertoires.
  • -x: Par défaut, git clean respecte les règles de .gitignore et ne supprime pas les fichiers ou les répertoires qui correspondent à ces modèles. L'ajout de -x annule ce comportement, en demandant à Git de supprimer également les fichiers/répertoires qui sont ignorés par .gitignore ou d'autres règles d'ignorance. Il en résulte un nettoyage très complet, qui supprime tous les fichiers non suivis dans le référentiel, y compris les sorties de compilation, les fichiers journaux et les autres artefacts générés qui sont généralement ignorés.

Comprendre Git Pull

La façon habituelle de mettre à jour notre référentiel local avec les modifications effectuées à distance est d'utiliser la commande git pull . Cependant, cette commande ne peut pas être utilisée pour remplacer nos modifications locales car git pull essaiera de fusionner notre version locale avec la version distante.

Sous le capot, git pull effectue les opérations suivantes :

  1. Il utilise git fetch pour télécharger la dernière version du référentiel distant.
  2. Il utilise git merge pour fusionner les branches locales et distantes.

En raison de l'étape de fusion, git pull n'est pas une commande appropriée dans les situations où nous voulons ignorer et rejeter les modifications locales.

<code data-mce-selected=

Que pensez-vous de la git pull --force?

En consultant la documentation de la commande git pull , nous constatons qu'elle propose une option --force. On croit souvent à tort que cette option force la commande git pull à s'exécuter en effaçant les modifications locales avec les modifications à distance.

Lorsque nous fournissons l'option --force à git pull, cette option est transmise à git fetch. Ainsi, git pull --force effectue les étapes suivantes :

  1. git fetch --force
  2. git merge

 <code data-mce-selected=

Nous avons appris que fetch est utilisé pour mettre à jour la vue locale du référentiel distant. Si la seule différence entre votre dépôt local actuel et le dépôt distant est quelques commits manquants (la branche locale est en retard sur la version distante), alors git fetch mettra simplement à jour la vue locale en ajoutant ces nouveaux commits à l'historique.

Git fetch synchronise le dépôt local avec le dépôt distant si l'historique des branches correspond.

Cependant, il se peut que quelqu'un ait réécrit l'historique des livraisons de la branche distante, la rendant incompatible avec la vue locale. Dans ce cas, fetch ne fonctionnera pas.

La récupération de Git échouera si l'historique de la branche ne correspond pas, à moins d'utiliser l'option <code data-mce-selected=>.

Nous pouvons contourner ce problème en utilisant l'option --force qui forcera Git à ignorer l'historique local et à l'écraser avec l'historique distant. 

Nous voyons que l'option --force est liée au fait de forcer l'écrasement de l'historique des livraisons et n'a rien à voir avec le fait d'ignorer les changements locaux dans le répertoire de la branche de travail.

Intégrer les changements locaux

L'écrasement des modifications locales par les modifications distantes n'est pas une pratique courante de Git mais peut être utile dans certains cas où nous ne voulons pas gérer de conflits ou ne nous soucions pas de nos modifications locales.

Fusionner

D'habitude, on retire les modifications et on gère les conflits. Les gens ont tendance à avoir peur des conflits. Certains conflits peuvent être insurmontables, mais ce n'est pas toujours le cas. Un conflit survient lorsque

  1. La branche locale et la branche distante ont toutes deux modifié la même partie d'un fichier.
  2. Un fichier est supprimé d'un côté et modifié de l'autre.

Dans ce cas, Git ne peut pas deviner quelles modifications nous voulons conserver, et nous devons le lui indiquer manuellement. Git mettra en évidence le conflit dans les fichiers comme suit :

Exemple de conflits Git

Pour résoudre un conflit, nous modifions le fichier en supprimant ces lignes, à l'exception de celles que nous voulons conserver. Après avoir traité tous les conflits, nous pouvons valider les modifications. Pour un guide approfondi, consultez ce tutoriel sur comment résoudre les conflits de fusion dans Git.

La cueillette des cerises

Si nous voulons vraiment que notre version locale corresponde d'abord à la version distante et que nous puissions ensuite intégrer nos modifications, nous pouvons intégrer les modifications de la branche de sauvegarde dans la branche actuelle, comme suit :

git cherry-pick <commit_hash>

Ici, est le hash du commit que nous voulons intégrer. Cela suppose qu'avant de faire git reset, nous avons créé une branche de sauvegarde avec git branch et que les modifications locales ont été validées.

Pour trouver l'adresse , nous pouvons lister les hachages des livraisons dans la branche de sauvegarde en utilisant la commande suivante :

git log <name_of_the_backup_branck>

Mise en réserve

Alternativement, si nous ne voulons pas livrer nos changements ou créer une branche de sauvegarde, nous pouvons cacher nos changements avant de les fusionner en les utilisant :

git stash

Cette commande peut être utilisée pour sauvegarder temporairement le travail en cours sans l'intégrer à l'historique de la branche. La mise en cache met de côté vos modifications, ce qui vous permet d'avoir un répertoire de travail propre.

Après la réinitialisation, nous pouvons rétablir les modifications à l'aide de la commande suivante :

git stash pop

En utilisant la mise en réserve, l'ensemble du flux de travail ressemblerait à ce qui suit :

git fetch
git stash
git reset --hard origin/<branch_name>
git stash pop

Pour en savoir plus, consultez cette avec stash et d'autres commandes git.

Conclusion

Bien qu'il ne s'agisse pas d'une bonne pratique, nous nous trouvons parfois dans une situation où nous voulons simplement que notre branche locale corresponde au contenu de la branche distante tout en supprimant nos modifications locales.

On croit à tort que cela se fait à l'aide de git pull --force. Ceci est incorrect car git pull --force combine git fetch --force et git merge. Par conséquent, il tente de fusionner les modifications locales avec les modifications à distance, sans les écraser.

La manière correcte d'écraser les modifications locales avec le contenu du référentiel distant est la suivante :

git fetch
git reset --hard origin/<branch_name>

La commande git reset doit être utilisée avec précaution car elle supprime les modifications locales, même si elles ont été validées. Si nous avions des commits locaux et que nous avons créé une branche de sauvegarde, nous pouvons les ramener en utilisant git cherry-pick. Si nous n'avons pas effectué de validation et que nous souhaitons sauvegarder temporairement notre travail local, nous pouvons utiliser git stash avant la réinitialisation, puis git stash pop pour rétablir nos modifications.

Obtenez une certification pour le poste de Data Engineer de vos rêves

Nos programmes de certification vous aident à vous démarquer et à prouver aux employeurs potentiels que vos compétences sont adaptées à l'emploi.

Obtenez votre certification
Timeline mobile.png

François Aubry's photo
Author
François Aubry
LinkedIn
L'enseignement a toujours été ma passion. Dès mes premiers jours d'études, j'ai cherché avec enthousiasme des occasions de donner des cours particuliers et d'aider d'autres étudiants. Cette passion m'a amenée à poursuivre un doctorat, où j'ai également été assistante d'enseignement pour soutenir mes efforts académiques. Au cours de ces années, j'ai trouvé un immense épanouissement dans le cadre d'une classe traditionnelle, en favorisant les liens et en facilitant l'apprentissage. Cependant, avec l'avènement des plateformes d'apprentissage en ligne, j'ai reconnu le potentiel de transformation de l'éducation numérique. En fait, j'ai participé activement au développement d'une telle plateforme dans notre université. Je suis profondément engagée dans l'intégration des principes d'enseignement traditionnels avec des méthodologies numériques innovantes. Ma passion est de créer des cours qui sont non seulement attrayants et instructifs, mais aussi accessibles aux apprenants à l'ère du numérique.
Sujets

En savoir plus sur Git !

Certification disponible

cours

Introduction à Git

4 hr
38.1K
Familiarisez-vous avec Git pour le contrôle des versions. Découvrez comment suivre, comparer, modifier et inverser des fichiers, ainsi que collaborer avec des collègues à l'aide de Git.
Afficher les détailsRight Arrow
Commencer le cours
Voir plusRight Arrow