JavaRush /Курси /C++ SELF /Безпечні експерименти: робота з гілками

Безпечні експерименти: робота з гілками

C++ SELF
Рівень 36 , Лекція 2
Відкрита

1. Що таке гілки і навіщо вони потрібні?

Робота з branches (гілками) у Git — один із ключових аспектів керування версіями. Вона дає змогу паралельно вести кілька ліній розробки в межах одного репозиторію. Саме розгалуження робить Git потужним інструментом для спільної роботи, експериментів і керування різними версіями проєкту.

            gitGraph
            commit id: "Початкове налаштування"
            commit id: "Додано базові можливості"
            branch feature/new-idea
            checkout feature/new-idea
            commit id: "Реалізовано нову логіку"
            commit id: "Рефакторинг логіки"
            checkout main
            commit id: "Термінове виправлення в main"
            merge feature/new-idea
            commit id: "Підготовка до релізу"
        
Від основної гілки main відгалужується нова гілка feature/new-idea для безпечної розробки. Після завершення роботи вона зливається назад у main.

Уявіть, що ви хочете серйозно щось переробити у своєму проєкті або провести ризикований експеримент. Як би ви діяли без Git? Найімовірніше, ви скопіювали б увесь проєкт у нову папку й працювали б уже в ній. Якщо результат вам сподобається, ви перенесете його в основну папку. Якщо ні — просто видалите копію.

Гілки в Git працюють за тим самим принципом, але значно елегантніше. Розгляньмо це на прикладі написання книжки:

  1. У вас є готовий рукопис — це ваша основна гілка main.
  2. Ви хочете написати альтернативну кінцівку — створюєте нову гілку, наприклад feature/new-idea.
  3. Ви пишете нову кінцівку, не зачіпаючи основного тексту рукопису, тобто працюєте в новій гілці.
  4. Якщо нова кінцівка виявиться кращою, ви замінюєте нею стару — виконуєте злиття гілок, merge.
  5. Стару чернетку з непотрібною кінцівкою можна видалити — так само, як і непотрібну гілку.

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.

Перемикання на гілку main

Крок 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: Додано новий розділ"
            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). Це гарантовано призведе до конфлікту під час злиття.

Змоделюймо конфлікт:

  1. Переконайтеся, що ви перебуваєте в гілці main і у вас немає незбережених змін у вікні Commit.
  2. Створіть нову гілку feature/new-title, але поки що не перемикайтеся на неї. Переконайтеся, що прапорець Checkout branch знято.
  3. Тепер, перебуваючи в гілці main, змініть перший рядок у README.md на «My Awesome Project» і виконайте commit.
  4. Перемкніться на гілку feature/new-title. Ви побачите, що перший рядок у README.md тут лишився старим: це стан файлу на момент створення гілки. Змініть цей самий рядок на «My Super Project» і виконайте commit.
  5. Поверніться до гілки 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 (злиття перемотуванням). Це трапляється тоді, коли історія однієї гілки є просто продовженням історії іншої, а самі гілки не розходяться паралельно.

Приклад:

  1. У вас є певний коміт у main (припустімо, C1).
  2. Ви робите новий коміт у гілці main з текстом «My Awesome Project». Гілка main тепер вказує на коміт C2 (main -> C1 -> C2).
  3. Ви створюєте гілку feature/new-title з поточного положення гілки main. Це означає, що нова гілка теж починається з коміту C2.
  4. Ви робите коміт у feature/new-title з текстом «My Super Project». Ця гілка «йде вперед» і тепер вказує на коміт C3 (feature/new-title -> C1 -> C2 -> C3).
  5. Ви повертаєтеся в 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. Ви побачите графічне представлення всіх ваших гілок і комітів. Це допоможе наочно відстежити, яка гілка від якої відокремилася і де їх було злито.

Вікно логів Git

Тут ви можете натиснути на будь-який коміт і побачити, які зміни до нього увійшли, хто його зробив і коли. Це справжня машина часу для вашого коду!

Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