Git Pull : Ignorer les modifications locales

GitGitBeginner
Pratiquer maintenant

💡 Ce tutoriel est traduit par l'IA à partir de la version anglaise. Pour voir la version originale, vous pouvez cliquer ici

Introduction

Ce tutoriel fournit un guide complet sur la commande "git pull --ignore-unmerged", qui vous permet de prioriser les modifications distantes par rapport à vos modifications locales dans un dépôt Git. Que vous travailliez sur un projet en équipe ou que vous ayez besoin de synchroniser rapidement votre codebase locale avec le dépôt distant, ce tutoriel vous aidera à comprendre les cas d'utilisation, les avantages et les risques potentiels liés à l'utilisation de cette commande.

Dans ce lab (atelier), vous apprendrez à configurer un dépôt Git, à créer des modifications conflictuelles et à utiliser la commande git pull --ignore-unmerged pour résoudre les conflits. Vous explorerez également des approches alternatives pour gérer les conflits dans un flux de travail Git.

Configuration d'un dépôt Git

Avant d'explorer les commandes git pull, configurons un simple dépôt Git avec lequel travailler. Cela vous fournira un environnement pratique pour comprendre comment Git gère les modifications et les conflits.

Créer un nouveau dépôt

Tout d'abord, créons un nouveau répertoire pour notre dépôt Git. Ouvrez votre terminal et exécutez les commandes suivantes :

cd ~/project
mkdir git-pull-demo
cd git-pull-demo

Maintenant, initialisons un dépôt Git dans ce répertoire :

git init

Vous devriez voir une sortie similaire à celle-ci :

Initialized empty Git repository in /home/labex/project/git-pull-demo/.git/

Configurer les informations utilisateur Git

Pour effectuer des commits, Git a besoin de connaître votre identité. Configurez votre nom d'utilisateur et votre adresse e-mail avec les commandes suivantes :

git config --local user.name "Learner"
git config --local user.email "learner@example.com"

Créer et commettre les fichiers initiaux

Créons quelques fichiers d'exemple avec lesquels travailler. Tout d'abord, créons un simple fichier texte :

echo "## Git Pull Demo" > README.md
echo "This is the first line of the file." > file1.txt

Maintenant, ajoutons ces fichiers à la zone de staging et effectuons votre premier commit :

git add README.md file1.txt
git commit -m "Initial commit"

La sortie devrait ressembler à ceci :

[main (root-commit) xxxxxxx] Initial commit
 2 files changed, 2 insertions(+)
 create mode 100644 README.md
 create mode 100644 file1.txt

Félicitations, vous avez créé avec succès un dépôt Git avec un premier commit. Vérifions l'état de notre dépôt :

git status

Vous devriez voir :

On branch main
nothing to commit, working tree clean

Cela indique que toutes vos modifications ont été commises. Vous disposez maintenant d'un dépôt Git fonctionnel pour les étapes suivantes.

Simulation d'un dépôt distant

Pour comprendre le fonctionnement de la commande git pull, nous devons simuler un dépôt distant. Dans un scénario réel, il s'agirait d'un dépôt hébergé sur des plateformes telles que GitHub, GitLab ou Bitbucket. Pour ce lab (atelier), nous allons créer un répertoire local qui agira comme notre dépôt "distant".

Créer un dépôt "distant"

Créons un dépôt nu (bare repository) qui agira comme notre dépôt distant :

cd ~/project
mkdir remote-repo.git
cd remote-repo.git
git init --bare

Vous devriez voir :

Initialized empty Git repository in /home/labex/project/remote-repo.git/

Un dépôt nu est un dépôt Git qui n'a pas de répertoire de travail. Il est conçu pour être un dépôt central où vous pouvez pousser (push) et tirer (pull) des modifications.

Connecter votre dépôt local au dépôt distant

Maintenant, revenons à votre dépôt local et ajoutons le dépôt distant :

cd ~/project/git-pull-demo
git remote add origin ~/project/remote-repo.git

Pousser vos modifications vers le dépôt distant

Poussons vos modifications locales vers le dépôt distant :

git push -u origin main

La sortie devrait ressembler à ceci :

Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Delta compression using up to 2 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (4/4), 279 bytes | 279.00 KiB/s, done.
Total 4 (delta 0), reused 0 (delta 0)
To /home/labex/project/remote-repo.git
 * [new branch]      main -> main
