Skip to content

Все для WordPress, веб-розробки — і не тільки

🐙 Помилка Git «fatal: refusing to merge unrelated histories»: причини та рішення

🐙 Помилка Git «fatal: refusing to merge unrelated histories»: причини та рішення

Ви зробили git pull, і замість очікуваних змін термінал зустрів вас червоним рядком: fatal: refusing to merge unrelated histories. Проєкт не оновився, коміти не підтягнулися, а ви сидите й думаєте, чи не зламали ви репозиторій.

Ні, не зламали. Git просто відмовляється змішувати дві незалежні історії, і це осмислена поведінка, а не баг. За п’ять хвилин ви не лише зрозумієте, чому виникає ця помилка, а й навчитеся виправляти її в будь-якій ситуації: під час першого пушу, після втрати .git та при об’єднанні різнорідних проєктів.

💡 Швидкий огляд:

  • Коли Git відмовляється зливати незв’язані гілки та чому це правильно
  • Прапор --allow-unrelated-histories, універсальне рішення для pull, merge і першого пушу
  • Покрокові сценарії: клонування без історії, новий репозиторій, rebase і force-push
  • Що робити, якщо прапор не допоміг, і як не доводити до цієї помилки в майбутньому

Що означає помилка та чому Git її видає

Git відстежує історію через ланцюжок комітів. Кожен коміт посилається на батьківський, так вибудовується граф, за яким Git розуміє, що звідки взялося. Коли ви робите git merge, Git шукає спільного предка у двох гілок і від нього обчислює різницю.

Але іноді спільного предка просто немає. Два графи комітів не перетинаються, як два окремі проєкти, які ніколи не знали одне про одного. У такій ситуації Git відмовляється зливати історію наосліп і викидає:

1fatal: refusing to merge unrelated histories

Це не помилка у звичному сенсі. Це захист: Git каже вам «я не розумію, як ці дві історії пов’язані, тому не буду гадати». Рішення існує, і воно вбудоване в Git, починаючи з версії 2.9.0 (випущена в червні 2016 року).

Два типові сценарії, які призводять до помилки

Перший сценарій, **пошкодження або видалення директорії **.git. Ви клонували проєкт, попрацювали з кодом, але папка .git виявилася видаленою (випадково, антивірусом або під час копіювання без прихованих файлів). Git втрачає всю локальну історію і під час спроби git push або git pull сприймає ваш робочий каталог як абсолютно новий проєкт, ніяк не пов’язаний із віддаленим репозиторієм.

Другий сценарій, новий репозиторій зустрічається з наявним. Ви зробили git init, додали кілька комітів локально, а потім спробували підключити віддалений репозиторій, у якому вже є своя історія. Git бачить два незалежні графи комітів і відмовляється їх змішувати. Таке часто трапляється, коли ви починаєте проєкт з нуля, а потім вирішуєте завантажити його на GitHub поверх наявного репозиторію, або коли переносите код з одного проєкту в інший.

Обидва сценарії вирішуються одним і тим самим механізмом, але перед його застосуванням варто зрозуміти, що саме ви хочете отримати в результаті: злиття двох історій в одну чи повну заміну однієї історії іншою.

Рішення: прапор --allow-unrelated-histories

Ключ до виправлення, прапор --allow-unrelated-histories. Він явно каже Git: «Я знаю, що в цих гілок немає спільного предка, і я усвідомлено хочу їх злити». Прапор працює з обома основними командами, git pull і git merge.

**Для **git pull (найчастіший випадок):

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

Замініть main на назву вашої гілки, якщо вона відрізняється (master, develop тощо). Git створить merge-коміт, який з’єднає дві незалежні історії. Швидше за все, відкриється редактор для повідомлення коміту, опишіть, навіщо ви об’єднуєте історії, збережіть і закрийте редактор.

**Для **git merge (коли гілки локальні):

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

Після успішного злиття Git запропонує запушити результат. Не забудьте це зробити:

1git push origin main

Важливий нюанс: --allow-unrelated-histories не усуває конфлікти злиття. Якщо в обох гілках є файли з однаковими іменами, Git все одно попросить вас вирішити конфлікти вручну, прапор відповідає лише за з’єднання історій, а не за вміст файлів.

