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. Откройте меню управления ветками.
В верхней панели IDE находится виджет, отображающий имя текущей ветки (по умолчанию — 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)
Команда merge берет все коммиты из ветки feature/add-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 в main.
Шаг 3. Проверьте результат.
Теперь в файле README.md в ветке main появился ваш новый раздел с примерами. Вы успешно объединили свою работу с основной версией проекта!
5. Конфликты при слиянии: не бойтесь, это нормально!
Иногда при слиянии веток возникают конфликты. Это происходит, когда в обеих ветках были изменены одни и те же строки в одном и том же файле. Git не может сам решить, какая версия правильная, и просит вашей помощи.
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, и у вас нет несохраненных изменений. - Сразу создайте новую ветку
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 увидит, что обе ветки имеют новые, расходящиеся истории от их общего предка. В обеих историях изменена одна и та же строка, поэтому Git не сможет выбрать, какая версия правильная, и покажет вам окно для разрешения конфликта.
Merge Revision
Что вы здесь видите:
- Слева (Your changes): версия файла из вашей текущей ветки (
main). - Справа (Changes from branch...): версия файла из ветки, которую вы сливаете.
- По центру (Result): итоговая версия файла, которую вы должны собрать.
Вы можете нажимать на стрелочки >> или <<, чтобы принять целиком тот или иной вариант.
Когда результат в центральной панели вас устроит, нажмите Apply. 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. Вы увидите графическое представление всех ваших веток и коммитов. Это поможет наглядно отследить, какая ветка от какой отделилась и где они были слиты.
Здесь вы можете кликнуть на любой коммит, чтобы увидеть, какие изменения в него вошли, кто и когда его сделал. Это настоящая машина времени для кода!
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