Branch 'main' set up to track remote branch 'main' from 'origin'.

Cette commande pousse votre branche locale main vers le dépôt distant et configure le suivi entre vos branches locales et distantes avec le flag -u.

Vérifier la connexion

Pour vérifier que votre dépôt local est correctement connecté au dépôt distant, exécutez :

git remote -v

Vous devriez voir :

origin  /home/labex/project/remote-repo.git (fetch)
origin  /home/labex/project/remote-repo.git (push)

Cela montre que votre dépôt local est connecté au dépôt distant avec le nom "origin".

Maintenant que nous avons configuré nos dépôts local et distant, nous pouvons passer à la compréhension de la gestion des conflits et de l'utilisation de la commande git pull --ignore-unmerged.

Création de modifications conflictuelles

Dans cette étape, nous allons créer un scénario où les modifications dans le dépôt distant entrent en conflit avec vos modifications locales. Cela nous aidera à comprendre comment Git gère les conflits et pourquoi la commande git pull --ignore-unmerged peut être utile.

Créer un nouveau clone de dépôt

Tout d'abord, créons un deuxième clone de notre dépôt pour simuler un membre de l'équipe apportant des modifications :

cd ~/project
git clone remote-repo.git team-member-repo
cd team-member-repo

Vous devriez voir :

Cloning into 'team-member-repo'...
done.

Apporter des modifications dans le dépôt du "membre de l'équipe"

Maintenant, modifions le fichier file1.txt dans ce dépôt :

echo "This line was added by a team member." >> file1.txt
git add file1.txt
git commit -m "Team member added a line"
git push origin main

Vous devriez voir :

[main xxxxxxx] Team member added a line
 1 file changed, 1 insertion(+)
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 2 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 325 bytes | 325.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To /home/labex/project/remote-repo.git
   xxxxxxx..xxxxxxx  main -> main

Apporter des modifications conflictuelles dans votre dépôt original

Maintenant, revenons à votre dépôt original et apportons une modification différente au même fichier :

cd ~/project/git-pull-demo
echo "This line was added locally." >> file1.txt
git add file1.txt
git commit -m "Added a line locally"

Vous devriez voir :

[main xxxxxxx] Added a line locally
 1 file changed, 1 insertion(+)

Tenter de tirer (pull) les modifications

Maintenant, essayons de tirer les modifications depuis le dépôt distant :

git pull origin main

Étant donné que vous avez apporté des modifications au même fichier que votre "membre de l'équipe", Git signalera un conflit :

From /home/labex/project/remote-repo
 * branch            main       -> FETCH_HEAD
Auto-merging file1.txt
CONFLICT (content): Merge conflict in file1.txt
Automatic merge failed; fix conflicts and then commit the result.

Voir le conflit

Examinons le fichier avec le conflit :

cat file1.txt

Vous devriez voir quelque chose comme :

This is the first line of the file.
<<<<<<< HEAD
This line was added locally.
=======
This line was added by a team member.
>>>>>>> xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Git a marqué les sections conflictuelles avec <<<<<<< HEAD, ======= et >>>>>>>. La section avant ======= est votre modification locale, et la section après est la modification distante.

Ceci est un scénario de conflit de fusion typique. Dans l'étape suivante, nous utiliserons l'option git pull --ignore-unmerged pour résoudre ce conflit.

Utilisation de git pull avec l'option --ignore-unmerged

Maintenant que nous avons créé un conflit entre nos dépôts local et distant, explorons comment utiliser l'option git pull --ignore-unmerged pour le résoudre.

Comprendre l'option --ignore-unmerged

L'option --ignore-unmerged indique à Git de prioriser les modifications distantes par rapport à vos modifications locales lorsqu'il y a des conflits. Cela peut être utile dans les situations où vous savez que les modifications distantes sont plus importantes que vos modifications locales.

Annuler la fusion en cours

Avant de pouvoir utiliser l'option --ignore-unmerged, nous devons annuler la fusion en cours :

cd ~/project/git-pull-demo
git merge --abort

Cette commande restaurera votre répertoire de travail à l'état qu'il avait avant la tentative de fusion. Vérifions le contenu du fichier :

cat file1.txt

Vous devriez maintenant voir seulement vos modifications locales :

This is the first line of the file.
This line was added locally.

Utilisation de l'option --ignore-unmerged

Maintenant, utilisons l'option git pull --ignore-unmerged :