Покрокові сценарії для різних ситуацій

Ситуація 1: перший пуш у непорожній віддалений репозиторій

Ви створили проєкт локально (git init → коміти), а на GitHub уже є репозиторій із README.md і .gitignore. Прямий git push не пройде, тому що віддалена гілка містить коміти, яких у вас немає.

Правильна послідовність:

Спочатку підтягніть віддалену історію та злийте її з вашою локальною:

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

Вирішіть конфлікти, якщо вони є (зазвичай конфліктує README.md), зробіть коміт злиття, потім:

1git push origin main

Ситуація 2: відновлення після втрати.git

Папка .git видалена, але робочий каталог цілий. Відновити зв’язок із віддаленим репозиторієм можна без втрати незакомічених змін:

1git init
2git remote add origin <url-репозитория>
3git fetch origin
4git reset --mixed origin/main

Команда git reset --mixed синхронізує індекс Git із віддаленою гілкою, але зберігає всі ваші робочі файли недоторканими. Після цього додайте зміни та зробіть новий коміт:

1git add .
2git commit -m "Восстановление после потери .git"
3git push origin main

Цей підхід кращий за --allow-unrelated-histories, тому що він не створює штучний merge-коміт і зберігає історію чистою.

Ситуація 3: rebase з незв’язаними історіями

Команда git rebase теж може видати цю помилку, особливо часто під час використання прапора --preserve-merges (зараз його замінено на --rebase-merges). Рішення, додати --allow-unrelated-histories:

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

Але будьте обережні: rebase переписує історію, і якщо хтось іще працює з цією гілкою, ви створите їм проблеми. Для спільних гілок завжди віддавайте перевагу merge.

Що робити, якщо прапор не допоміг

Іноді --allow-unrelated-histories відпрацьовує без помилок, але результат виявляється не тим, що ви хотіли.

Проблема: merge-коміт засмічує історію. Якщо ви об’єднали два великі проєкти, граф комітів стає важкочитаним. У цьому випадку розгляньте альтернативу, перенесення файлів зі збереженням історії через git format-patch і git am:

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

Проблема: після злиття проєкт не компілюється. Злиття незв’язаних історій може призвести до дублювання файлів конфігурації, конфліктів залежностей або несумісних версій пакетів. Після --allow-unrelated-histories завжди перевіряйте: залежності (npm install / composer install), конфігураційні файли (.env, config/), шляхи та імпорти в коді. Краще витратити п’ять хвилин на перевірку зараз, ніж розбиратися з падаючим білдом у CI пізніше.

Проблема: ви передумали. Відкотити злиття незв’язаних історій можна стандартним способом, git reset --hard HEAD~1 (якщо ви ще не пушили результат) або git revert -m 1 HEAD (якщо вже запушили).

Як уникнути помилки в майбутньому

Три прості правила, які позбавлять вас цієї помилки в повсякденній роботі.

Не видаляйте .git без крайньої потреби. Якщо потрібно скопіювати код без історії, використовуйте git archive або копіюйте файли, виключаючи приховану папку .git усвідомлено, а не випадково.

Не створюйте новий репозиторій усередині наявного. Якщо вам потрібно виділити частину кодової бази в окремий проєкт, використовуйте git subtree split або git filter-branch (зараз рекомендується git filter-repo). Ці інструменти збережуть історію потрібних файлів, і Git знатиме, звідки вони взялися.

Перед git init у папці з кодом завжди перевіряйте, чи немає там уже репозиторію: git status. Якщо Git відповідає fatal: not a git repository, можна ініціалізувати. Якщо показує статус, ви вже всередині наявного репозиторію і git init тут не потрібен.

Тим, хто тільки починає працювати з Git, рекомендуємо наш посібник «Git інструкція для початківців», там покроково розібрано SSH-ключі, створення репозиторію та повний цикл роботи з GitHub. А якщо Git ще не встановлено, почніть з інструкції «Як встановити Git у Windows».

⁉️🤔 Часті питання

У яких версіях Git працює --allow-unrelated-histories?

