A3.4 Додаток C: Команди Git - Розгалуження та злиття
За створення нових гілок та злиття їх воєдино відповідає кілька Git команд.
git branch
Команда git branch - це свого роду "менеджер гілок". Вона вміє перераховувати ваші гілки, створювати нові, видаляти та перейменовувати їх.
Більшість розділу Розгалуження Git присвячена цій команді, вона використовується повсюдно в цьому розділі. Вперше команда branch була представлена в розділі Створення нової гілки глави 3, а більшість її можливостей як перерахування та видалення гілок були розібрані в розділі Управління гілками глави 3.
У розділі Відстеження гілок розділу 3 ми показали використання поєднання git branch -u для відстеження гілок.
Нарешті, ми розібралися, що відбувається за лаштунками цієї команди в розділі Посилання в Git глави 10.
git checkout
Команда git checkout використовується для перемикання гілок та вивантаження їхнього вмісту в робочий каталог.
Ми познайомилися з цією командою у розділі Перемикання гілок розділу 3 разом із git branch.
У розділі Відстеження гілок розділу 3 ми дізналися про прапор --track для відстеження гілок.
У розділі Використання команди checkout у конфліктах глави 7 ми використовували цю команду з опцією --conflict=diff3 для вирішення конфліктів заново, якщо попереднє рішення не відповідало певним причинам.
Ми розглянули деталі взаємозв'язку цієї команди та git reset у розділі Розкриття таємниць reset глави 7.
Ми дослідили внутрішні механізми цієї команди у розділі HEAD глави 10.
git merge
Команда git merge використовується для злиття однієї або кількох гілок у поточну. Потім вона встановлює покажчик поточної гілки на результуючий коміт.
Ми познайомили вас з цією командою в розділі Основи розгалуження розділу 3. І хоча git merge зустрічається в цій книзі повсюдно, практично всі використання мають вигляд git merge із зазначенням єдиної гілки для злиття.
Ми дізналися, як робити «сплющені» злиття (коли Git робить злиття у вигляді нового комміту, без збереження всієї історії роботи) наприкінці розділу Форк публічного проекту.
У розділі Розширене злиття розділу 7 ми глибше розібралися з процесом злиття і цією командою, включаючи прапори -Xignore-all-whitespace і --abort , що використовується для скасування злиття у разі виникнення проблем.
Ми навчилися перевіряти криптографічні підписи перед злиттями, якщо ваш проект використовує GPG у розділі Підпис коммітів глави 7.
Ну і нарешті в розділі Злиття піддерев глави 7 ми познайомилися зі злиттям піддерев.
git mergetool
Команда git mergetool просто викликає зовнішню програму злиття, якщо у вас виникли проблеми злиття.
Ми коротко згадали про неї у розділі Основні конфлікти злиття глави 3 і розповіли як налаштувати свою програму злиття у розділі Зовнішні програми злиття та порівняння глави 8.
git log
Команда git log використовується для перегляду історії коммітів, починаючи з найсвіжішого та йдучи до витоків проекту. За замовчуванням, вона показує лише історію поточної гілки, але може бути налаштована висновок історії інших, навіть кількох відразу, гілок. Також її можна використовувати для перегляду відмінностей між гілками лише на рівні коммітів.
Практично у всіх розділах книги ця команда використовується для демонстрації історії проекту.
Ми познайомилися з git log та деякими її деталями у розділі Перегляд історії коммітів глави 2.Там ми бачили використання опцій -p і --stat для отримання уявлення про зміни в кожному коміті, а також --pretty and --oneline для налаштування формату виведення цієї команди більш повним і докладним або коротким.
У розділі Створення нової гілки глави 3 ми використали опцію --decorate щоб відобразити покажчики гілок на історії коммітів, а також --graph щоб переглядати історію у вигляді дерева.
У розділах Невелика команда глави 5 та Діапазони коммітів глави 7 ми познайомили вас із синтаксисом branchA..branchB , що дозволяє команді git log показувати лише комміти, присутні в одній гілці, але відсутні в іншій. Ми докладно розглядаємо це питання розділі Діапазони коммітів.
У розділах Історія при злитті та Три точки глави 7 ми розглянули синтаксис branchA…branchB та опцію --left-right що дозволяють побачити, що знаходиться в одній чи іншій гілці, але не в них обох відразу. Також у розділі Історія злиття ми розглянули опцію --merge , яка може бути корисною при вирішенні конфліктів, а також --cc для перегляду конфліктів злиття в історії проекту.
У розділі RefLog-скорочення глави 7 ми використовували опцію -g для виведення git reflog , використовуючи git log .
У розділі Пошук глави 7 ми розглянули використання опцій -S та -L для пошуку подій в історії проекту, наприклад, історії розвитку будь-якої фічі.
У розділі Підпис коммітів глави 7 ми показали, як використовувати опцію --show-signature для відображення рядка валідації підпису для кожного комміта в git log .
git stash
Команда git stash використовується для тимчасового збереження всіх незафіксованих змін для очищення робочого каталогу без необхідності фіксувати незавершену роботу в поточній гілці.
Ця команда практично повністю розкрита у розділі Приховування та очищення глави 7.
git tag
Команда git tag використовується для завдання постійної мітки на якийсь момент в історії проекту. Зазвичай, вона використовується для релізів.
Ми познайомилися і розібралися з нею в розділі Робота з тегами розділу 2 і використовували на практиці розділ Позначте свої релізи розділу 5.
Ми навчилися створювати підписані за допомогою GPG мітки, використовуючи прапорець -s і перевіряти їх, використовуючи прапорець -v , у розділі Підпис глави 7.
Гайд по Git : Частина 2 : Гілки та злиття гілок
У цій статті розуміємося з поняттям гілок у git. Як смержити одну гілку до іншої, і чим відрізняється Merge від Rebase.
Майже кожна система контролю версій підтримує розгалуження у тій чи іншій формі. За допомогою розгалуження можна відхилятися від основної лінії розробки та продовжувати роботу незалежно від неї, не торкаючись основної гілки. У багатьох ВКВ створення гілок є ресурсозатратним процесом, який часто вимагає створення нової копії каталогу з вихідним кодом, що може зайняти значний час для великих проектів.
Гілки в Git, як і комміти, надзвичайно легкі. Гілка в Git - це просто вказівник, що переміщується, не більше того. Саме тому багато фанатів Git повторюють мантру:
Оскільки створення великої кількості гілок майже не впливає на використання пам'яті або місця на жорсткому диску, зручно створювати окремі гілки для кожного завдання. Можна сказати, що гілка зберігає зміни поточного комміту та його попередників.
За замовчуванням, основною гілкою надається ім'я main або master . Як тільки ви починаєте робити комміти, покажчик основної гілки (main) завжди буде вказувати на останній комміт.
Приклад роботи з гілками
Створимо нову гілку з ім'ям newImage:
$ git branch NewImage
Команда створення нової гілки
Ми створили новий покажчик для гілки newImage, який вказує на останній коміт у гілці main. Однак ми залишаємося на гілці main.
Команда git branch не лише створює гілки, а й дозволяє переглядати існуючі. Гілка, на якій ви знаходитесь, позначена зірочкою:
$ git branch * main newImage
Якщо ми зробимо зміни на цьому етапі, вони будуть застосовані до гілки main , а не до нової гілки newImage .
Щоб перейти на нову гілку, використовуємо команду:
$ git checkout newImage Переключено на гілку «newImage»
Тепер зміни зберігатимуться у гілці newImage і не торкнуться гілки main. Наприклад, давайте змінимо файл file.txt і зробимо коміт:
echo "new branch" >> file.txt git add file.txt git commit -m "Четвертий коміт"
[newImage 378501d] Четвертий коміт 1 file changed, 1 insertion(+)
Тепер, щоб побачити, як працюють гілки, перейдемо назад на гілку main і зробимо ще один коміт:
git checkout main echo "change main" >> three-file.txt git add three-file.txt git commit -m "П'ятий коміт"
[main 60e062b] П'ятий коміт 1 file changed, 1 insertion(+)
Четвертий і П'ятий комміти мають однієї й тієї ж батька (третій комміт), але вони незалежні друг від друга. Зміни у гілці newImage не торкаються розробки у гілці main . Тому рекомендується створювати окрему гілку для кожного завдання і потім зливати її з основною гілкою розробки.
Для створення нової гілки та перемикання на неї в одній команді використовуйте:
$ git checkout -b your_branch_name
Merge
Ми вже знаємо, як створювати гілки та комітити зміни.Тепер потрібно розібратися, як поєднувати зміни з двох різних гілок після виконання завдання в окремій гілці.
Перший спосіб поєднання змін, який ми розглянемо - це команда git merge. Злиття створює спеціальний тип комміту, який має двох батьків. Коміт із двома батьками зазвичай вказує на те, що ми об'єднуємо зміни з одного комміту з іншим та всіма їх попередніми комітами.
Припустимо, у нас є дві гілки: main і newImage. Ми зробили деяку роботу у гілці newImage, наприклад, це був наш четвертий коміт. Тепер потрібно влити ці зміни у гілку main.
Перебуваючи у гілці main, перевіримо, що файл file.txt не містить змін, зроблених раніше у гілці newImage:
$ cat file.txt 12345 67890
Тепер виконаємо злиття гілки newImage з гілкою main :
$ git merge newImage
Merge made by the 'recursive' strategy. file.txt | 1 + 1 file changed, 1 insertion(+)
Ми створили коміт, який має двох батьків. Тепер перевіримо, що зміни з гілки newImage з'явилися у файлі file.txt у гілці main :
$ cat file.txt 12345 67890 new branch
Також подивимося історію коммітів (log), щоб переконатися, що було створено новий коміт злиття:
$ git log -2 commit 'newImage' commit 60e062b14597415fbea93ed73746db7d14c161ce Автор: uPagge Date: Tue Jun 15 22:16:11 2021 +0300 П'ятий коміт
Rebase
Другий спосіб поєднання змін із різних гілок - це rebase. При виконанні ребейза Git фактично копіює набір коммітів та переносить їх в інше місце.
Хоча це може звучати трохи складно, основна перевага rebase полягає в тому, що він дозволяє створювати чисту та красиву лінійну послідовність комітів. Історія стає більш упорядкованою, якщо використати rebase.
Створимо нову гілку bugFix від гілки main:
$ git checkout -b bugFix Переключено на нову гілку «bugFix»
Внесемо зміни і зробимо коміт у гілці bugFix:
$ echo "bugFix" >> file.txt $ git add file.txt $ git commit -m "Коміт у гілці bugFix" [bugFix 7feb311] Коміт у гілці bugFix 1 file changed, 1 insertion(+)
Тепер повернемося у гілку main , зробимо зміни та коміт:
$ git checkout main Переключено на гілку «main» $ echo "main" >> new-file.txt $ git add new-file.txt $ git commit -m "Комміт у гілці main" [main 3a59d58] Коміт у гілці main 1 file changed, 1 insertion(+)
Перед виконанням rebase подивимося лог коммітів у гілці main:
$ git log --oneline 3a59d58 (HEAD -> main) Коміт у гілці main b5c01a3 Merge branch 'newImage' 60e062b П'ятий коміт 378501d (newImage) Четвертий коміт b64191a Третій коміт 06f7fc0 Перший коміт
Тепер виконаємо rebase гілки bugFix на гілку main :
$ git rebase bugFix Спочатку перемотуємо покажчик поточного комміту, щоб застосувати ваші зміни поверх нього. Застосування: Коміт у гілці main
Після виконання rebase знову перевіримо лог:
git log --oneline 8868e84 (HEAD -> main) Коміт у гілці main 7feb311 (bugFix) Коміт у гілці bugFix b5c01a3 Merge branch 'newImage' 60e062b П'ятий коміт 378501d (ne Третій коміт b66f9c7 Другий коміт 06f7fc0 Перший коміт
Як видно, коміт із гілки bugFix тепер знаходиться перед коммітом із гілки main, створюючи лінійну послідовність.
Git дописав копію комміту C7 за коммітом C6 і переніс туди покажчик
Також перевіримо вміст файлу file.txt:
$ cat file.txt 12345 67890 new branch bugFix
Git переніс копію комміта з гілки bugFix після комміту з гілки main та оновив покажчик гілки.
Тепер можна видалити гілку bugFix, оскільки її зміни вже були застосовані:
$ git branch -d bugFix Гілка bugFix видалена (була 7feb311).
Перевіримо лог ще раз:
git log --oneline 8868e84 (HEAD -> master) Коміт у гілці main 7feb311 Коміт у гілці bugFix b5c01a3 Merge branch 'newImage' 60e062b П'ятий коміт 378501d (newImage) b66f9c7 Другий коміт 06f7fc0 Перший коміт
Коміт із гілки bugFix залишився в історії, проте вказівник на гілку було видалено.
Висновок
Ми розглянули роботу з гілками у Git та процес їх злиття. В ідеальному проекті всі гілки прагнуть бути об'єднаними в основну гілку. Не забувайте створювати окремі гілки від основної гілки розробки для кожного окремого завдання. Це дозволяє ізолювати зміни та підтримувати чистоту історії проекту.
Робота з гілками в Git (git branch)
Інструкція про те, як працювати з гілками у Git. Розкажемо, як закомітити зміни та запушити у нову гілку, як видалити гілку чи змінити її — і це не все.
Ця інструкція є частиною курсу «Введення в Git».
Дивитись весь курс
Вступ
Розгалуження стало невід'ємною частиною командної розробки, тому що дає можливість працювати над різними версіями вихідного коду. Основною ідеєю розгалуження є відхилення від основного коду та продовження роботи незалежно від нього.Також це зручно у тестуванні окремого функціоналу, тому що дозволяє працювати над новою частиною коду, не турбуючись про поломку чогось у робочій версії. У цій інструкції розповімо про те, як працювати з гілками Git.
Основні поняття: про гілку Git та master
Під гілкою прийнято розуміти незалежну послідовність комітів у хронологічному порядку. Однак саме в Git реалізація гілки виконана як покажчик на останній коміт у гілці, що розглядається. Після створення гілки вже новий покажчик посилається на поточний коміт.
Ім'я основної гілки Git-проекту за замовчуванням - master (проте часто буває main, наприклад, у GitHub), вона з'являється відразу при ініціалізації репозиторію. Ця гілка нічим не відрізняється від інших і також її можна перейменувати, але за домовленістю master прийнято вважати головною гілкою в проекті.
Що робить git branch
Команда git branch – головний інструмент для роботи з розгалуженням. З її допомогою можна додавати нові гілки, перераховувати та перейменовувати існуючі та видаляти їх.
Способи створення гілок та перемикання між ними
Щоб у Git додати гілку ми використовуємо:
Після цієї операції гілка вже була створена, але ви, як і раніше, перебуваєте в колишній гілці. Якщо ви плануєте переміститися на іншу гілку, у тому числі щойно створену, необхідно написати checkout:
Для того, щоб визначити, де зараз розробник, Git використовує спеціальний покажчик HEAD, що посилається на поточну локальну гілку. В результаті checkout HEAD переміститься на іншу гілку.
Як за допомогою git branch створити гілку і перейти до неї
Найчастіше при створенні нової гілки git користувачеві необхідно відразу ж перейти на неї.У такому випадку варто використати:
$ git checkout branch
Це буде рівносильно:
Також ми отримаємо той же результат при використанні git checkout з ключем -b:
Якщо користувачеві потрібно отримати список певної множини гілок, тоді можна скористатися ключами. Одними з найпоширеніших будуть:
- -r - при використанні цього ключа ми отримаємо список віддалених гілок,
- -a — використовуючи цей параметр, у виводі будуть видалені та локальні гілки.
Про команду git checkout
Під час виконання цієї команди Git потрібно здійснити певний порядок дій, щоб переходити на гілку, яку ми вказали. Для цього програма виконує такий алгоритм:
Перевірка, що вказана нами гілка існує у проекті
Цей етап необхідний, тому що в іншому випадку програма не зможе перейти на гілку, яка не визначена. Для більшого розуміння необхідно згадати, що таке гілка в git. Враховуємо, що фактично завдання гілки – це запис комміту, на який вона посилається. Усередині Git наявність конкретної гілки перевіряється наявністю однойменного файлу у конкретній директорії.
Перемикання вказівника HEAD на нову гілку
Необхідно змістити покажчик, щоб Git розумів, де зараз триває робота.
Зміна робочої версії таким чином, щоб нова гілка їй повністю відповідала
Сама концепція роботи розгалуження у тому, що у різних гілках перебувають різні версії коду, з яких робота ведеться окремо друг від друга. Тоді потрібно змінити робочу копію. Git бере останній коміт та відновлює всі зміни.
Після завершення всіх перелічених вище дій вважатимуться, що ми повністю переключилися.Також за допомогою checkout можна витягти окремий файл (або папку) з іншої гілки та отримати його, попередньо перейшовши в ту гілку, куди ви збираєтесь перенести файл.
Основи розгалуження та злиття
Розгалуження дозволяє розділяти робочий процес, оптимізувати тестування і написання нового коду. кінець розробки проекту цілий продукт в одному місці.
Для цього в Git передбачено злиття - перенесення змін з однієї гілки на іншу. ми отримуємо, застосувавши git merge:
Операція може призвести до появи конфліктів при спробі злити гілки. Це викликано тим, що зміни видаляють або переписують інформацію в існуючих файлах.
Також варто згадати існування ключів, призначених спеціально для роботи з конфліктами:
- -abort — перериває злиття і повертає все на початок
- -continue — продовжує злиття після вирішення конфлікту
Вирішити конфлікт можна двома способами:
- Вручну вирішити файловий конфлікт Для цього потрібно самим змінити файли, з якими виникли проблеми.
- Вибрати більш підходящий файл, а від другого відмовитись.
Управління гілками за допомогою git branch
Ця команда може трохи більше, ніж просто в git створювати гілки з поточної.
При виконанні цього рядка ми отримаємо список існуючих гілок, де символом * буде відзначена гілка, де ви зараз знаходитесь.
first_branch * master second_branch
За допомогою параметра -v можна отримати останній збережений коміт у кожній гілці.
$ git branch -v first_branch 8fa301b Fix math * master 225cc2d Merge branch 'first_branch' second_branch c56ee12 Refactor code style
Також існують опції -merged і -no-merged, За допомогою яких можна відфільтрувати отриману послідовність гілок. Тобто ми отримаємо список відгалужень, які вже були злиті, або, навпаки, гілки, які ще не пройшли через злиття з іншими.
$ git branch --merged first_branch * master
Як закомітити зміни в нову гілку
Після створення нової гілки, переходу в неї та здійснення всіх запланованих перетворень, потрібно зробити коміт у цю ж гілку, щоб зберегти всі зміни для виконання цих дій нічим не відрізняються від команд для створення коммітів у гілці майстер.
Після виконання послідовності цих команд ми закоммітували зміни у потрібній версії програми.
Як запушити в нову гілку
Якщо ми хочемо запушити нашу гілку, то для цього потрібно написати:
Тепер гілка запушена. Якщо до того ми вже пушили її, то відбудеться відправка нових коммітів.
На відміну від команди git checkout, при виконанні пуша немає перевірки на існування вказаної гілки.
Як перейменувати гілку
У процесі розробки можуть виникнути ситуації, коли людина хоче інакше називати вже створену гілку. Це може бути пов'язано з різними причинами (наприклад, функціонал, що розробляється в даній версії, не відповідає назві). Щоб перейменувати гілку застосовуємо:
Однак тут потрібно бути обережними, щоб не перевантажити проект непотрібними гілками. Якщо запустити перейменовану гілку, то на сервері з'явиться гілка з новим ім'ям, але й гілка зі старою назвою теж залишиться. Щоб уникнути цієї проблеми, необхідно видалити гілку локально і на сервері.
Як видалити гілку
Видалення гілок не такий простий процес, як може здатися. Можна випадково видалити незбережені зміни у вихідному коді, що призведе до небажаних наслідків. Тому тут треба діяти обережно. З операцією видалення над гілками справляється звична команда git branch з параметром -d:
Для коректного видалення потрібно пам'ятати кілька правил, щоб не отримати помилки:
- Не можна видалити гілку, в якій ви знаходитесь. Git викине помилку і не зробить видалення. Отже, потрібно перейти на іншу гілку.
- Git не дозволить видалити гілку, яка має незбережені зміни. Так ми уникаємо ситуації, коли частина написаного коду буде безповоротно втрачена. Якщо ж ми впевнені, що зміни в цій версії не потрібні і можна їх сміливо видаляти, то замість прапора -d використовуємо -D:
Дотримуючись всіх умов, нам вдасться видалити вказану гілку.
Робота з гілками на практиці
В інструментах для розробки мовами часто є вбудований функціонал, що дозволяє працювати безпосередньо з Git.Наприклад, у таких середовищах розробки як IntelliJ IDEA, PyCharm, PhpStorm, CLine, Rider дуже зручно та зрозуміло, як правильно оперувати з різними гілками. Для прикладу розберемо роботу в одному з таких середовищ.
Як працювати з гілками у PhpStorm
Справа в нижньому кутку розташовані вкладки для роботи з Git, де і відбувається все налаштування розгалуження. На цій панелі розташовано назву поточної гілки. За бажання створити нову потрібно натиснути на цей пункт і вибрати New Branch. Для зміни гілки - вибрати зі списку потрібну і клікнути на Checkout. Для видалення та перейменування передбачені кнопки Delete і Rename відповідно.
Робота у спеціальному додатку майже нічим не відрізняється від роботи в консолі, тому всі отримані знання можна застосовувати незалежно від обраного способу.
Отримання інформації про стан гілок
Як переглянути стан файлів гілки
Зазначимо, що при переході на іншу версію незакоммічені зміни перенесуться на гілку, куди ми перейдемо. Тому перед перемиканням необхідно переконатися, що зміни у поточній гілці вже закоммічені. Для цього підходить git status:
Виконання цієї операції дозволить переглянути файли, розташовані у гілці, де ми знаходимося. Саме за допомогою неї можна відслідковувати незакоммічені зміни, щоб випадково не перенести їх в інше місце. Порожній висновок цієї команди показує те, що у гілці відсутні змінені файли і ми можемо без побоювань продовжувати з нею роботу. А інакше необхідно закомітіті всі потрібні виправлення.
Як переглянути історії коммітів гілки
Неодноразово в процесі розробки потрібно подивитися на журнал змін: для відстеження розвитку проекту або визначення комміту, до якого слід повернутися. У таких ситуаціях рятує команда git log:
Ця команда має безліч ключів, використовуючи які можна отримати більш конкретну інформацію:
- - (рівноцінно -n=) - показує останні n коммітів,
- -pretty = (доступні такі значення, як oneline, short, medium, full та інші) **** - форматований висновок історії,
- -p - Виводяться зміни, що містяться в коміті,
- -graph - представляє дерево взаємозв'язків коммітів у вигляді ASCII-графа - такий метод використання дозволяє отримати графічне представлення гілок прямо в консолі,
- -all — на виході ми отримуємо історію всіх коммітів для всіх існуючих гілок,
- -Decorate - Вказує, на що посилаються покажчики.
Якщо нам потрібно переглянути історію для конкретної гілки, то допоможе виконання:
Структура гілок Git представлена у вигляді графа. Коли ми отримуємо коміти певної гілки, пересуваючись «вгору» графом, ми повинні зупинитися в той момент, коли дійдемо до комміта, який буде меншим за вказівник батька гілки. При виконанні цієї умови коли гілка, чия історія коммітів нас цікавить, дістається свого батька, висновок припиняється, і ми отримуємо коректну відповідь.
Як переглянути різницю між коммітами
Досить часто під час розробки будь-якого продукту розробник може виникнути потреба подивитися різницю між двома комитами, перш ніж заливати щось. Для цього існує git diff:
Для цієї операції також передбачено кілька ключів:
- —diff-filter= — за допомогою цього параметра, змінюючи значення міток, можна задати оновлення між якими файлами ми хочемо побачити.Розглянемо деякі можливі значення міток:
- D - Покаже видалені файли,
- M – ми отримаємо файли, модифіковані після останнього комміту.
Висновок
Git має безліч переваг у порівнянні з іншими системами контролю версій саме через легку роботу з розгалуженням. Така гнучкість допомагає максимально оптимізувати процес розробки. А саме розгалуження дуже спрощує розробку проекту. Гілки забезпечують безпечний спільний доступ до коду для різних людей. Адже саме вони дають можливість пластично та витончено працювати над створенням нового продукту.
Як встановити Git на Windows