Перед Lab-01
Git & GitHub: Практичний воркшоп
Клонування, гілки, коміти, push — все що потрібно для 22 лабораторних
Git & GitHub: Практичний воркшоп
Перед Lab-01. Цей воркшоп — єдине що потрібно знати про Git для виконання всіх 22 лабораторних.
Ніяких попередніх знань не потрібно.
Мета
Після цього воркшопу ти вмієш:
- Клонувати репозиторій і орієнтуватись у його структурі
- Створювати гілку для кожної лаби та правильно її називати
- Робити коміти з правильним форматом повідомлення
- Зливати лабу в
mainі переходити до наступної - Пушити роботу на GitHub
Частина 1. Архітектура Git
Git розбиває твою роботу на чотири зони. Зрозуміти їх — значить зрозуміти Git.

| Зона | Що тут живе | Ключова команда |
|---|---|---|
| Working Directory | Файли які ти редагуєш | git status |
| Staging Area | Зміни підготовлені до коміту | git add |
| Local Repository | Зафіксована історія (.git/) |
git commit |
| Remote (GitHub) | Твоя копія на сервері | git push / pull |
Важливо: git add не зберігає зміни назавжди — він лише переміщує їх до Staging. Тільки git commit фіксує знімок назавжди в локальному репо.
Навіщо потрібна Staging Area?
Уявімо: ти сидів над Task02 і за день змінив 7 файлів. Більшість стосується Task02, але паралельно підправив якийсь баг у Task01 в іншому файлі. Без Staging Area лишається два варіанти: або всі 7 файлів в один коміт (каша в історії — незрозуміло що де), або взагалі нічого не комітити.
Staging Area вирішує це: ти вибираєш саме ті файли які стосуються поточного завдання, комітиш їх — і лише потім беришся за наступне.
# Day1: змінив і Doctor.cs, і DoctorService.cs, і щось підправив у Patient.cs
# Хочемо три окремих логічних коміти:
git add src/Models/Doctor.cs
git commit -m "Lab03 Task02: add Doctor class"
git add src/Services/DoctorService.cs
git commit -m "Lab03 Task02: implement DoctorService"
git add src/Models/Patient.cs
git commit -m "Lab03 Task01: fix null check in Patient"Три логічних одиниці — три коміти — чиста зрозуміла історія. Так виглядає git log:
a1b2c3d Lab03 Task01: fix null check in Patient
3d4e5f6 Lab03 Task02: implement DoctorService
7g8h9i0 Lab03 Task02: add Doctor classКрок 1. Встановлення Git
Завантаж з git-scm.com та встанови (всі налаштування за замовчуванням).
Перевірка:
git --version
# git version 2.x.xКрок 2. Налаштування імені та email
Git підписує кожен коміт твоїм іменем. Виконай один раз:
git config --global user.name "Іван Петренко"
git config --global user.email "ivan.petrenko@gmail.com"Перевірка:
git config --list
# user.name=Іван Петренко
# user.email=ivan.petrenko@gmail.comКрок 3. Клонування репозиторію курсу
git clone https://github.com/<викладач>/OOP-Tomka-CourseForHardCoders.git
cd OOP-Tomka-CourseForHardCodersgit clone — це одноразова операція. Вона завантажує весь репозиторій разом з повною історією комітів. Після цього у тебе є локальна копія з якою можна працювати без інтернету.
git status
# On branch main
# nothing to commit, working tree cleanКрок 3а. `.gitignore` — що не потрібно комітити
Коли ти відкриєш проєкт у Visual Studio і зіберш його — з'явиться купа тимчасових файлів:
src/bin/Debug/net8.0/MyApp.exe
src/bin/Debug/net8.0/MyApp.dll
src/obj/Debug/net8.0/MyApp.pdb
.vs/MyApp/v17/.suo
...Їх не можна комітити: вони великі (MB), генеруються автоматично, залежать від твоєї машини. Якщо їх закомітити — репо розпухне, а колеги отримають чужі бінарники.
Для цього існує файл .gitignore — список патернів які Git повністю ігнорує.
Репо курсу вже містить .gitignore. Перевір:
cat .gitignore
# або відкрий у редакторіЯкщо .gitignore відсутній або неповний — створи/допиши в корені репо:
# C# / .NET
bin/
obj/
*.user
*.suo
.vs/
*.userprefs
.idea/
*.DotSettings.user
# Операційна система
.DS_Store
Thumbs.db
desktop.ini
# Конфіденційні дані
*.env
appsettings.Development.json
secrets.jsonПеревір що .gitignore працює — після цих рядків git status не повинен показувати bin/ або obj/:
# Збери проєкт, потім:
git status
# Ти маєш бачити лише свої .cs файли, а не сотні bin/obj файлівЯкщо
bin/все одно з'являється — файл.gitignoreабо не в тому місці, або вже заком'ічено відповідні папки. В такому разі:git rm -r --cached bin/ obj/і потімgit add .gitignore.
Частина 2. Що таке коміт і гілка
Перш ніж створювати гілки — треба розуміти що вони собою являють.