git pull --ignore-unmerged origin main

Vous pourriez remarquer que Git signale toujours un conflit :

From /home/labex/project/remote-repo
 * branch            main       -> FETCH_HEAD
Auto-merging file1.txt
CONFLICT (content): Merge conflict in file1.txt
Automatic merge failed; fix conflicts and then commit the result.

C'est parce que l'option --ignore-unmerged fonctionne un peu différemment de ce que son nom laisse supposer. Elle ne résout pas directement les conflits en ignorant vos modifications locales. Au lieu de cela, elle permet à Git de poursuivre une fusion même lorsqu'il y a des entrées non fusionnées.

Comprendre ce qui s'est réellement passé

La bonne façon de prioriser les modifications distantes par rapport aux modifications locales est d'utiliser l'option --strategy-option theirs :

git reset --hard ## Attention : cela supprimera toutes les modifications non validées
git pull -X theirs origin main

La sortie devrait ressembler à ceci :

From /home/labex/project/remote-repo
 * branch            main       -> FETCH_HEAD
Updating xxxxxxx..xxxxxxx
Fast-forward
 file1.txt | 1 +
 1 file changed, 1 insertion(+)

Cette commande indique à Git de résoudre automatiquement les conflits en préférant les modifications distantes ("theirs") par rapport à vos modifications locales ("ours").

Vérifions le contenu du fichier maintenant :

cat file1.txt

Vous devriez voir :

This is the first line of the file.
This line was added by a team member.

Comme vous pouvez le voir, la modification distante a été priorisée par rapport à votre modification locale. L'option --strategy-option theirs est un moyen plus direct d'obtenir ce que beaucoup de personnes croient incorrectement que --ignore-unmerged fait.

Quand utiliser --ignore-unmerged

L'option --ignore-unmerged est en fait plus utile dans les cas où vous souhaitez tirer (pull) les mises à jour pour les fichiers qui n'ont pas de conflits, tout en laissant les fichiers conflictuels non fusionnés pour une résolution manuelle ultérieure.

Pour démontrer cela correctement, créons un autre scénario :

## Ajouter un nouveau fichier localement
echo "This is a new local file." > local_file.txt
git add local_file.txt
git commit -m "Added local_file.txt"

## Créer une modification dans le dépôt du membre de l'équipe
cd ~/project/team-member-repo
echo "This is a second line by team member." >> file1.txt
echo "This is a new remote file." > remote_file.txt
git add file1.txt remote_file.txt
git commit -m "Team member made more changes"
git push origin main

## Revenir à votre dépôt
cd ~/project/git-pull-demo
## Apporter une modification différente au fichier file1.txt
echo "This is another local change." >> file1.txt
git add file1.txt
git commit -m "Made another local change"

Maintenant, lorsque vous essayez de tirer les modifications, vous obtiendrez un conflit :

git pull origin main

Sortie :

From /home/labex/project/remote-repo
 * branch            main       -> FETCH_HEAD
Auto-merging file1.txt
CONFLICT (content): Merge conflict in file1.txt
Automatic merge failed; fix conflicts and then commit the result.

Annulons la fusion et essayons avec --ignore-unmerged :

git merge --abort
git pull --ignore-unmerged origin main

Cela peut toujours afficher des conflits, mais cela vous permettra d'obtenir toutes les modifications non conflictuelles (comme remote_file.txt) tout en laissant le fichier conflictuel (file1.txt) à résoudre manuellement.

Approches alternatives pour gérer les conflits

Bien que les commandes git pull --ignore-unmerged et git pull -X theirs puissent être utiles dans des scénarios spécifiques, il existe plusieurs autres approches pour gérer les conflits avec lesquelles vous devriez être familiarisé. Ces approches vous donnent plus de contrôle sur le processus de fusion et peuvent être plus sûres dans de nombreuses situations.

1. Résolution manuelle des conflits

L'approche la plus courante et la plus sûre consiste à résoudre les conflits manuellement. Créons un scénario de conflit propre et résolvons - le manuellement :

cd ~/project/git-pull-demo
git reset --hard HEAD~1 ## Revenir à un commit précédent

Vous devriez voir :

HEAD is now at xxxxxxx Added local_file.txt

Maintenant, apportons une modification au fichier file1.txt :

echo "This is a different local change." >> file1.txt
git add file1.txt
git commit -m "Made a different local change"

