1. Что такое ветки и зачем они нужны?
Работа с branches (ветками) в Git — это один из ключевых аспектов управления версиями, который позволяет параллельно вести несколько линий разработки в одном репозитории. Ветвление делает Git мощным инструментом для совместной работы, экспериментов и управления различными версиями проекта.
gitGraph
commit id: "Initial setup"
commit id: "Add base features"
branch feature/new-idea
checkout feature/new-idea
commit id: "Implement new logic"
commit id: "Refactor the logic"
checkout main
commit id: "Urgent bugfix on main"
merge feature/new-idea
commit id: "Prepare for release"
main отходит новая ветка,
feature/new-idea, для безопасной разработки. После завершения работы она сливается обратно в
main.
Представьте, что вы хотите что-то серьезно переделать в вашем проекте или провести рискованный эксперимент. Как бы вы поступили без Git? Скорее всего, скопировали бы весь проект в новую папку и работали в ней. Если результат понравится — перенесли бы его в основную папку. Если нет — просто удалили бы копию.
Ветки в Git работают по тому же принципу, но гораздо элегантнее. Давайте рассмотрим на примере написания книги:
- У вас есть готовая рукопись (это ваша основная ветка
main). - Вы хотите написать альтернативную концовку (создаете новую ветку, например
feature/new-idea). - Вы пишете новую концовку, не затрагивая основной текст рукописи (работаете в новой ветке).
- Если новая концовка окажется лучше, вы заменяете ею старую (делаете слияние веток —
merge). - Старый черновик с ненужной концовкой можно удалить (удаляете ветку).
2. Создание новой ветки и работа в ней
Шаг 1. Откройте меню управления ветками.
На главной панели инструментов, рядом с названием проекта находится виджет, отображающий имя текущей ветки (по умолчанию — main). Нажмите на него и выберите + New Branch.
Шаг 2. Имя новой ветки.
Хорошая практика — называть ветки в соответствии с задачей, которую вы решаете. Например, feature/add-usage-examples.
После создания ветки IDE автоматически переключится на нее. Вы увидите новое имя в том же виджете.
Шаг 3. Внесите и закоммитьте изменения.
Теперь вы находитесь в своей "песочнице". Давайте добавим в наш файл README.md новый раздел с примерами использования. Внесите изменения и сделайте commit, как вы научились в прошлой лекции.
3. Переключение между ветками
Ваши изменения с примерами использования теперь надежно сохранены в ветке feature/add-usage-examples. Давайте вернемся в основную ветку main и посмотрим, что там.
Шаг 1. Снова нажмите на виджет с именем текущей ветки в левом верхнем углу.
Шаг 2. В списке Local или Recent выберите ветку main, и в появившемся подменю нажмите Checkout.
Шаг 3. Проверьте результат.
Как только вы переключитесь, откройте файл README.md. Вы увидите, что раздела с примерами использования в нем нет! Он остался в другой ветке. Таким образом, вы можете работать над новой функциональностью, не затрагивая стабильную версию в ветке main.
4. Слияние веток
Команда merge берет все коммиты из ветки feature/add-usage-examples (в данном случае, коммит C3) и объединяет их с текущей веткой main, создавая новый коммит слияния.
gitGraph
commit id: "C1"
commit id: "C2"
branch feature/add-examples
checkout feature/add-examples
commit id: "C3: Add new section"
checkout main
merge feature/add-examples
Итак, вы закончили работу над своей задачей в ветке feature/add-usage-examples и хотите добавить эти изменения в основной проект.
Шаг 1. Переключитесь на целевую ветку.
Убедитесь, что вы находитесь в той ветке, КУДА хотите добавить изменения. В нашем случае это main.
Шаг 2. Выполните слияние.
Снова нажмите на виджет управления ветками. В списке выберите ветку, ОТКУДА вы хотите взять изменения (feature/add-usage-examples), и в подменю выберите Merge 'feature/add-usage-examples' into 'main'.
Шаг 3. Проверьте результат.
Теперь в файле README.md в ветке main появился ваш новый раздел с примерами. Вы успешно объединили свою работу с основной версией проекта!
5. Конфликты при слиянии
Для новичков слово "конфликт" часто звучит пугающе, но в командной разработке это абсолютная норма. Конфликт происходит, когда в обеих сливаемых ветках были изменены одни и те же строки в одном и том же файле. Git не может сам решить, чья версия правильнее, и просит вашей помощи.
И здесь проявляется вся мощь IntelliJ IDEA (и CLion). Разрешать конфликты в терминале — то еще удовольствие, но встроенный в IDE инструмент трехстороннего слияния (3-way merge) превращает эту задачу в наглядный и простой процесс.
gitGraph
commit id: "C1: Общая база"
branch feature/new-title
checkout main
commit id: "C2: Изменение в main"
checkout feature/new-title
commit id: "C3: Изменение в feature"
main и
feature/new-title, имеют новые коммиты (C2 и C3), которые основаны на общем предке (C1). Это гарантированно приведет к конфликту при слиянии.
Давайте смоделируем конфликт:
- Убедитесь, что вы находитесь в ветке
main, и у вас нет несохраненных изменений в окне Commit. - Создайте новую ветку
feature/new-title, но не переключайтесь на нее пока. Убедитесь, что галочка Checkout branch снята. - Теперь, находясь в ветке
main, измените первую строку вREADME.mdна "My Awesome Project" и сделайтеcommit. - Переключитесь на ветку
feature/new-title. Вы увидите, что первая строка вREADME.mdздесь осталась старой: это состояние файла на момент создания ветки. Измените эту же строку на "My Super Project" и сделайтеcommit. - Вернитесь в ветку
mainи выполните слияние сfeature/new-title.
Теперь Git увидит, что обе истории изменены в одном и том же месте. Он покажет вам окно для разрешения конфликта (Merge Conflicts).
Нажмите кнопку Merge, чтобы открыть инструмент разрешения конфликтов. Что вы здесь видите:
- Слева (Your changes): версия файла из вашей текущей ветки (куда вы сливаете —
main). - Справа (Changes from branch): версия файла из ветки, которую вы сливаете.
- По центру (Result): итоговая версия файла, которую вы должны собрать руками.
Вы можете нажимать на стрелочки >> или << (или на крестики для отмены), чтобы принять целиком тот или иной вариант. Также вы можете просто написать правильный текст в центральной панели.
Когда результат в центральной панели вас устроит и все конфликты будут разрешены, нажмите Apply (или Save Changes and Finish). IDE сама создаст специальный коммит слияния, и конфликт будет решен.
Почему иногда не возникает конфликта?
Может возникнуть ситуация, когда вы выполнили все шаги, а конфликта не произошло. Чаще всего это связано с тем, что Git смог выполнить fast-forward merge (слияние перемоткой). Это происходит, когда история одной ветки просто продолжила историю другой, и они не расходились параллельно.
Пример:
- У вас есть некий коммит в
main(допустим, C1). - Вы делаете новый коммит в ветке
mainс текстом "My Awesome Project". Веткаmainтеперь указывает на коммит C2 (main -> C1 -> C2). - Вы создаете ветку
feature/new-titleиз текущего положения ветки main. Это значит, что новая ветка тоже начинается с коммита C2. - Вы делаете коммит в
feature/new-titleс текстом "My Super Project". Эта ветка "уходит вперед" и теперь указывает на коммит C3 (feature/new-title -> C1 -> C2 -> C3). - Вы возвращаетесь в
main(которая все еще на коммите C2) и даете команду слить feature/new-title.
Git смотрит на ситуацию и видит, что ветка main является прямым предком ветки feature/new-title. В истории main не было никаких новых коммитов, пока вы работали в другой ветке. Git думает: "А, так тут просто нужно перемотать main вперед до коммита C3. Никаких противоречий нет". И он просто перемещает указатель main на коммит C3 без конфликтов.
gitGraph
commit id: "C1"
commit id: "C2"
branch feature/new-title
checkout feature/new-title
commit id: "C3"
checkout main
merge feature/new-title
6. Просмотр истории изменений
Чтобы лучше понимать, что происходит в вашем проекте, полезно смотреть на его историю.
Откройте окно инструмента Git (обычно это иконка на левой боковой панели или внизу окна IDE) и выберите вкладку Log или Show Git Log в панеле инструментов Git. Вы увидите графическое представление всех ваших веток и коммитов. Это поможет наглядно отследить, какая ветка от какой отделилась и где они были слиты.
Здесь вы можете кликнуть на любой коммит, чтобы увидеть, какие изменения в него вошли, кто и когда его сделал. Это настоящая машина времени для вашего кода!
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