Коміт — не різниця файлів, а знімок
Кожен коміт — це об'єкт із чотирма полями:
- SHA — унікальний 40-символьний хеш (ідентифікатор)
- tree — посилання на знімок усіх файлів проєкту в цей момент
- parent — SHA попереднього коміту (так формується ланцюжок)
- message — твоє повідомлення
Коміт незмінний. Якщо змінити повідомлення — Git створить новий коміт з новим SHA. Старий залишиться в базі.
Гілка — просто pointer
Гілка — це файл із 41 байтом: SHA коміту на який вона вказує. Створити гілку дешево і безпечно — файли не копіюються.
main → a3f82c1 (вказує на "Initial commit")
Lab-01 → 3a4b5c6 (вказує на "Lab01 Task03: Doctor")
HEAD → Lab-01 (вказує на поточну гілку)HEAD — це завжди поточне місце де ти знаходишся. Коли робиш git checkout Lab-01, HEAD переміщується на гілку Lab-01.
Крок 4. Перша гілка
# Переконайся що ти на main
git checkout main
# Створи гілку для Lab-01 і одразу перейди на неї
git checkout -b Lab-01Прапор -b означає "create + checkout". Після цього:
git branch
# * Lab-01
# mainЗірочка показує поточну гілку.
Крок 5. Читати вивід `git status`
git status — команда яку ти будеш запускати десятки разів. Важливо розуміти що вона показує.
Стан після git checkout -b Lab-01 (ще нічого не змінено):
On branch Lab-01
nothing to commit, working tree cleanПісля того як створив новий файл src/Program.cs:
On branch Lab-01
Untracked files:
(use "git add <file>..." to include in what will be committed)
src/Program.cs
nothing added to commit but untracked files presentUntracked = Git бачить файл але ще не відстежує його. git add починає відстеження.
Після того як змінив вже існуючий файл:
On branch Lab-01
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
modified: src/Models/Patient.cs
Untracked files:
src/Program.csДва сигнали:
modified— файл вже був у репо, і ти його змінивUntracked— новий файл якого ще не було
Після git add src/:
On branch Lab-01
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
new file: src/Program.cs
modified: src/Models/Patient.csChanges to be committed = файли в Staging Area, готові до коміту. Якщо помітив помилку — git restore --staged <file> повертає файл зі Staging назад.
Після git commit:
On branch Lab-01
nothing to commit, working tree cleanЧисто — можна братись за наступне завдання.
Усі зміни які ти робиш — потрапляють в гілку Lab-01, а не в main.
Частина 3. Workflow курсу
Кожна лаба — один цикл. Подивись на структуру всього курсу:

Як видно з графа: main — стабільна лінія. Кожна лаба — окрема гілка яка відходить від main, набирає коміти (по одному на завдання) і зливається назад. Після злиття одразу стартує наступна лаба.
Формат коміту
Усі коміти в курсі дотримуються одного шаблону:
Lab01 Task01: коротко що зробленоLab01— номер лаби (без дефіса, дві цифри)Task01— номер завдання (дві цифри):— двокрапка і пробіл- Далі — дієслово + що:
add Patient class,implement GetCost,fix null check
Приклади:
Lab01 Task01: add Hello World console output
Lab03 Task02: add Patient class with properties
Lab17 Task03: configure Fluent API for Doctor with WorkScheduleКрок 6. Коміт після кожного завдання
Повний цикл виглядає так. Після виконання завдання:
6.1 — Переглянь що змінилось
git status
# Changes not staged for commit:
# modified: src/Program.cs
# Untracked files:
# src/Models/Patient.csЯкщо хочеш побачити конкретні зміни (рядки):
git diff
# --- a/src/Program.cs
# +++ b/src/Program.cs
# @@ -1,3 +1,6 @@
# +Console.WriteLine("Hello, World!");Рядки з + — додані, з - — видалені. git diff показує тільки нестейджені зміни. Для перегляду того що вже в Staging: git diff --cached.
6.2 — Добав до Staging
git add src/
# або конкретний файл:
git add src/Program.csПеревір що потрапило в Staging:
git status
# Changes to be committed:
# modified: src/Program.cs
# new file: src/Models/Patient.cs6.3 — Зафіксуй
git commit -m "Lab01 Task01: add Hello World console output"
# [Lab-01 3a4b5c6] Lab01 Task01: add Hello World console output
# 2 files changed, 8 insertions(+)Git підтвердить: SHA коміту (3a4b5c6), назву гілки, скільки файлів і рядків змінилось.
6.4 — Переглянь результат
git log --oneline
# 3a4b5c6 Lab01 Task01: add Hello World console output
# a1b2c3d Initial commitПісля кожного наступного завдання — повторюй цей цикл:
виконав завдання → git status → git diff → git add → git commit → даліОдин git commit на одне завдання. Не більше, не менше.
Крок 7. Завершення лаби — злиття в main
Виконав усі завдання? Зливай в main:
# Перейди на main
git checkout main
# Злий гілку Lab-01 (--no-ff зберігає топологію гілки в графі)
git merge --no-ff Lab-01 -m "Merge Lab-01: Intro to C#"Прапор --no-ff (no fast-forward) важливий: він створює явний merge-коміт навіть якщо злиття можна зробити лінійно. Завдяки цьому в git log --graph видно де починалась і де закінчилась кожна лаба.
Перевір результат:
git log --oneline --graph --all
# * c8d9e0f Merge Lab-01: Intro to C#
# |\
# | * 3a4b5c6 Lab01 Task03: add Doctor class
# | * 2b3c4d5 Lab01 Task02: add Patient class
# | * 1a2b3c4 Lab01 Task01: add Hello World
# |/
# * a1b2c3d Initial commitКрок 8. Перехід до наступної лаби
Відразу після злиття:
git checkout -b Lab-02Готово — Lab-02 стартує з чистого main.
Частина 4. Merge vs Rebase
Під час роботи над лабою може виникнути ситуація: main пішов вперед (наприклад, викладач запушив нові файли) поки ти виконував завдання. Потрібно синхронізуватись.