Прапор з’явився в Git 2.9.0 (червень 2016) і присутній у всіх наступних версіях. Якщо ваша версія Git старіша, оновіть її: команда git --version покаже поточну, а git update-git-for-windows (на Windows) або пакетний менеджер вашої системи оновить до актуальної. Перевірити версію Git найпростіше командою git --version у терміналі. На середину 2026 року актуальною є гілка 2.48+. Якщо ви на Windows і Git встановлювався дуже давно, завантажте свіжий інсталятор з git-scm.com, автооновлення в старих версіях працювало нестабільно.

Чи можна використовувати прапор із git push безпосередньо?

Ні, git push не приймає --allow-unrelated-histories. Push не створює злиття, він лише надсилає наявні коміти. Помилка «unrelated histories» під час push означає, що ваша локальна гілка та віддалена розійшлися на рівні історії. Рішення: спочатку git pull --allow-unrelated-histories, вирішіть конфлікти, і тільки потім git push. Формально --allow-unrelated-histories працює з git fetch + git merge і з git pull (який усередині робить fetch + merge). Push залишається окремою операцією, яку ви виконуєте після успішного злиття. Не намагайтеся обійти це через --force, ви втратите чужі коміти на віддаленому репозиторії.

Що краще для чистоти історії: merge чи rebase?

Для з’єднання незв’язаних історій однозначно merge. Rebase у цьому контексті створює більше проблем, ніж вирішує: він намагається переграти коміти однієї гілки поверх іншої, але без спільного предка це призводить до конфліктів на кожному коміті. Merge із --allow-unrelated-histories робить рівно те, що потрібно, створює одну точку з’єднання двох графів, після якої історія єдина. Виняток, коли ви навмисно хочете переписати історію і точно знаєте, що робите. Наприклад, під час перенесення коду з одного репозиторію в інший з очищенням від старих комітів. У цьому випадку git rebase --allow-unrelated-histories може бути осмисленим, але для повсякденної роботи вибирайте merge.

Я втратив папку .git, але в мене є незакомічені зміни. Я їх втрачу?

Ні, не втратите. Сама папка .git містить лише історію та метадані Git, але не ваші робочі файли. Усі змінені, нові та навіть незакомічені файли залишаться в робочому каталозі недоторканими. Процедуру відновлення описано в розділі «Ситуація 2» вище, git initgit remote addgit fetchgit reset --mixed. Ключовий момент: використовуйте саме --mixed, а не --hard. Прапор --mixed скидає індекс, але зберігає всі зміни у файлах. Якщо ви не впевнені, зробіть резервну копію всієї папки проєкту перед відновленням — це займе десять секунд і повністю виключить ризик втрати даних за будь-якої нестандартної ситуації.

Помилка виникає під час клонування через IDE. Це та сама проблема?

Так, та сама. Деякі IDE (наприклад, PHPStorm, Visual Studio, старі версії IntelliJ) під час створення проєкту з шаблону ініціалізують новий Git-репозиторій, а потім намагаються підключити віддалений. Виходить рівно другий сценарій із початку статті. Рішення те саме: відкрийте термінал у папці проєкту та виконайте git pull origin main --allow-unrelated-histories. Після ручного злиття IDE підхопить новий стан автоматично, достатньо оновити вікно проєкту або натиснути Refresh на панелі Git.

Чи варто боятися помилки «unrelated histories»?

Ні. Це одна з найбезпечніших помилок Git, вона не пошкоджує дані, не видаляє файли та не заважає продовжити роботу. Прапор --allow-unrelated-histories, не милиця й не обхідний шлях, а документована можливість, спеціально додана розробниками Git для випадків, коли ви усвідомлено хочете з’єднати дві незалежні історії.

Освоївши цю команду, ви отримуєте в розпорядження потужний інструмент: тепер ви можете об’єднувати проєкти будь-якого ступеня ізольованості, переносити код між репозиторіями та відновлювати роботу після втрати .git, і все це без паніки та перестворення репозиторію з нуля. Якщо Git сьогодні чогось вас і навчив, то це того, що «fatal» у його повідомленнях не означає «фатально для проєкту», він означає «я не буду гадати, скажи мені явно, що робити».