git merge
Слияние веток в Git (merge) — это перенос работы из одной ветки в другую командой git merge: коммиты ветки становятся частью main. Вы сольёте в main ветки feature/projects и feature/footer, увидите два вида слияния — перемотку и merge-коммит — и удалите ветки, которые своё отработали.
Страница проектов уже есть в ветке feature/projects, но main о ней ничего не знает. Черновик готов — пора переносить его в чистовик.
Главное правило
Сливают в текущую ветку. Сначала встаньте на ветку, которая принимает изменения (main), затем назовите ветку, которую вливаете. Читается так: «в main влить feature/projects».
Но сначала доделаем ветку: на главной нужна ссылка на новую страницу. Перейдите на feature/projects и добавьте в index.html внутри раздела projects, сразу после </ul>, одну строку:
<section id="projects">
<h2>Мои проекты</h2>
<ul>
<li>Сайт-визитка</li>
<li>Список дел</li>
</ul>
<p><a href="projects.html">Все проекты</a></p>
</section>
$ git switch feature/projects
Switched to branch 'feature/projects'
$ git add index.html
$ git commit -m "Добавить ссылку на страницу проектов"
[feature/projects 5dd4568] Добавить ссылку на страницу проектов
1 file changed, 1 insertion(+)
В ветке два коммита. Теперь сливаем:
$ git switch main
Switched to branch 'main'
$ git merge feature/projects
Updating 5acc5ae..5dd4568
Fast-forward
index.html | 1 +
projects.html | 14 ++++++++++++++
2 files changed, 15 insertions(+)
create mode 100644 projects.html
Разбор по строкам
Updating 5acc5ae..5dd4568—mainпередвигается с коммита5acc5aeна5dd4568.Fast-forward— способ слияния: перемотка (о нём ниже).index.html | 1 +иprojects.html | 14 ++++— что пришло вmainпо файлам: плюсы — добавленные строки.2 files changed, 15 insertions(+)— итог: два файла, 15 новых строк;create mode ... projects.html— вmainпоявился новый файл.
Откройте index.html в браузере: внизу раздела «Мои проекты» есть ссылка «Все проекты», и она ведёт на новую страницу.
Fast-forward
Пока вы работали в ветке, в main не появилось ни одного нового коммита. Значит, feature/projects — это просто main плюс два коммита сверху. Соединять нечего: Git передвигает метку main вперёд, на последний коммит ветки, как перематывают видео. Отсюда название: fast-forward, «перемотка».
До: 5acc5ae --- 294653e --- 5dd4568
^ ^
main feature/projects
После: 5acc5ae --- 294653e --- 5dd4568
^
main, feature/projects
Что на схеме: коммиты те же, сдвинулась только метка main. Нового коммита перемотка не создаёт — это видно и в истории:
$ git log --oneline -4
5dd4568 (HEAD -> main, feature/projects) Добавить ссылку на страницу проектов
294653e Добавить страницу проектов
5acc5ae Revert "Поменять цвет фона"
875cb0a Поменять цвет фона
Разбор по строкам
(HEAD -> main, feature/projects)— обе ветки теперь стоят на одном коммите, вы наmain.- Флаг
-4— показать только четыре последних коммита.
Merge-коммит
Чаще бывает иначе: пока вы делали ветку, в main тоже что-то закоммитили. Проверим на подвале. Создайте ветку feature/footer и добавьте в index.html перед </body> строку подвала (© в HTML — знак копирайта):
<footer><p>© 2026 Алекс Иванов</p></footer>
</body>
$ git switch -c feature/footer
Switched to a new branch 'feature/footer'
$ git add index.html
$ git commit -m "Добавить подвал"
[feature/footer 578f2d5] Добавить подвал
1 file changed, 1 insertion(+)
Теперь вернитесь на main и допишите в конец README.md пустую строку и строку про страницы сайта:
# portfolio
Личный сайт-визитка Алекса Иванова. Учебный проект курса по Git.
Страница на чистом HTML и CSS, без фреймворков.
Страницы: главная (index.html) и проекты (projects.html).
$ git switch main
Switched to branch 'main'
$ git add README.md
$ git commit -m "Описать страницы в README"
[main 89766ce] Описать страницы в README
1 file changed, 2 insertions(+)
$ git log --oneline --graph --all
* 89766ce (HEAD -> main) Описать страницы в README
| * 578f2d5 (feature/footer) Добавить подвал
|/
* 5dd4568 (feature/projects) Добавить ссылку на страницу проектов
* 294653e Добавить страницу проектов
* 5acc5ae Revert "Поменять цвет фона"
...
Разбор по строкам
* 89766ce (HEAD -> main)— новый коммит вmain.| * 578f2d5 (feature/footer)— коммит ветки на боковой линии.|/— здесь линии сходятся:5dd4568— общий предок, с него обе ветки разошлись.
Перемотать main теперь нельзя: у каждой ветки свой новый коммит. Git создаёт merge-коммит (коммит слияния) — особый коммит с двумя родителями, который соединяет обе линии. Выполните git merge feature/footer. Сначала откроется редактор, который вы настроили для Git, с готовым сообщением:
Merge branch 'feature/footer'
# Please enter a commit message to explain why this merge is necessary,
# especially if it merges an updated upstream into a topic branch.
#
# Lines starting with '#' will be ignored, and an empty message aborts
# the commit.
Разбор по строкам
Merge branch 'feature/footer'— готовое сообщение коммита. Обычно его оставляют как есть.- Строки с
#— комментарии, в коммит не попадут. Пустое сообщение отменит коммит. - Сохраните и закройте: в VS Code — закройте вкладку с файлом, в nano — Ctrl+O, Enter, Ctrl+X.
$ git merge feature/footer
Merge made by the 'ort' strategy.
index.html | 1 +
1 file changed, 1 insertion(+)
Разбор по строкам
Merge made by the 'ort' strategy.— слияние сделано, создан merge-коммит;ort— название алгоритма, которым Git сливает по умолчанию, выбирать ничего не нужно.index.html | 1 +— что пришло из ветки: строка подвала.
$ git log --oneline --graph -5
* d3c03bd (HEAD -> main) Merge branch 'feature/footer'
|\
| * 578f2d5 (feature/footer) Добавить подвал
* | 89766ce Описать страницы в README
|/
* 5dd4568 (feature/projects) Добавить ссылку на страницу проектов
* 294653e Добавить страницу проектов
Разбор по строкам
* d3c03bd (HEAD -> main) Merge branch 'feature/footer'— merge-коммит, на нём теперьmain.|\— в него входят две линии: у коммита два родителя,89766ceизmainи578f2d5из ветки.git log -1покажет их в строкеMerge: 89766ce 578f2d5.
Обратите внимание: Git сам собрал правку index.html из ветки и правку README.md из main. Даже если две ветки меняют один файл, но в разных местах, Git тоже соединит их сам. Сложность возникает, только когда обе ветки поменяли одни и те же строки, — это конфликт, и ему посвящён следующий урок.
Флаг --no-ff
Команда git merge --no-ff имя-ветки создаёт merge-коммит, даже когда перемотка возможна. Некоторые команды так делают, чтобы в истории было видно, где жила ветка. Нам пока хватит поведения по умолчанию.
Удаляем слитые ветки
После слияния ветка своё отработала: её коммиты уже в main. Ветка — лишь метка, поэтому удаление ветки не удаляет ни одного коммита. Сначала спросим Git, какие ветки уже слиты в текущую:
$ git branch --merged
feature/footer
feature/projects
* main
$ git branch -d feature/projects
Deleted branch feature/projects (was 5dd4568).
$ git branch -d feature/footer
Deleted branch feature/footer (was 578f2d5).
$ git branch
* main
Разбор по строкам
git branch --merged— ветки, все коммиты которых уже есть в текущей ветке. Их можно удалять.git branch -d(от delete) — удалить ветку.(was 578f2d5)— коммит, на который она указывала.* main— осталась одна ветка, а вся работа в ней.
Флаг -d безопасный: неслитую ветку он удалить откажется.
$ git branch -d feature/test
error: the branch 'feature/test' is not fully merged
hint: If you are sure you want to delete it, run 'git branch -D feature/test'
hint: Disable this message with "git config advice.forceDeleteBranch false"
Разбор по строкам
error: the branch 'feature/test' is not fully merged— «ветка слита не полностью»: в ней есть коммиты, которых нет в текущей ветке.hint: ... run 'git branch -D feature/test'— если уверены, удалите с большой-D.
Осторожно: git branch -D
Большая -D удаляет ветку без проверки. Её неслитые коммиты больше не будут видны ни в одной ветке, найти их можно будет только по reflog, и то какое-то время. Прежде чем нажать Enter, проверьте git log --oneline имя-ветки: точно ли эти коммиты не нужны?
Подробно — в документации git merge.
Практика у себя
Если вы выполняли команды по ходу урока, сверьтесь с шагами и итогом.
Шаг 1. git switch feature/projects, добавьте ссылку «Все проекты» в index.html, закоммитьте «Добавить ссылку на страницу проектов».
Шаг 2. git switch main, затем git merge feature/projects. Ожидаемо: Fast-forward и create mode 100644 projects.html.
Шаг 3. git switch -c feature/footer, добавьте подвал перед </body>, закоммитьте «Добавить подвал».
Шаг 4. git switch main, допишите строку в README.md, закоммитьте «Описать страницы в README». git log --oneline --graph --all покажет развилку.
Шаг 5. git merge feature/footer, в редакторе оставьте сообщение Merge branch 'feature/footer', сохраните и закройте. Ожидаемо: Merge made by the 'ort' strategy.
Шаг 6. Удалите обе ветки: git branch -d feature/projects и git branch -d feature/footer. Итоговая история:
$ git log --oneline --graph
* d3c03bd (HEAD -> main) Merge branch 'feature/footer'
|\
| * 578f2d5 Добавить подвал
* | 89766ce Описать страницы в README
|/
* 5dd4568 Добавить ссылку на страницу проектов
* 294653e Добавить страницу проектов
* 5acc5ae Revert "Поменять цвет фона"
...
Проверьте себя
git branchпоказывает только* main.- В
git log --oneline --graphесть merge-коммитMerge branch 'feature/footer'с двумя линиями под ним. - В папке есть
projects.html, а на главной в браузере — ссылка «Все проекты» и подвал. git status:nothing to commit, working tree clean.
Частые ошибки
Слили «не в ту сторону». Вы стояли на feature/footer и выполнили git merge main. Тогда коммиты main пришли в ветку, а сам main не изменился. Признак — первая строка git status: On branch feature/footer. Ничего не сломано: перейдите на main (git switch main) и слейте как надо: git merge feature/footer. Перед каждым слиянием проверяйте, на какой вы ветке.
Не удаляли ветки. Через месяц в git branch десяток имён, и непонятно, какие ещё в работе. Удаляйте ветку сразу после слияния; git branch --merged подскажет, какие уже не нужны.
not fully merged при -d. Git защищает коммиты, которых нет в текущей ветке. Возможно, вы стоите не на main или забыли слить ветку. Проверьте git status и git log --oneline --graph --all, и только если коммиты точно не нужны — -D.
Already up to date. Git отвечает так, если все коммиты ветки уже есть в текущей: сливать нечего. Это не ошибка.
Что важно запомнить
- Сливают в текущую ветку:
git switch main, затемgit merge имя-ветки. - Fast-forward («перемотка») —
mainне уходил вперёд, Git просто двигает метку; нового коммита нет. - Merge-коммит — обе ветки ушли вперёд; у такого коммита два родителя, сообщение по умолчанию
Merge branch '…'. - Разные места в файлах Git соединяет сам.
- Слитые ветки удаляют
git branch -d;-Dудаляет без проверки — осторожно.
Пока Git всё сливал сам: ветки меняли разные места. А что, если две ветки поменяют одну и ту же строку? Тогда Git остановится и попросит решить, какая версия верная. Это конфликт слияния — в следующем уроке разберём его спокойно и по шагам.