git merge main — зберігає топологію
git checkout Lab-01
git merge mainСтворює merge-коміт який об'єднує дві лінії розробки. Граф набуває форми "ромба" — видно точний момент злиття. Це підхід який ми використовуємо для фінального злиття лаби в main.
git rebase main — переписує поверх
git checkout Lab-01
git rebase mainGit "від'єднує" твої коміти E і F, застосовує нові коміти C і D з main, а потім "перекладає" твої коміти зверху. Результат: E' і F' з новими SHA. Стара E і F видаляються.
Плюс: лінійна, чиста історія.
Правило: ніколи не робити rebase на гілці яку вже запушив і яку бачать інші. Rebase переписує SHA — у колег виникнуть конфлікти.
Коли rebase доречний: локальне прибирання комітів перед PR, git rebase -i для squash/reorder.
Для курсу
У більшості випадків rebase не знадобиться — ти єдиний хто працює у своєму форку. Якщо викладач оновив репо — просто:
git checkout main
git pull origin main
git checkout Lab-01
git merge main # або git rebase main — на свій розсудЧастина 5. Push на GitHub
Крок 9. Запуши main після кожного злиття
git push origin mainКрок 10. Запуши поточну лабу (для бекапу і перевірки)
git push origin Lab-01Перша пуш гілки — можна скоротити через флаг -u:
git push -u origin Lab-01
# Тепер достатньо просто: git pushПереглянути що запушено:
git branch -r
# origin/main
# origin/Lab-01
# origin/Lab-02Частина 6. Аутентифікація GitHub
Перший git push часто дивує студентів — Git запитує логін або взагалі відхиляє з'єднання. Причина: GitHub вже кілька років не приймає звичайний пароль через командний рядок. Потрібна або Token-автентифікація, або SSH.
Варіант A — HTTPS + Git Credential Manager (рекомендовано на Windows)
Git for Windows встановлює Git Credential Manager (GCM) автоматично. При першому git push відкриється вікно браузера з GitHub — просто авторизуйся там.
git push origin main
# Відкриється браузер → GitHub → "Authorize Git Credential Manager"
# Після підтвердження — пуш пройде
# Наступні pushи — без запиту (токен кешується)Якщо браузер не відкрився і Git запитує пароль у терміналі — пароль не підійде. Потрібен Personal Access Token:
- GitHub → верхній правий куток → Settings
- Лівий сайдбар → Developer settings → Personal access tokens → Tokens (classic)
- Generate new token → вибери scopes:
repo(повний доступ до репо) - Скопіюй токен — він показується тільки один раз
- Вставляй його як пароль коли Git запитує
git push origin main
# Username: your-github-username
# Password: ghp_xxxxxxxxxxxx ← вставляєш токен, не парольВаріант B — SSH ключ (зручніше на Linux / macOS)
SSH-ключ — це пара файлів: приватний (тільки у тебе) і публічний (на GitHub). Після налаштування — ніяких запитів пароля ніколи.
Крок 1 — Згенерувати ключ:
ssh-keygen -t ed25519 -C "your-email@gmail.com"
# Enter file in which to save the key: (натисни Enter — default location)
# Enter passphrase: (можна залишити порожнім для зручності)Ключ збережеться в ~/.ssh/id_ed25519 (приватний) і ~/.ssh/id_ed25519.pub (публічний).
Крок 2 — Додати публічний ключ на GitHub:
# Скопіюй вміст публічного ключа:
cat ~/.ssh/id_ed25519.pub
# ssh-ed25519 AAAA... your-email@gmail.comGitHub → Settings → SSH and GPG keys → New SSH key → вставляєш вміст файлу.
Крок 3 — Перевір з'єднання:
ssh -T git@github.com
# Hi username! You've successfully authenticated, but GitHub does not provide shell access.Крок 4 — Клонуй репо через SSH URL (замість HTTPS):
git clone git@github.com:<викладач>/OOP-Tomka-CourseForHardCoders.gitЯкщо вже клонував через HTTPS — зміни remote:
git remote set-url origin git@github.com:<викладач>/OOP-Tomka-CourseForHardCoders.gitПеревірка remote URL
git remote -v
# origin https://github.com/... (HTTPS варіант)
# origin git@github.com:... (SSH варіант)Частина 7. GitHub у браузері
Після git push — перейди в браузер на сторінку репозиторію.
Перегляд гілок:
https://github.com/<user>/<repo>/branches — список усіх гілок. Видно чи запушилась Lab-01.
Перегляд комітів конкретної гілки: Натисни на назву гілки → вкладка Commits → бачиш усі коміти з повідомленнями, датами, SHA.
Порівняти гілку з main:
На сторінці гілки → кнопка Compare → видно які файли і рядки змінились порівняно з main.
Переглянути конкретний коміт: Натисни на SHA або повідомлення будь-якого коміту → бачиш diff: які рядки додані (зелені), які видалені (червоні).
Перевірити структуру файлів: Вкладка Code → можна навігувати по папках, відкривати файли, бачити їх стан на будь-якій гілці через dropdown зліва.
Типові помилки
1. Коміт потрапив у `main` замість `Lab-01`
# Відмінити останній коміт з main (зміни залишаться в файлах)
git checkout main
git reset --soft HEAD~1
# Перейти на Lab-01 і закомітити там
git checkout Lab-01
git add .
git commit -m "Lab01 Task01: ..."2. Забув `git add` — файл не потрапив у коміт
git status # видно що файл не staged
git add src/Models/Patient.cs # додай конкретний файл
git commit --amend --no-edit # додай до попереднього коміту (якщо ще не пушив)3. Неправильний формат коміту
# Змінити повідомлення останнього коміту (якщо ще не пушив)
git commit --amend -m "Lab01 Task01: add Patient class with properties"4. Конфлікт при злитті
Auto-merging src/Models/Patient.cs
CONFLICT (content): Merge conflict in src/Models/Patient.csВідкрий файл — Git позначив конфліктні місця:
<<<<<<< HEAD
public string FullName { get; set; }
=======
public string FirstName { get; set; }
public string LastName { get; set; }
>>>>>>> Lab-01Обери правильний варіант (або об'єднай), видали маркери, потім:
git add src/Models/Patient.cs
git commit -m "resolve merge conflict in Patient"5. Push rejected — remote has changes
! [rejected] main -> main (non-fast-forward)Хтось (або ти з іншого комп'ютера) запушив в main. Спочатку отримай:
git pull origin main --rebase
git push origin mainШпаргалка
| Команда | Що робить |
|---|---|
git clone <url> |
Скачати репо (одноразово) |
git status |
Стан робочої директорії і staging |
git diff |
Що змінилось (не staged) |
git diff --cached |
Що в staging |
git add <path> |
Додати файл/директорію до staging |
git add -p |
Додавати по частинах (інтерактивно) |
git commit -m "..." |
Зафіксувати зміни |
git log --oneline |
Коротка історія комітів |
git log --oneline --graph --all |
Граф усіх гілок |
git checkout main |
Перейти на гілку main |
git checkout -b Lab-01 |
Створити гілку і перейти на неї |
git branch |
Список гілок (зірочка = поточна) |
git merge --no-ff Lab-01 -m "..." |
Злити Lab-01 в поточну гілку |
git push origin main |
Запушити main на GitHub |
git push -u origin Lab-01 |
Запушити гілку і встановити tracking |
git pull origin main |
Отримати зміни з GitHub |
git stash |
Тимчасово сховати незакомічені зміни |
git stash pop |
Відновити сховані зміни |
git restore <file> |
Відмінити зміни у файлі (Working Dir) |
git restore --staged <file> |
Прибрати файл зі staging |
git reset --soft HEAD~1 |
Відмінити останній коміт (зміни лишаються) |
git diff |
Зміни в Working Directory (ще не staged) |
git diff --cached |
Зміни в Staging Area (вже додані, ще не закомічені) |
git show <SHA> |
Деталі конкретного коміту (diff + metadata) |
git commit --amend -m "..." |
Змінити повідомлення останнього коміту (до push!) |
git rm -r --cached <dir> |
Прибрати директорію з відстеження (після .gitignore) |
git remote -v |
Показати URL remote-репозиторіїв |
git remote set-url origin <url> |
Змінити URL remote (HTTPS ↔ SSH) |
Структура гілок у курсі
main
├── Lab-01 (Intro to C#) → merge → main
├── Lab-02 (Arrays) → merge → main
├── Lab-03 (Classes) → merge → main
│ ...
├── Lab-17 (EF Core Basics) → merge → main
├── Lab-18 (EF Relations) → merge → main
│ ...
└── Lab-22 (SOLID + DI) → merge → mainКожна гілка: Lab-XX з великої літери, дві цифри, дефіс.
Кожен коміт: LabXX TaskXX: дієслово + що зроблено.