Урок курса
Ветвление и слияние
Bash Linux + Git: от новичка до уверенного пользователяЧто такое ветка в Git?
Ветка (branch) — это независимая линия разработки, которая позволяет изолировать изменения. Основная ветка вашего репозитория — main или master. Ветвление помогает:
- Работать над новой функциональностью, не затрагивая основной код.
- Экспериментировать, не боясь сломать основную версию проекта.
- Разделять задачи между разработчиками, объединяя их работу позже.
Пример:
Вы работаете над проектом, и вам нужно добавить новую функцию. Вместо того чтобы вносить изменения в основную ветку, вы создаёте отдельную ветку feature-branch и работаете там. Если всё работает, вы объединяете её с основной веткой.
Важная модель: ветка — это указатель на коммит
Чтобы ветки не воспринимались как папки с кодом, зафиксируем модель:
-
Коммиты образуют историю (граф).
-
Ветка — это имя/указатель на последний коммит в этой линии разработки.
-
HEAD— указатель “где Вы сейчас находитесь”. ОбычноHEADпривязан к текущей ветке.
Практически это означает:
-
когда Вы делаете новый коммит, “двигается” указатель текущей ветки;
-
переключение ветки меняет, какой коммит сейчас выбран, а значит — какие версии файлов окажутся в working tree.
Проверить текущую ветку и состояние удобно так:
git status -sb
А увидеть картину истории — так:
git log --oneline --decorate --graph --all
Создание и управление ветками
Создание новой ветки
git branch feature-branch
Это создаёт новую ветку feature-branch, но Вы всё ещё находитесь в текущей ветке. Чтобы переключиться на неё, используйте:
git switch feature-branch
Создание и переключение одновременно
git switch -c new-feature
Просмотр списка веток
git branch
Текущая ветка будет отмечена звёздочкой.
Примечание по командам: в старых материалах часто встречается
git checkout. Сейчас для веток предпочтительнееgit switch(а для файлов —git restore).checkoutумеет и то и другое, но из-за этого новички постоянно путаются.
Типы слияний веток (merge) — fast-forward и no-fast-forward
Перед слиянием убедитесь, что Вы находитесь в ветке-приёмнике (куда вливаете). Если Вы хотите влить feature-branch в основную ветку, сначала перейдите в неё:
git switch main
Fast-forward merge
Когда в основной ветке не было изменений с момента создания новой ветки, слияние будет “прямым” (fast-forward):
git merge feature-branch
Это просто перемещает указатель основной ветки на последний коммит feature-branch.
No-fast-forward merge
Если Вы хотите сохранить факт ветвления в истории, используйте --no-ff:
git merge --no-ff feature-branch
Это создаст новый коммит слияния, даже если изменения могли бы быть объединены напрямую.
Когда что выбирать (коротко):
-
fast-forward — история линейная, “ветки как будто не было”;
-
--no-ff— в истории явно видно, что была отдельная feature-ветка.
Разрешение конфликтов (Ваш материал + что делать, если передумали)
Конфликт возникает, если изменения в разных ветках затрагивают одну и ту же часть файла. В этом случае Git не может автоматически объединить изменения.
Пример конфликта:
<<<<<<< HEAD Текст из основной ветки ======= Текст из feature-branch >>>>>>> feature-branch
Как разрешить конфликт:
1. Отредактируйте файл, выбрав правильное содержимое (можно принять текущее/входящее или написать свой итоговый вариант).
2. Добавьте файл в индекс:
git add conflicted-file.txt
3. Завершите слияние:
git commit -m "Решён конфликт при слиянии"
Если Вы начали merge и хотите откатить процесс слияния целиком, используйте:
git merge --abort
Это вернёт репозиторий к состоянию до git merge (если это возможно).
Давайте посмотрим на следующий скрипт, который подготавливает наш репозиторий к мердж-конфликту.
#!/usr/bin/env bash
set -e
# 1. Инициализируем новый репозиторий
git init conflict-demo
cd conflict-demo
# 2. Делает первый коммит с базовой версией greet.js
cat > greet.js << 'EOF'
function greet() {
console.log("Hello, world!");
}
EOF
git add greet.js
git commit -m "Add initial greet.js"
# 3. Создаём feature-branch и меняем реализацию
git checkout -b feature-branch
cat > greet.js << 'EOF'
function greet(name) {
console.log(\`Hello, \${name}!\`);
}
EOF
git add greet.js
git commit -m "Feature: make greet accept a name"
# 4. Возвращаемся на master и вносим другое изменение в ту же строку
git checkout master
cat > greet.js << 'EOF'
function greet() {
console.log("Hi there!");
}
EOF
git add greet.js
git commit -m "Master: change greeting text to informal"
После чего в репозитории выполним git merge feature-branch и увидим следующую картину
Осталось принять текущее или входящее изменение (или написать что нибудь свое, что тоже вариант). По факту нам нужно просто изменить greet.js произвольным образом, VSCode в данном случае лишь предлагает наиболее популярные варианты.
После чего сделав git add greet.js и git commit мы совершим необходимый merge реквест. (Победа)
Здесь мы рассмотрели лишь один из типов конфликта, на самом деле их довольно много, однако решаются все однотипно.
Практическая часть
Шаги для выполнения задания:
- Создайте новую ветку
feature-branchи переключитесь на неё.git switch -c feature-branch - Внесите изменения в файл
README.mdи сделайте коммит. - Переключитесь обратно на основную ветку (
main) и выполните слияние:git switch main git merge feature-branch - Если возникнет конфликт, решите его и завершите слияние.
Итоги урока
В этом уроке вы узнали:
- Что такое ветка в Git и зачем она нужна.
- Как создавать и управлять ветками.
- Типы слияний веток: fast-forward и no-fast-forward.
- Как разрешать конфликты при слиянии.
Продолжить с сохранением прогресса
Перейдите к уроку в учебном кабинете.
