Git
Система керування версіями
План
Призначення Git – спільна робота над одним проєктом
Базові поняття Git
Варіанти створення Git-репозиторію
Репозиторії можна робити приватними або публічними
Варіанти створення локального репозиторію
Варіант 1. Створення та клонування віддаленого репозиторію
git config --global user.name "firstName lastName"
git config --global user.email "yourEmail@gmail.com"
git clone git@gitlab.com:<UserName>/myproject.git
Варіант 2. Ініціалізація локального репозиторію
Серія команд для ініціалізації локального репозиторію
cd projects/DemoNodeJSApp – змінюємо робочу папку на DemoNodeJSApp
git init – створюємо локальний репозиторій
git checkout -b main – створюємо та робимо поточною гілку main
git remote add origin git@gitlab.com:<UserName>/demo-nodejs-app.git – додаємо інформацію про віддалений репозиторій. Origin – ім’я, що використовується для посилання на віддалений репозиторій.
Операції Git
Основний цикл роботи з Git при внесенні змін
Робота з гілками Git
Створення гілки на віддаленому репозиторії
git pull – передаємо зміни з віддаленого на локальний репозиторій
git checkout bugfix/user-auth-error – перемикаємось на гілку bugfix/user-auth-error
git branch – виводимо інформацію про наявні гілки та поточну гілку
Створення гілки через термінал
Крок 1. Виконаємо команди для створення нової гілки:
git checkout main – перемикаємось на головну гілку
git checkout -b feature/database-connection – створюємо нову гілку з гілки main, перемикаємось на неї
Крок 2. Для прикладу створимо файл connect.js з виводом рядка “Connection to DB”.
Крок 3. Робимо відправку на віддалений репозиторій:
git add . – додаємо всі змінені файли в Git-індекс
git commit -m "Connect to DB feature" – фіксуємо зміни
git push --set-upstream origin feature/database-connection – відправляємо на віддалений репозиторій нову гілку та коміт, зроблений в ній.
На практиці
Запити на злиття гілки
Щоб включити зміни з вихідної гілки в цільову гілку, хорошою практикою є запит на злиття (MR).
При відкритті запиту на злиття, можна вивести зміни та спільно працювати над ними до безпосереднього злиття. Запити на злиття включають:
Запити на злиття
Крок 1. Клацнемо branches. В гілці, яку потрібно злити з головною, клацнемо Merge Request.
Крок 2. Задамо заголовок та опис запиту на злиття. Також поля “assignee” та “reviewer”.
Крок 3. Особа Assignee оцінює запит, переглядає коментарі від рецензентів і здійснює безпосередньо злиття гілок. При цьому гілка, з якої відбулося злиття, може видалитись.
Видалення гілок
Якщо на віддаленому репозиторії після злиття, робочу гілку видалено, то на локальному репозиторії вона отримує статус gone, і її теж можна видалити:
# Перемикаємось на гілку main
git checkout main
# Отримуємо зміни по злиттю
git pull
# Отримуємо інформацію про всі віддалені репозиторії, зокрема інформацію про видалені гілки на віддалених репозиторіях
git fetch --all --prune
# Вивести список гілок для визначення, які гілки видалені (gone)
git branch -vv
# Видалити потрібну гілку з локального репозиторію
git branch -D feature/database-connection
Коміти злиття
Припустимо, що в нас є локальний репозиторій. Ми зробили коміт, але відправку зробити не можемо, оскільки на віддаленому репозиторії інший користувач відправив новий коміт. Система запропонує спочатку отримати зміни:
git pull
В такому випадку додатково створюється так званий merge-коміт (коміт злиття віддаленої та локальної гілки). При наступній відправці змін з локального репозиторію вже відправиться два коміти:
Виключення даних про коміти злиття з віддаленого репозиторію
Крок 1. Робимо коміт локальних змін.
Крок 2. Виконуємо git pull --rebase <remote-name> <branch-name
По суті, rebase спочатку видаляє наші коміти, які ми зробили на поточній гілці. Потім він застосує всі віддалені коміти, а потім застосує наші коміти поверх.
Крок 3. Відправляємо коміти на віддалений репозиторій: git push
Конфлікти злиття
Якщо паралельно робити зміни в одному файлі на різних репозиторіях, це може призвести до конфліктів. Наприклад, здійснивши локальний коміт, отримаємо зміни з віддаленого репозиторію і отримаємо конфлікт при злитті:
CONFLICT (content): Merge conflict in <fileName>
Automatic merge failed; fix conflicts and then commit the result.
При цьому код матиме вигляд:
Вирішення конфліктів злиття. Інструмент Resolve Merge Conflict
Вирішивши даний конфлікт, зробимо новий коміт та здійснимо відправку на віддалений репозиторій.
Файли, що не потрібно відстежувати
Виключення відстеження заданих файлів (.gitignore)
Крок 1. Створимо файл .gitignore та додамо в нього такі файли та папки:
node_modules/*
.idea/*
build/*
Крок 2. Зважаючи на те, що папка node_modules продовжує знаходитись в репозиторії, потрібно її видалити з репозиторію, залишивши локально:
git rm -r --cached node_modules
Крок 3. Робимо додавання змін в Git-індекс, фіксацію та віправку в поточну гілку:
git add .
git commit -m "Added .gitignore"
git push
Переконуємось в наявності файлу .gitignore і що папка node_modules видалена з усім її вмістом на віддаленому репозиторії.
Збереження незавершених змін (git stash)
При спробі виконати команду git checkout main, якщо не зроблений коміт, система повідомить про помилку і не перемикне гілку.
Для можливості перемикання на іншу гілку із збереженням незавершених змін без необхідності робити коміт потрібно виконати команду:
git stash
Потім знову перейти в дану гілку і повернути зроблені зміни назад:
git stash pop
Навігація по історії
Для виводу історії комітів можна виконати команду
git log
При потребі можна повернутись до стану будь-якого попереднього коміту (наприклад, якщо потрібно відслідкувати помилку). Для цього виконаємо команду:
git checkout <commit_hash>
Для повернення до попередньої точки HEAD (останній коміт поточної гілки) виконаємо команду:
git checkout -
Скасування або внесення змін до вже зроблених комітів
git reset --hard HEAD~1
HEAD – вказівник на верхній коміт, 1 – кількість комітів, що скасовується. Параметр --hard відміняє і коміт і самі зміни в проекті. Якщо зміни потрібно залишити для подальшої роботи з ними, вказуємо параметр --soft (по замовчуванню).
Якщо поточні зміни потрібно додати в уже виконаний останній коміт, це можна зробити командою:
git commit --amend
Для скасування коміту на віддаленому репозиторії після відповідної дії на локальному, необхідно виконати команду:
git push --force
Для скасування коміту в головній гілці необхідно виконати команду:
git revert <commit_hash>
Злиття гілок
Завдання: необхідно зміни з головної гілки передати в власну гілку для підтримки актуального стану власної гілки та врахування поточних етапів розробки
Для злиття комітів з головної гілки у власну гілку, виконаємо такі команди
# Змінюємо поточну гілку на features
git checkout features
# Зливаємо коміти в поточну гілку з головної гілки
git merge main
# Переглядаємо історію і переконуємось, що останній коміт – злиття гілки main в гілку features
git log
# Відправляємо зміни щодо злиття на віддалений репозиторій
git push
Роль Git в CI/CD