Skip to content

Tout pour WordPress, le développement web — et plus encore

🐙 Erreur Git 'fatal: refusing to merge unrelated histories' : causes et solution

🐙 Erreur Git 'fatal: refusing to merge unrelated histories' : causes et solution

Vous avez exécuté git pull et, au lieu des modifications attendues, le terminal vous a affiché une ligne rouge: fatal: refusing to merge unrelated histories. Le projet ne s'est pas mis à jour, les commits n'ont pas été récupérés, et vous vous demandez si vous avez cassé le dépôt.

Non, vous ne l'avez pas cassé. Git refuse simplement de mélanger deux historiques indépendants, et c'est un comportement intentionnel, pas un bug. Dans cinq minutes, vous comprendrez non seulement pourquoi cette erreur se produit, mais vous saurez aussi la corriger dans n'importe quelle situation: lors du premier push, après avoir perdu le dossier .git et lors de la fusion de projets distincts.

💡 Aperçu rapide:

  • Pourquoi Git refuse de fusionner des branches sans lien et pourquoi c'est la bonne chose à faire
  • L'option --allow-unrelated-histories, une solution universelle pour pull, merge et le premier push
  • Scénarios pas à pas: clonage sans historique, nouveau dépôt, rebase et force-push
  • Que faire si l'option ne suffit pas et comment éviter cette erreur à l'avenir

Ce que signifie l'erreur et pourquoi Git la déclenche

Git suit l'historique via une chaîne de commits. Chaque commit référence son parent, construisant un graphe que Git utilise pour comprendre ce qui vient d'où. Lorsque vous faites git merge, Git cherche un ancêtre commun entre deux branches et calcule la différence à partir de celui-ci.

Mais parfois, il n'y a tout simplement pas d'ancêtre commun. Deux graphes de commits ne se croisent pas, comme deux projets distincts qui n'ont jamais eu connaissance l'un de l'autre. Dans une telle situation, Git refuse de fusionner les historiques à l'aveugle et affiche:

1fatal: refusing to merge unrelated histories

Ce n'est pas une erreur au sens habituel du terme. C'est une protection: Git vous dit «Je ne comprends pas comment ces deux historiques sont liés, donc je ne vais pas deviner.» La solution existe, et elle est intégrée à Git depuis la version 2.9.0 (publiée en juin 2016).

Deux scénarios typiques qui mènent à l'erreur

