Собрать работу из веток в одну и разобраться, когда изменения пересеклись
main через git mergeСлияние всегда выполняется в текущую ветку. Чтобы влить feature/projects в main, сначала переходят на main:
$ git switch main
$ git merge feature/projects
Частая ошибка — выполнить git merge main, находясь в ветке функции. Это тоже слияние, но в обратную сторону: основная ветка вливается в ветку функции. Так делают намеренно, чтобы подтянуть свежие изменения, — но не когда хотят выложить функцию.
Если после ответвления в main ничего не коммитили, сливать нечего — достаточно передвинуть указатель main вперёд:
До: e15d2f0 ◀── a3f9c21 ◀── 5d8e0f3 ◀── 9c2a7e1
│ │
main feature/projects
$ git merge feature/projects
Updating a3f9c21..9c2a7e1
Fast-forward
projects.html | 42 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 42 insertions(+)
После: e15d2f0 ◀── a3f9c21 ◀── 5d8e0f3 ◀── 9c2a7e1
│
main, feature/projects
История остаётся прямой линией, нового коммита нет. Минус: из истории не видно, что эти коммиты делались в отдельной ветке.
Если пока шла работа в ветке, в main появились другие коммиты, истории разошлись. Git находит общего предка, сводит изменения обеих веток и создаёт коммит слияния — коммит с двумя родителями:
$ git merge feature/projects
Merge made by the 'ort' strategy.
projects.html | 42 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 42 insertions(+)
$ git log --oneline --graph
* c71b4a0 (HEAD -> main) Merge branch 'feature/projects'
|\
| * 9c2a7e1 (feature/projects) Добавить карточки проектов
| * 5d8e0f3 Добавить раздел с проектами
* | f3a01c9 Исправить телефон в контактах
|/
* a3f9c21 Добавить форму обратной связи
Git откроет редактор с готовым сообщением «Merge branch …» — его можно оставить. Флаг --no-ff заставляет создать коммит слияния даже там, где возможна перемотка. Многие команды так и работают: каждая функция в истории видна как отдельная «петля».
Конфликт возникает, когда обе ветки изменили одни и те же строки одного файла по-разному. Git не знает, какой вариант правильный, и оставляет решение вам. Изменения в разных файлах или в разных местах одного файла сливаются автоматически.
$ git merge fix/contact-phone
Auto-merging contacts.html
CONFLICT (content): Merge conflict in contacts.html
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: contacts.html
В файле Git размечает спорный фрагмент маркерами:
<p>Пишите на почту или звоните:</p>
<<<<<<< HEAD
<p>Телефон: +7 (812) 555-01-01</p>
=======
<p>Телефон: +7 (921) 555-02-02, с 10 до 19</p>
>>>>>>> fix/contact-phone
<<<<<<< HEAD … ======= — вариант текущей ветки (куда вливаем).======= … >>>>>>> fix/contact-phone — вариант вливаемой ветки.Разрешить конфликт — значит отредактировать файл так, как он должен выглядеть в итоге, и убрать все маркеры. Итог не обязан совпадать ни с одним из вариантов: здесь правильно взять новый номер и оставить часы работы.
<p>Пишите на почту или звоните:</p>
<p>Телефон: +7 (921) 555-02-02, с 10 до 19</p>
$ git add contacts.html # отметить конфликт как разрешённый
$ git commit # завершить слияние, сообщение уже подготовлено
[main 2e8d9f4] Merge branch 'fix/contact-phone'
git add найдите оставшиеся маркеры: git diff --check покажет их. Забытый <<<<<<< в HTML сломает вёрстку, в коде — сборку.Если запутались и хотите начать заново — отмените слияние. Рабочий каталог вернётся к состоянию до git merge:
$ git merge --abort
Влитая ветка больше не нужна: её коммиты уже есть в main. Удалите её, чтобы список веток показывал только текущую работу:
$ git branch --merged # ветки, уже влитые в текущую
feature/projects
fix/contact-phone
* main
$ git branch -d feature/projects fix/contact-phone
Deleted branch feature/projects (was 9c2a7e1).
Deleted branch fix/contact-phone (was 7e4c1d2).
main в свою ветку, чтобы разрешать расхождения по одному.git switch main, потом git merge веткаgit add, git commitgit merge --abort возвращает всё как было до слияния