Maintenant, tirons (pull) les modifications depuis le dépôt distant :

git pull origin main

Vous verrez un conflit :

From /home/labex/project/remote-repo
 * branch            main       -> FETCH_HEAD
Auto-merging file1.txt
CONFLICT (content): Merge conflict in file1.txt
Automatic merge failed; fix conflicts and then commit the result.

Modifiez le fichier pour résoudre le conflit en utilisant nano :

nano file1.txt

Dans l'éditeur nano, vous pouvez voir les marqueurs de conflit. Modifiez le fichier pour conserver les deux modifications ou apportez d'autres modifications selon vos besoins. Par exemple, vous pourriez vouloir qu'il ressemble à ceci :

This is the first line of the file.
This line was added by a team member.
This is a second line by team member.
This is a different local change.

Enregistrez le fichier (Ctrl + O, puis Entrée) et quittez nano (Ctrl + X).

Maintenant, terminez le processus de fusion :

git add file1.txt
git commit -m "Manually resolved conflict"

Vous devriez voir :

[main xxxxxxx] Manually resolved conflict

2. Utilisation de git stash

Une autre approche consiste à utiliser git stash pour sauvegarder temporairement vos modifications locales, tirer les modifications distantes, puis réappliquer vos modifications :

## Apporter une nouvelle modification au fichier file1.txt
echo "This is yet another local change." >> file1.txt

## Utiliser git stash pour sauvegarder vos modifications locales
git stash

## Tirer les modifications distantes
git pull origin main

## Réappliquer vos modifications locales
git stash pop

S'il y a des conflits lorsque vous exécutez git stash pop, Git vous le fera savoir, et vous pourrez les résoudre manuellement.

3. Création d'une branche de fonctionnalité (feature branch)

Une troisième approche consiste à créer une branche de fonctionnalité pour vos modifications locales :

## Créer et basculer vers une nouvelle branche
git checkout -b feature - branch

## Apporter vos modifications
echo "This is a change in the feature branch." >> file1.txt
git add file1.txt
git commit -m "Made a change in feature branch"

## Revenir à la branche principale
git checkout main

## Tirer les modifications distantes
git pull origin main

## Fusionner votre branche de fonctionnalité
git merge feature - branch

S'il y a des conflits lors de la fusion, Git vous permettra de les résoudre manuellement avant de terminer la fusion.

4. Utilisation d'outils de fusion

Git prend également en charge divers outils de fusion qui peuvent rendre le processus de résolution de conflits plus visuel et intuitif. Vous pouvez configurer Git pour utiliser l'outil de fusion de votre choix avec :

git config --global merge.tool <tool - name>

Lorsque vous rencontrez des conflits, vous pouvez ensuite exécuter :

git mergetool

Cela ouvrira l'outil de fusion configuré, qui vous aidera à résoudre les conflits.

Chacune de ces approches a ses avantages et ses cas d'utilisation. La meilleure approche dépend de votre situation spécifique et de vos préférences.

Résumé

Dans ce laboratoire (lab), vous avez appris les mécanismes de résolution de conflits de Git et exploré plus particulièrement la commande git pull --ignore-unmerged. Vous avez acquis une expérience pratique sur les points suivants :

  1. La configuration d'un dépôt Git et sa connexion à un dépôt distant
  2. La création et la simulation de modifications conflictuelles entre les dépôts local et distant
  3. La compréhension de ce que fait la commande git pull --ignore-unmerged et de ses limitations
  4. L'utilisation de la commande plus efficace git pull -X theirs pour prioriser les modifications distantes
  5. L'exploration d'approches alternatives pour gérer les conflits, notamment :
    • La résolution manuelle des conflits
    • L'utilisation de git stash
    • La création de branches de fonctionnalité (feature branches)
    • L'utilisation d'outils de fusion

Le principal enseignement est que bien que des commandes telles que git pull --ignore-unmerged et git pull -X theirs puissent être utiles dans des scénarios spécifiques, elles doivent être utilisées avec prudence. Dans la plupart des cas, la résolution manuelle des conflits vous donne plus de contrôle et vous aide à vous assurer que les modifications importantes ne sont pas perdues accidentellement.

En comprenant ces concepts et commandes Git, vous êtes désormais mieux équipé pour gérer les conflits de code dans des environnements de développement collaboratif, rendant votre flux de travail Git plus efficace et moins sujet aux erreurs.