Premier scénario, **la corruption ou la suppression du dossier .git. Vous avez cloné un projet, travaillé avec le code, mais le dossier .git a été supprimé (accidentellement, par un antivirus ou lors d'une copie sans les fichiers cachés). Git perd tout l'historique local et, lors d'une tentative de git push ou git pull, traite votre répertoire de travail comme un projet complètement nouveau, sans lien avec le dépôt distant.

Deuxième scénario, un nouveau dépôt rencontre un dépôt existant. Vous avez fait git init, ajouté plusieurs commits en local, puis essayé de connecter un dépôt distant qui a déjà son propre historique. Git voit deux graphes de commits indépendants et refuse de les mélanger. Cela arrive souvent lorsque vous démarrez un projet de zéro, puis décidez de le publier sur GitHub par-dessus un dépôt existant, ou lorsque vous transférez du code d'un projet à un autre.

Les deux scénarios se résolvent par le même mécanisme, mais avant de l'appliquer, vous devez comprendre ce que vous voulez exactement accomplir: fusionner deux historiques en un seul ou remplacer complètement un historique par un autre.

Solution: l'option --allow-unrelated-histories

La clé pour corriger cela est l'option --allow-unrelated-histories. Elle indique explicitement à Git: «Je sais que ces branches n'ont pas d'ancêtre commun, et je souhaite consciemment les fusionner.» L'option fonctionne avec les deux commandes principales, git pull et git merge.

**Pour **git pull (le cas le plus courant):

1git pull origin main --allow-unrelated-histories

Remplacez main par le nom de votre branche s'il est différent (master, develop, etc.). Git va créer un commit de fusion qui relie les deux historiques indépendants. Un éditeur va probablement s'ouvrir pour le message de commit, décrivez pourquoi vous fusionnez les historiques, sauvegardez et fermez l'éditeur.

**Pour **git merge (lorsque les branches sont locales):

1git merge feature-branch --allow-unrelated-histories

Après une fusion réussie, Git vous invitera à pousser le résultat. N'oubliez pas de le faire:

1git push origin main

Nuance importante: --allow-unrelated-histories ne supprime pas les conflits de fusion. Si les deux branches ont des fichiers avec les mêmes noms, Git vous demandera toujours de résoudre les conflits manuellement, l'option ne gère que la connexion des historiques, pas le contenu des fichiers.

Scénarios pas à pas pour différentes situations

Situation 1: premier push vers un dépôt distant non vide

Vous avez créé un projet en local (git init → commits), et sur GitHub il y a déjà un dépôt avec README.md et .gitignore. Un git push direct ne fonctionnera pas car la branche distante contient des commits que vous n'avez pas.

Séquence correcte:

Récupérez d'abord l'historique distant et fusionnez-le avec votre historique local:

1git pull origin main --allow-unrelated-histories

Résolvez les conflits s'il y en a (généralement des conflits sur README.md), faites un commit de fusion, puis:

1git push origin main

Situation 2: récupération après la perte de.git

Le dossier .git est supprimé, mais le répertoire de travail est intact. Vous pouvez restaurer la connexion au dépôt distant sans perdre les modifications non commitées:

1git init
2git remote add origin <repository-url>
3git fetch origin
4git reset --mixed origin/main

La commande git reset --mixed synchronise l'index Git avec la branche distante, mais garde tous vos fichiers de travail intacts. Après cela, ajoutez les modifications et faites un nouveau commit:

1git add .
2git commit -m "Recovery after losing .git"
3git push origin main

Cette approche est préférable à --allow-unrelated-histories car elle ne crée pas de commit de fusion artificiel et garde l'historique propre.

Situation 3: rebase avec des historiques sans lien

La commande git rebase peut aussi déclencher cette erreur, surtout avec l'option --preserve-merges (maintenant remplacée par --rebase-merges). Solution, ajoutez --allow-unrelated-histories:

1git rebase --rebase-merges --allow-unrelated-histories main

Mais soyez prudent: le rebase réécrit l'historique, et si quelqu'un d'autre travaille avec cette branche, vous allez lui créer des problèmes. Pour les branches partagées, préférez toujours merge.

Que faire si l'option ne suffit pas

Parfois, --allow-unrelated-histories s'exécute sans erreur, mais le résultat n'est pas celui que vous vouliez.

Problème: le commit de fusion encombre l'historique. Si vous avez fusionné deux grands projets, le graphe des commits devient difficile à lire. Dans ce cas, envisagez une alternative, le transfert de fichiers avec conservation de l'historique via git format-patch et git am:

1git format-patch --root -o patches/ HEAD
2git am patches/*.patch

Problème: après la fusion, le projet ne compile pas. Fusionner des historiques sans lien peut entraîner des doublons de fichiers de configuration, des conflits de dépendances ou des versions de paquets incompatibles. Après --allow-unrelated-histories, vérifiez toujours: les dépendances (npm install / composer install), les fichiers de configuration (.env, config/), les chemins et les imports dans le code. Mieux vaut passer cinq minutes à vérifier maintenant que de gérer des échecs de build en CI plus tard.

Problème: vous avez changé d'avis. Vous pouvez annuler une fusion d'historiques sans lien de la manière standard, git reset --hard HEAD~1 (si vous n'avez pas encore poussé le résultat) ou git revert -m 1 HEAD (si vous avez déjà poussé).

Comment éviter l'erreur à l'avenir

Trois règles simples qui vous épargneront cette erreur dans votre travail quotidien.

Ne supprimez pas .git sans nécessité absolue. Si vous devez copier du code sans l'historique, utilisez git archive ou copiez les fichiers en excluant consciemment le dossier caché .git, pas accidentellement.

Ne créez pas un nouveau dépôt à l'intérieur d'un dépôt existant. Si vous devez extraire une partie du code dans un projet séparé, utilisez git subtree split ou git filter-branch (maintenant git filter-repo est recommandé). Ces outils conserveront l'historique des fichiers nécessaires, et Git saura d'où ils viennent.

Avant de faire git init dans un dossier contenant du code, vérifiez toujours s'il y a déjà un dépôt: git status. Si Git répond fatal: not a git repository, vous pouvez initialiser. S'il affiche un statut, vous êtes déjà dans un dépôt existant et git init n'est pas nécessaire ici.

Pour ceux qui débutent avec Git, nous recommandons notre guide "Guide Git pour débutants", il explique pas à pas les clés SSH, la création de dépôt et le flux de travail complet sur GitHub. Et si Git n'est pas encore installé, commencez par le guide "Comment installer Git sur Windows".

⁉️🤔 Foire aux questions

Quelles versions de Git prennent en charge --allow-unrelated-histories?

L'option est apparue dans Git 2.9.0 (juin 2016) et est présente dans toutes les versions ultérieures. Si votre version de Git est plus ancienne, mettez-la à jour: la commande git --version affichera la version actuelle, et git update-git-for-windows (sur Windows) ou le gestionnaire de paquets de votre système effectuera la mise à jour vers la version la plus récente. Le moyen le plus simple de vérifier la version de Git est la commande git --version dans le terminal. À la mi-2026, la branche actuelle est la 2.48+. Si vous êtes sur Windows et que Git a été installé il y a longtemps, téléchargez un nouvel installateur depuis git-scm.com, la mise à jour automatique dans les anciennes versions fonctionnait de manière instable.

Puis-je utiliser l'option directement avec git push?

Non, git push n'accepte pas --allow-unrelated-histories. Push ne crée pas de fusion, il envoie seulement les commits existants. L'erreur «unrelated histories» lors d'un push signifie que votre branche locale et la branche distante ont divergé au niveau de l'historique. Solution: d'abord git pull --allow-unrelated-histories, résolvez les conflits, et seulement ensuite git push. Formellement, --allow-unrelated-histories fonctionne avec git fetch + git merge et avec git pull (qui fait en interne fetch + merge). Push reste une opération distincte que vous effectuez après une fusion réussie. N'essayez pas de contourner cela avec --force, vous perdriez les commits des autres sur le dépôt distant.

Qu'est-ce qui est préférable pour un historique propre: merge ou rebase?

Pour connecter des historiques sans lien, clairement merge. Rebase dans ce contexte crée plus de problèmes qu'il n'en résout: il essaie de rejouer les commits d'une branche par-dessus une autre, mais sans ancêtre commun, cela entraîne des conflits sur chaque commit. Merge avec --allow-unrelated-histories fait exactement ce qui est nécessaire, il crée un point de connexion unique entre deux graphes, après quoi l'historique est unifié. Exception: lorsque vous voulez intentionnellement réécrire l'historique et que vous savez exactement ce que vous faites. Par exemple, lors du transfert de code d'un dépôt à un autre avec nettoyage des anciens commits. Dans ce cas, git rebase --allow-unrelated-histories peut avoir un sens, mais pour le travail quotidien, choisissez merge.

J'ai perdu le dossier .git, mais j'ai des modifications non commitées. Vais-je les perdre?

Non, vous ne les perdrez pas. Le dossier .git lui-même contient uniquement l'historique et les métadonnées Git, mais pas vos fichiers de travail. Tous les fichiers modifiés, nouveaux et même non commités resteront dans le répertoire de travail, intacts. La procédure de récupération est décrite dans la «Situation 2» ci-dessus, git initgit remote addgit fetchgit reset --mixed. Point clé: utilisez exactement --mixed, pas --hard. L'option --mixed réinitialise l'index mais préserve toutes les modifications dans les fichiers. En cas de doute, faites une copie de sauvegarde de tout le dossier du projet avant la récupération, cela prendra dix secondes et éliminera complètement le risque de perte de données dans toute situation non standard.

L'erreur se produit lors du clonage via un IDE. Est-ce le même problème?

Oui, exactement le même. Certains IDE (par exemple, PHPStorm, Visual Studio, les anciennes versions d'IntelliJ) lors de la création d'un projet à partir d'un modèle initialisent un nouveau dépôt Git, puis essaient de connecter un dépôt distant. C'est exactement le deuxième scénario du début de l'article. La solution est la même: ouvrez un terminal dans le dossier du projet et exécutez git pull origin main --allow-unrelated-histories. Après la fusion manuelle, l'IDE détectera automatiquement le nouvel état, il suffit de rafraîchir la fenêtre du projet ou de cliquer sur Actualiser dans le panneau Git.

Faut-il craindre l'erreur «unrelated histories»?

Non. C'est l'une des erreurs Git les plus sûres, elle ne corrompt pas les données, ne supprime pas les fichiers et n'empêche pas de continuer à travailler. L'option --allow-unrelated-histories n'est pas une béquille ou une solution de contournement, mais une capacité documentée, spécifiquement ajoutée par les développeurs de Git pour les cas où vous voulez consciemment connecter deux historiques indépendants.

Une fois cette commande maîtrisée, vous gagnez un outil puissant: vous pouvez désormais fusionner des projets quel que soit leur degré d'isolement, transférer du code entre dépôts et restaurer le travail après la perte de .git, et tout cela sans panique ni recréation du dépôt de zéro. Si Git vous a appris quelque chose aujourd'hui, c'est que «fatal» dans ses messages ne signifie pas «fatal pour le projet», cela signifie «je ne vais pas deviner, dites-moi explicitement quoi faire.»