Пошук уроків, статей та іншого контенту
Навчитеся редагувати конфліктні ділянки, позначати їх вирішеними та завершувати або скасовувати злиття.
Git може автоматично об’єднати зміни, якщо вони стосуються різних рядків або файлів. Конфлікт виникає, коли Git не може однозначно визначити, яку версію потрібно залишити.
Типовий сценарій:
У поточній гілці змінено один і той самий рядок.
В іншій гілці цей рядок також змінено.
Виконується git merge.
Git зупиняє злиття й очікує, що конфлікт буде вирішено вручну.
Наприклад, у гілці main і в гілці feature/login файл config.js містить різні значення для одного параметра.
Після спроби злиття Git може вивести:
Auto-merging config.js
CONFLICT (content): Merge conflict in config.js
Automatic merge failed; fix conflicts and then commit the result.Це означає, що злиття ще не завершене.
Перший крок після повідомлення про конфлікт — перевірити стан репозиторію:
git statusПриклад результату:
On branch main
You have unmerged paths.
(fix conflicts and run "git commit")
(use "git merge --abort" to abort the merge)
Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified: config.jsКоманда git status показує:
які файли мають конфлікти;
чи потрібно додати файл після виправлення;
чи можна скасувати поточне злиття.
Не слід одразу виконувати git commit -a: спочатку потрібно вручну опрацювати конфліктні файли та додати їх до індексу.
Git вставляє у файл спеціальні маркери:
<<<<<<< HEAD
API_URL=https://api.example.com
=======
API_URL=https://staging.example.com
>>>>>>> feature/loginКонфліктна ділянка має таку структуру:
<<<<<<< HEAD — початок версії з поточної гілки;
рядки до ======= — варіант із поточної гілки;
======= — роздільник між двома варіантами;
рядки до >>>>>>> feature/login — варіант із гілки, яку приєднують;
>>>>>>> feature/login — кінець конфліктної ділянки.
Під час звичайного git merge:
HEAD — поточна гілка, у яку виконується злиття;
feature/login — гілка, зміни якої приєднуються.
Ці маркери не є частиною правильного коду. Їх потрібно видалити.
Розглянемо файл до злиття:
const config = {
apiUrl: "https://api.example.com",
timeout: 5000
};
module.exports = config;Після конфлікту він може виглядати так:
const config = {
<<<<<<< HEAD
apiUrl: "https://api.example.com",
=======
apiUrl: "https://staging.example.com",
>>>>>>> feature/login
timeout: 5000
};
module.exports = config;Потрібно вирішити, який варіант залишити. Наприклад, можна вибрати адресу для staging:
const config = {
apiUrl: "https://staging.example.com",
timeout: 5000
};
module.exports = config;Після редагування у файлі не повинно залишитися жодного маркера:
<<<<<<<
=======
>>>>>>>Потім перевірте, що таких маркерів більше немає:
grep -nE '<<<<<<<|=======|>>>>>>>' config.jsЯкщо команда нічого не вивела, маркери у файлі відсутні.
Після виправлення файлу потрібно додати його до індексу:
git add config.jsУ Git команда git add у цьому випадку означає не просто «підготувати зміни». Вона повідомляє Git, що конфлікт у файлі опрацьовано.
Перевірте стан:
git statusТепер файл може відображатися в секції змін, підготовлених для коміту:
All conflicts fixed but you are still merging.
(use "git commit" to conclude merge)
Changes to be committed:
modified: config.jsЯкщо конфліктних файлів кілька, кожен із них потрібно виправити й додати окремо:
git add config.js routes.js package.jsonМожна також додати всі виправлені файли:
git add .Однак перед цим варто перевірити зміни, щоб випадково не додати зайві файли.
Переглянути зміни, підготовлені після вирішення конфлікту, можна так:
git diff --stagedПеревірте:
чи всі маркери конфлікту видалено;
чи залишено правильний варіант коду;
чи не втрачено потрібні рядки з обох гілок;
чи файл залишається синтаксично правильним.
Якщо в проєкті є тести або перевірка форматування, запустіть їх до завершення злиття. Наприклад:
npm testКоманда залежить від конкретного проєкту. Якщо тестів немає, хоча б перевірте файли вручну та виконайте доступну перевірку синтаксису.
Коли всі конфлікти виправлено й файли додано до індексу, завершіть merge-комітом:
git commitGit зазвичай відкриє редактор із підготовленим повідомленням, наприклад:
Merge branch 'feature/login' into mainЗбережіть повідомлення та закрийте редактор.
Або вкажіть повідомлення без відкриття редактора:
git commit -m "Merge feature/login into main"Після цього перевірте стан:
git statusОчікуваний результат:
On branch main
nothing to commit, working tree cleanЗлиття завершено, а merge-коміт містить результат об’єднання двох гілок.
Нижче наведено типовий порядок дій:
# Перейти до гілки, у яку потрібно злити зміни
git switch main
# Запустити злиття гілки feature/login
git merge feature/login
# Переглянути файли з конфліктами
git status
# Після ручного редагування перевірити підготовлені зміни
git diff
# Позначити виправлений файл як вирішений
git add config.js
# Переглянути зміни, які потраплять до merge-коміту
git diff --staged
# Завершити злиття
git commit -m "Merge feature/login into main"
# Переконатися, що незавершених змін немає
git statusКоманди git diff і git diff --staged мають різне призначення:
git diff показує зміни, які ще не додано через git add;
git diff --staged показує зміни, уже підготовлені до коміту.
Іноді не потрібно об’єднувати вміст вручну. Можна повністю залишити версію з поточної гілки або версію з гілки, яку приєднують.
Залишити версію поточної гілки:
git restore --ours -- config.js
git add config.jsЗалишити версію гілки, яку приєднують:
git restore --theirs -- config.js
git add config.jsУ контексті:
--ours — варіант поточної гілки;
--theirs — варіант іншої гілки, яку зливають.
Після git restore файл також потрібно виконати git add, щоб позначити конфлікт як вирішений.
Ці команди замінюють увесь файл відповідним варіантом. Якщо потрібно зберегти частини обох версій, краще відредагувати файл вручну.
Якщо конфліктів надто багато або злиття було запущено помилково, його можна скасувати:
git merge --abortЦя команда:
припиняє поточну операцію злиття;
повертає робоче дерево до стану до git merge;
не створює коміт.
Перевірте результат:
git statusЯкщо злиття ще триває, Git зазвичай показує підказку:
(use "git merge --abort" to abort the merge)git merge --abort працює саме для незавершеного merge. Якщо злиття вже завершено комітом, ця команда його не скасує.
Дві гілки змінили ті самі рядки. Git додає маркери конфлікту, а розв’язання виконується редагуванням файлу.
deleted by usПоточна гілка видалила файл, а інша гілка його змінила. Потрібно вирішити:
Залишити видалення:
git rm path/to/file.jsЗалишити файл із гілки, яку приєднують:
git restore --theirs -- path/to/file.js
git add path/to/file.jsdeleted by themПоточна гілка змінила файл, а інша гілка його видалила.
Залишити файл:
git add path/to/file.jsВидалити файл:
git rm path/to/file.jsРішення залежить від очікуваного стану проєкту, а не лише від того, яку дію пропонує Git.
Файл із <<<<<<<, ======= або >>>>>>> може залишитися формально доданим до індексу, але міститиме некоректний код.
Перед комітом перевіряйте:
grep -R -nE '<<<<<<<|=======|>>>>>>>' .Для великих проєктів краще виконувати перевірку лише для змінених файлів, щоб не знаходити випадкові збіги в залежностях або службових файлах.
git commit до git addПісля редагування Git може й далі вважати файл конфліктним. Потрібна послідовність:
git add path/to/file
git commit--ours або --theirsЦі параметри замінюють увесь файл. Якщо в обох версіях були потрібні зміни, вони можуть бути втрачені. Перед використанням перевірте обидва варіанти:
git diff
git diff --ours
git diff --theirsПід час конфлікту команда git diff --ours показує версію поточної гілки, а git diff --theirs — версію іншої гілки.
Поки злиття не завершено або не скасовано, репозиторій перебуває в проміжному стані. Спочатку потрібно виконати одну з дій:
git commitабо:
git merge --abortGit перевіряє структуру коміту, але не визначає, чи правильна бізнес-логіка. Перед завершенням злиття перегляньте staged-зміни та запустіть тести.
Merge-конфлікт виникає, коли Git не може автоматично об’єднати зміни.
git status показує конфліктні файли та поточний стан злиття.
Маркери <<<<<<<, =======, >>>>>>> потрібно видалити вручну.
Після редагування файл позначають вирішеним командою git add.
git diff --staged допомагає перевірити майбутній merge-коміт.
Злиття завершують командою git commit.
Повністю вибрати одну версію файлу можна через git restore --ours або git restore --theirs.
Незавершене злиття скасовують командою git merge --abort.