12. (Л) Основи роботи з Git та GitHub. Система контролю версій, репозиторії, коміти, запит на злиття, віддалена співпраця¶
Зміст лекції¶
- Навіщо потрібен контроль версій
- Що таке система контролю версій
- Встановлення та початкове налаштування Git
- Репозиторій:
git init - Три зони та стани файлу
- Перший коміт
- Перегляд історії:
status,log,diff - Ігнорування файлів:
.gitignore - Скасування змін
- Гілки
- Злиття гілок і конфлікти
- GitHub: віддалений репозиторій
- Автентифікація: SSH-ключ
push,pull,clone- Fork і запит на злиття (Pull Request)
- Типовий процес віддаленої співпраці
- Типові помилки
Навіщо потрібен контроль версій¶
Уявіть звичну ситуацію: ви пишете практичну роботу і хочете спробувати інший підхід, але боїтеся зламати те, що вже працює. Найпростіше рішення — скопіювати файл. За тиждень каталог виглядає так:
practice5.py
practice5_new.py
practice5_new_fixed.py
practice5_final.py
practice5_final_v2.py
practice5_final_FINAL.py
Наступного дня ви вже не пам'ятаєте, у якому з файлів робочий варіант, чим _fixed відрізняється від _v2 і що саме ви змінювали. А якщо над проєктом працюють двоє — вони ще й надсилають один одному архіви поштою й вручну зводять правки докупи.
Проблеми, які тут виникають:
| Проблема | Прояв |
|---|---|
| Втрата історії | неможливо дізнатися, яким код був тиждень тому |
| Немає пояснень | незрозуміло, навіщо була зроблена та чи інша зміна |
| Неможливо відкотитися | зламали робочий код — і назад дороги немає |
| Конфлікти при співпраці | двоє правлять один файл, чиясь робота зникає |
| Немає резервної копії | зламався диск — зник увесь проєкт |
Система контролю версій розв'язує всі ці проблеми одразу: вона зберігає повну історію проєкту, дозволяє повернутися до будь-якого стану, показує, хто і що змінив, і дає кільком людям працювати над одним кодом без хаосу.
Це не лише про код
Ту саму ідею використовують для документації, конфігурацій, наукових статей і навіть законів. Наприклад, цей курс — теж репозиторій на GitHub, і кожне виправлення в тексті лекції зафіксоване як окрема зміна.
Що таке система контролю версій¶
Система контролю версій (VCS, Version Control System) — це програма, яка зберігає послідовні стани файлів проєкту та інформацію про те, хто, коли і навіщо їх змінив.
Git — найпоширеніша сьогодні система контролю версій. Її створив у 2005 році Лінус Торвальдс для розробки ядра Linux.
Ключові властивості Git:
- Розподілена — у кожного учасника є повна копія історії проєкту, а не лише остання версія. Працювати можна навіть без інтернету.
- Швидка — майже всі операції виконуються локально, без звернення до сервера.
- Знімками, а не різницями — Git зберігає стан усього проєкту на момент кожної фіксації.
Одразу розмежуємо два поняття, які часто плутають:
| Git | GitHub |
|---|---|
| Програма, що працює на вашому комп'ютері | Вебсервіс для зберігання Git-репозиторіїв |
| Безкоштовна, з відкритим кодом | Комерційний сервіс (з безкоштовним тарифом) |
| Працює без інтернету | Потрібен інтернет |
| Створена Лінусом Торвальдсом | Компанія, яка належить Microsoft |
graph LR
L1["Комп'ютер студента<br/>локальний репозиторій"] -->|push| GH["GitHub<br/>віддалений репозиторій"]
GH -->|pull| L1
GH -->|clone| L2["Комп'ютер колеги<br/>локальний репозиторій"]
L2 -->|push| GH
style L1 fill:#339af0,stroke:#333,color:#fff
style L2 fill:#339af0,stroke:#333,color:#fff
style GH fill:#51cf66,stroke:#333,color:#000
Встановлення та початкове налаштування Git¶
Ці два кроки роблять один раз, тому не переказуємо їх у лекції — офіційні інструкції завжди актуальніші:
| Крок | Де читати |
|---|---|
| Встановлення Git | Pro Git: Інсталяція Git · сторінка завантаження |
| Ім'я, пошта та інші налаштування | Pro Git: Початкове налаштування Git · документація git config |
| Обліковий запис GitHub | GitHub Docs: Creating an account |
Перед тим як рухатися далі, переконайтеся, що виконано три речі:
git --version # Git встановлений
git config user.name # ім'я вказане
git config user.email # пошта вказана
Без імені та пошти коміт не зробити
Git підписує кожну зміну автором, тому доки user.name і user.email не задані, git commit завершиться помилкою Author identity unknown. Вкажіть ту саму адресу, з якою зареєстрований ваш акаунт на GitHub, — інакше ваші коміти на сайті не будуть пов'язані з вашим профілем.
Репозиторій: git init¶
Репозиторій — це каталог проєкту разом з усією історією його змін. Ваші файли лежать там, де й лежали, а всі службові дані Git тримає окремо — у прихованому підкаталозі .git.
Створимо проєкт і перетворимо його на репозиторій:
Перевіримо, що з'явилося:
.git — це службовий каталог, у якому Git зберігає все, що потрібно йому для роботи:
| Що там лежить | Для чого |
|---|---|
об'єкти (objects/) |
збережені версії файлів та самі коміти |
посилання (refs/) |
гілки й теґи — вказівники на коміти |
HEAD |
у якій гілці ви зараз перебуваєте |
index |
вміст індексу — підготовка до наступного коміту |
config |
налаштування саме цього репозиторію |
Заглядати туди й тим паче правити щось вручну не потрібно — з усім цим ви працюєте через команди git. Важливо лише розуміти дві речі:
- історія існує лише завдяки цьому каталогу: видалите
.git— файли залишаться, але всі коміти, гілки й налаштування зникнуть, і тека знову стане звичайною; .gitлежить усередині каталогу проєкту, тому копіювання або переміщення теки проєкту переносить репозиторій разом з історією.
Ніколи не створюйте репозиторій у домашньому каталозі
Команда git init, виконана в ~ або /, змусить Git відстежувати геть усі ваші файли. Завжди спочатку створюйте окремий каталог проєкту й переходьте в нього командою cd.
Стани файлів¶
- untracked — Git бачить файл, але не стежить за ним (новий файл);
- modified — файл відстежується й змінений порівняно з останнім комітом;
- staged — зміни додані до індексу й чекають на коміт;
- committed — зміни збережені в історії.
Навіщо потрібен індекс
Індекс дозволяє зафіксувати не все підряд, а лише пов'язані між собою зміни. Ви виправили помилку в одному файлі й додали нову функцію в іншому — можна зробити два окремі коміти з різними поясненнями, замість одного незрозумілого «зробив усе».
Перший коміт¶
Створимо файл програми:
Подивимося, що каже Git:
On branch main
No commits yet
Untracked files:
(use "git add <file>..." to include in what will be committed)
hello.py
nothing added to commit but untracked files present (use "git add" to track)
Git помітив новий файл, але поки не стежить за ним. Додамо його до індексу:
On branch main
No commits yet
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: hello.py
Тепер фіксуємо зміни — робимо коміт:
[main (root-commit) 8f3a1c2] Add hello script
1 file changed, 1 insertion(+)
create mode 100644 hello.py
Коміт — це збережений знімок стану проєкту разом із метаданими. Кожен коміт містить:
| Складова | Приклад |
|---|---|
| Хеш (унікальний ідентифікатор) | 8f3a1c2d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b |
| Автор і дата | Ivan Petrenko <ivan.petrenko@example.com>, 2026-09-03 |
| Повідомлення | Add hello script |
| Посилання на попередній коміт | хеш батьківського коміту |
| Знімок файлів | стан усього проєкту на цей момент |
Коміти утворюють ланцюжок, де кожен знає свого попередника:
graph LR
C1["8f3a1c2<br/>Add hello script"] --> C2["a91b7e4<br/>Add input handling"]
C2 --> C3["c47d2f8<br/>Fix division by zero"]
C3 --> HEAD["HEAD<br/>(де ви зараз)"]
style C1 fill:#339af0,stroke:#333,color:#fff
style C2 fill:#339af0,stroke:#333,color:#fff
style C3 fill:#339af0,stroke:#333,color:#fff
style HEAD fill:#ff922b,stroke:#333,color:#000
HEAD — це вказівник на коміт, у якому ви зараз перебуваєте. Зазвичай це останній коміт поточної гілки.
Як писати повідомлення до коміту¶
Повідомлення пишуть англійською, у наказовому способі, теперішньому часі — воно відповідає на питання «що зробить цей коміт, якщо його застосувати».
| Погано | Добре |
|---|---|
fix |
Fix crash on empty input |
changes |
Add average grade calculation |
asdf |
Remove unused variables |
зробив практичну |
Add practice 5 solution |
Added new function and fixed bug and updated readme |
три окремі коміти |
Правила, яких дотримуються майже всюди:
- перший рядок — до 50 символів, без крапки в кінці;
- один коміт — одна логічно завершена зміна;
- якщо потрібні подробиці, після порожнього рядка додають детальний опис.
Коміт «на всяк випадок» наприкінці дня
Коміт Work in progress за понеділок нікому не допоможе через місяць. Фіксуйте зміни тоді, коли завершили окремий шматок роботи, і описуйте його по суті.
Скорочення¶
Якщо всі змінені файли треба додати одразу:
Крапка означає «поточний каталог з усім вмістом». Для вже відстежуваних файлів можна поєднати add і commit:
git add . вимагає уваги
Ця команда додає все, зокрема випадково створені файли, тимчасові дані та паролі. Завжди спочатку виконуйте git status і дивіться, що саме потрапить у коміт.
Перегляд історії: status, log, diff¶
git status — що відбувається зараз¶
Найчастіше вживана команда. Виконуйте її перед кожним add і commit.
On branch main
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: hello.py
Untracked files:
notes.txt
no changes added to commit (use "git add" and/or "git commit -a")
git log — історія комітів¶
commit c47d2f8b9a0e1f2d3c4b5a6978899aabbccddeef (HEAD -> main)
Author: Ivan Petrenko <ivan.petrenko@example.com>
Date: Wed Sep 3 10:41:12 2026 +0300
Fix division by zero
commit a91b7e4c5d6f7089a1b2c3d4e5f60718293a4b5c
Author: Ivan Petrenko <ivan.petrenko@example.com>
Date: Wed Sep 3 10:22:05 2026 +0300
Add input handling
Компактний вигляд, який використовують найчастіше:
* c47d2f8 (HEAD -> main) Fix division by zero
* a91b7e4 Add input handling
* 8f3a1c2 Add hello script
Вихід із перегляду
Якщо історія довга, Git відкриває її в програмі-переглядачі. Гортати — стрілками, вийти — клавіша q.
git diff — що саме змінилося¶
diff --git a/hello.py b/hello.py
index 3b18e51..b6fc4c6 100644
--- a/hello.py
+++ b/hello.py
@@ -1 +1,2 @@
-print("Hello, Git!")
+name = input("Your name: ")
+print(f"Hello, {name}!")
Рядки з - вилучені, з + — додані. Варіанти команди:
| Команда | Що показує |
|---|---|
git diff |
зміни в робочому каталозі, ще не додані до індексу |
git diff --staged |
зміни, вже додані до індексу |
git diff HEAD |
усі зміни від останнього коміту |
git show c47d2f8 |
вміст конкретного коміту |
Ігнорування файлів: .gitignore¶
У проєкті завжди є файли, яким не місце в репозиторії: кеш інтерпретатора, віртуальне середовище, налаштування редактора, паролі. Їх перелічують у файлі .gitignore у корені проєкту.
Створіть у корені проєкту файл .gitignore з таким вмістом:
# кеш інтерпретатора Python
__pycache__/
*.pyc
# віртуальне середовище
env/
.venv/
# налаштування редактора
.vscode/
.idea/
# локальні дані та секрети
*.log
.env
Після цього Git перестане показувати такі файли в git status.
| Шаблон | Що ігнорує |
|---|---|
*.log |
усі файли з розширенням .log |
env/ |
увесь каталог env |
secret.txt |
конкретний файл |
!important.log |
виняток: цей файл не ігнорувати |
Сам файл .gitignore потрібно закомітити — він частина проєкту:
Ніколи не комітьте паролі та ключі
Видалити секрет із історії Git дуже складно: навіть після видалення файлу він залишається в старих комітах, а якщо репозиторій публічний — його вже могли скопіювати. Паролі, токени та ключі API тримають у файлі .env, який завжди перелічений у .gitignore.
.gitignore не діє на вже відстежувані файли
Якщо файл потрапив у коміт раніше, додавання його до .gitignore нічого не змінить. Спочатку приберіть його з-під нагляду: git rm --cached secret.txt.
Скасування змін¶
Найцінніша можливість системи контролю версій — повернути все як було. Команда залежить від того, наскільки далеко зайшла зміна.
| Ситуація | Команда |
|---|---|
| Зіпсував файл, коміту ще не було | git restore hello.py |
| Додав до індексу зайвий файл | git restore --staged notes.txt |
| Помилка в повідомленні останнього коміту | git commit --amend -m "Correct message" |
| Забув додати файл в останній коміт | git add forgotten.py && git commit --amend --no-edit |
| Треба скасувати давній коміт | git revert c47d2f8 |
| Подивитися стан проєкту в старому коміті | git checkout c47d2f8 |
git revert не стирає історію, а створює новий коміт, який скасовує зміни зазначеного:
graph LR
C1["8f3a1c2<br/>Add hello script"] --> C2["a91b7e4<br/>Add feature"]
C2 --> C3["c47d2f8<br/>Revert 'Add feature'"]
style C1 fill:#339af0,stroke:#333,color:#fff
style C2 fill:#ff922b,stroke:#333,color:#000
style C3 fill:#51cf66,stroke:#333,color:#000
git reset --hard знищує роботу назавжди
Ця команда безповоротно видаляє незакомічені зміни в робочому каталозі. Використовуйте її, лише якщо точно розумієте, що втратите. Для скасування вже опублікованих комітів завжди беріть git revert — він безпечний для тих, хто вже завантажив вашу історію.
Закомічене майже неможливо втратити
Якщо зміни потрапили в коміт, їх практично завжди можна знайти — навіть після невдалих експериментів. У цьому допомагає git reflog, журнал усіх переміщень HEAD. Тому просте правило: комітьте частіше.
Гілки¶
Гілка (branch) — це незалежна лінія розробки. Вона дозволяє працювати над новою можливістю, не чіпаючи робочу версію програми.
Технічно гілка — це просто рухомий вказівник на коміт. Тому створення гілки в Git миттєве й нічого не копіює.
Типова ситуація: основна гілка main містить робочий код, а нову функцію ви пишете в окремій гілці.
graph LR
M1["Add hello script"] --> M2["Add input handling"]
M2 --> M3["Fix typo in output"]
M3 --> M4["Merge feature-average"]
M4 --> M5["Update readme"]
M2 -->|"git switch -c feature-average"| F1["Add average function"]
F1 --> F2["Add report function"]
F2 -->|"git merge"| M4
style M1 fill:#339af0,stroke:#333,color:#fff
style M2 fill:#339af0,stroke:#333,color:#fff
style M3 fill:#339af0,stroke:#333,color:#fff
style M4 fill:#51cf66,stroke:#333,color:#000
style M5 fill:#339af0,stroke:#333,color:#fff
style F1 fill:#ffd43b,stroke:#333,color:#000
style F2 fill:#ffd43b,stroke:#333,color:#000
Верхня лінія — гілка main, нижня — feature-average. Гілка відгалужується від того коміту, який існував на момент її створення, і повертається в main під час злиття.
Команди для роботи з гілками¶
git branch # список гілок
git switch -c feature-average # створити гілку й перейти до неї
git switch main # повернутися до main
git branch -d feature-average # видалити злиту гілку
Зірочка позначає поточну гілку.
switch чи checkout
У старих матеріалах ви побачите git checkout -b feature-average. Ця команда працює й досі, але сучасний Git має дві окремі, зрозуміліші команди: git switch — для гілок, git restore — для файлів. Використовуйте їх.
Навіщо потрібні гілки:
- Ізоляція — експеримент не ламає робочу версію в
main; - Паралельна робота — кожен учасник команди працює у своїй гілці;
- Огляд коду — гілку зручно перевіряти цілком перед злиттям;
- Легке скасування — невдалу ідею просто видаляють разом із гілкою.
Злиття гілок і конфлікти¶
Коли робота в гілці завершена, її зливають (merge) в основну. Для цього переходять у гілку-приймач і викликають git merge:
Після злиття гілку зазвичай видаляють:
Конфлікт злиття¶
Конфлікт виникає, коли в двох гілках змінено той самий рядок того самого файлу. Git не може вирішити, чия версія правильна, і просить розібратися людину.
Auto-merging greet.py
CONFLICT (content): Merge conflict in greet.py
Automatic merge failed; fix conflicts and then commit the result.
Git позначає проблемне місце прямо у файлі:
name = input("Your name: ")
<<<<<<< HEAD
print(f"Hello, {name}!")
=======
print(f"Welcome, {name}!")
>>>>>>> feature-average
Читається це так:
| Маркер | Значення |
|---|---|
<<<<<<< HEAD |
початок вашої версії (поточна гілка) |
======= |
межа між версіями |
>>>>>>> feature-average |
кінець версії з гілки, яку зливають |
Розв'язати конфлікт — означає вручну відредагувати файл: залишити потрібний варіант (або скласти новий) і обов'язково прибрати всі маркери:
Далі повідомляємо Git, що конфлікт вичерпано:
Маркери — це не код
Якщо забути прибрати <<<<<<< і =======, програма впаде з SyntaxError. Після розв'язання конфлікту завжди запускайте програму й перевіряйте, що вона працює.
Як конфліктувати рідше
Конфлікти — нормальна частина роботи, а не аварія. Але їх стає менше, якщо: частіше забирати зміни з main (git pull), робити невеликі коміти й домовлятися в команді, хто які файли зараз править.
GitHub: віддалений репозиторій¶
Локальний репозиторій живе лише на вашому комп'ютері. Віддалений репозиторій (remote) — його копія на сервері, доступна з будь-якого пристрою й іншим людям.
Що дає GitHub:
- резервну копію проєкту;
- доступ до коду з будь-якого комп'ютера;
- спільну роботу з іншими;
- огляд коду через запити на злиття;
- публічне портфоліо (роботодавці справді його дивляться);
- безкоштовний хостинг сайтів через GitHub Pages.
Створення репозиторію на GitHub¶
- Зареєструйтеся на github.com.
- Натисніть New repository.
- Вкажіть назву латиницею без пробілів, наприклад
python-practice. - Оберіть Public (публічний) або Private (приватний).
- Не додавайте README, якщо збираєтесь підключити вже наявний локальний репозиторій — так простіше.
- Натисніть Create repository.
Автентифікація: SSH-ключ¶
Щоб GitHub дозволив вам записувати зміни, він має переконатися, що це справді ви. Пароль для цього давно не використовується. Є два способи: персональний токен (Personal Access Token) для протоколу HTTPS і SSH-ключ. Розглянемо SSH — його налаштовують один раз і більше про нього не згадують.
Ідея: ви створюєте пару ключів. Приватний ключ залишається на вашому комп'ютері й нікому не показується. Публічний ключ ви завантажуєте на GitHub. Сервер перевіряє відповідність — і пускає без пароля.
Створення ключа:
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/ivan/.ssh/id_ed25519):
Enter passphrase (empty for no passphrase):
Your identification has been saved in /home/ivan/.ssh/id_ed25519
Your public key has been saved in /home/ivan/.ssh/id_ed25519.pub
На всі три питання достатньо натиснути Enter (парольна фраза необов'язкова, але додає захисту).
Показуємо публічний ключ:
Копіюємо весь рядок і на GitHub переходимо: Settings → SSH and GPG keys → New SSH key, вставляємо, зберігаємо.
Перевірка:
Файл без розширення .pub — приватний
id_ed25519.pub — публічний ключ, його можна показувати. id_ed25519 без .pub — приватний, його не надсилають нікому й ніколи не комітять у репозиторій.
push, pull, clone¶
Підключення віддаленого репозиторію¶
Після створення репозиторію GitHub показує його адресу. Прив'язуємо її до локального репозиторію під стандартним іменем origin:
origin git@github.com:ivan-petrenko/python-practice.git (fetch)
origin git@github.com:ivan-petrenko/python-practice.git (push)
git push — вивантажити зміни¶
Enumerating objects: 6, done.
Counting objects: 100% (6/6), done.
Writing objects: 100% (6/6), 512 bytes | 512.00 KiB/s, done.
To github.com:ivan-petrenko/python-practice.git
* [new branch] main -> main
branch 'main' set up to track 'origin/main'.
Прапорець -u потрібен лише першого разу: він запам'ятовує зв'язок між локальною гілкою й гілкою на сервері. Надалі достатньо:
git pull — забрати зміни¶
remote: Enumerating objects: 5, done.
Updating a91b7e4..f28c103
Fast-forward
average.py | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
git pull завантажує зміни з сервера і одразу зливає їх із вашою гілкою. Якщо ви хочете лише подивитися, що нового, не зливаючи, використовують git fetch.
git clone — отримати чужий репозиторій¶
Cloning into 'python-practice'...
remote: Enumerating objects: 12, done.
Receiving objects: 100% (12/12), done.
clone створює каталог, завантажує всю історію проєкту й автоматично налаштовує origin. Виконувати git init після цього не треба.
graph TD
subgraph Локально
WD["Робочий каталог"] -->|git add| ST["Індекс"]
ST -->|git commit| LR["Локальний репозиторій"]
end
LR -->|git push| RR["GitHub"]
RR -->|git pull| LR
RR -->|git clone| NEW["Новий локальний репозиторій"]
style WD fill:#339af0,stroke:#333,color:#fff
style ST fill:#ffd43b,stroke:#333,color:#000
style LR fill:#51cf66,stroke:#333,color:#000
style RR fill:#ff922b,stroke:#333,color:#000
style NEW fill:#51cf66,stroke:#333,color:#000
Fork і запит на злиття (Pull Request)¶
Ви не можете просто так записувати зміни в чужий репозиторій — інакше будь-хто зіпсував би будь-який проєкт. Натомість існує ввічливий механізм: запит на злиття.
Fork — це ваша особиста копія чужого репозиторію на GitHub. З нею ви робите що завгодно.
Pull Request (PR) — «запит на злиття»: пропозиція власникові оригінального проєкту взяти ваші зміни до себе. Це не команда Git, а можливість GitHub.
graph TD
A["Оригінальний репозиторій<br/>на GitHub"] -->|1. Fork| B["Ваша копія<br/>на GitHub"]
B -->|2. git clone| C["Локальна копія"]
C -->|3. git switch -c fix-typo| D["Гілка зі змінами"]
D -->|4. git commit| E["Коміт"]
E -->|5. git push| B
B -->|6. Pull Request| A
A -->|7. Review + Merge| F["Зміни в оригіналі"]
style A fill:#ff922b,stroke:#333,color:#000
style B fill:#339af0,stroke:#333,color:#fff
style C fill:#339af0,stroke:#333,color:#fff
style D fill:#ffd43b,stroke:#333,color:#000
style E fill:#ffd43b,stroke:#333,color:#000
style F fill:#51cf66,stroke:#333,color:#000
Покроково:
- На сторінці чужого репозиторію натискаєте Fork.
-
Клонуєте свою копію:
-
Створюєте гілку під конкретну зміну:
-
Правите файли й фіксуєте зміни:
-
Вивантажуєте гілку у свою копію на GitHub:
-
GitHub покаже кнопку Compare & pull request. Натискаєте, пишете заголовок і опис — що змінено й навіщо — і надсилаєте.
- Власник проєкту переглядає зміни, залишає коментарі, просить щось виправити або натискає Merge pull request.
Якщо після зауважень потрібно щось доправити, ви просто робите новий коміт у тій самій гілці й виконуєте git push — запит на злиття оновиться автоматично.
Що таке огляд коду
Розділ Files changed у запиті на злиття показує всі зміни порядково, і будь-хто може прокоментувати конкретний рядок. Саме так у командах знаходять помилки до того, як вони потраплять у робочу версію. У навчанні це теж корисно: попросіть однокурсника переглянути ваш PR.
Один PR — одна зміна
Запит, у якому одночасно виправлена помилка, доданий новий розділ і переформатовано весь файл, дуже важко переглядати. Робіть окремий PR для кожної логічно завершеної зміни.
Типовий процес віддаленої співпраці¶
Зберемо все докупи. Так виглядає звичайний робочий день у команді (і той самий процес підходить для навчального проєкту вдвох-утрьох):
# 1. забрати останні зміни колег
git switch main
git pull
# 2. створити гілку під свою задачу
git switch -c add-grade-report
# 3. писати код, періодично фіксуючи завершені шматки
git status
git add report.py
git commit -m "Add grade report function"
# 4. вивантажити гілку на GitHub
git push -u origin add-grade-report
# 5. відкрити Pull Request, дочекатися огляду й злиття
# 6. повернутися до main і оновитися
git switch main
git pull
git branch -d add-grade-report
Правила, які роблять співпрацю безболісною:
| Правило | Чому |
|---|---|
Починати день із git pull |
менше конфліктів під час злиття |
Не працювати безпосередньо в main |
main завжди має містити робочий код |
| Одна гілка — одна задача | легше переглядати й скасовувати |
| Комітити часто, дрібно | простіше знайти, де саме зламалося |
| Писати зрозумілі повідомлення | історія стає документацією проєкту |
| Не переписувати опубліковану історію | інакше зламаєте роботу колегам |
Шпаргалка команд¶
| Команда | Дія |
|---|---|
git init |
створити репозиторій |
git clone <url> |
завантажити віддалений репозиторій |
git status |
стан робочого каталогу та індексу |
git add <file> |
додати зміни до індексу |
git commit -m "msg" |
зафіксувати зміни |
git log --oneline --graph --all |
компактна історія |
git diff |
що змінилося |
git restore <file> |
скасувати зміни у файлі |
git restore --staged <file> |
прибрати файл з індексу |
git branch |
список гілок |
git switch -c <name> |
створити гілку й перейти до неї |
git switch <name> |
перейти до гілки |
git merge <name> |
злити гілку в поточну |
git remote -v |
список віддалених репозиторіїв |
git push |
вивантажити коміти на сервер |
git pull |
забрати зміни з сервера |
git revert <hash> |
скасувати коміт новим комітом |
Типові помилки¶
| Помилка | Причина | Виправлення |
|---|---|---|
fatal: not a git repository |
команда виконана поза репозиторієм | перейти в каталог проєкту або зробити git init |
Author identity unknown |
не налаштовані ім'я та пошта | git config --global user.name і user.email |
nothing to commit, working tree clean |
забули git add або справді немає змін |
перевірити git status |
Permission denied (publickey) |
SSH-ключ не доданий на GitHub | створити ключ і додати його в налаштуваннях |
Updates were rejected... fetch first |
на сервері є коміти, яких немає у вас | git pull, розв'язати конфлікти, потім git push |
CONFLICT (content): Merge conflict |
обидві гілки змінили той самий рядок | відредагувати файл, прибрати маркери, git add + git commit |
SyntaxError після злиття |
у файлі залишилися маркери <<<<<<< |
прибрати маркери й запустити програму |
error: pathspec 'main' did not match |
помилка в назві гілки | звірити назву через git branch |
| Репозиторій важить сотні мегабайтів | закомічені env/, дані, картинки |
додати .gitignore, прибрати через git rm --cached |
| Пароль потрапив у репозиторій | секрет не був у .gitignore |
негайно змінити пароль, а не лише видалити файл |
Підсумок¶
- Система контролю версій зберігає історію проєкту, дозволяє повертатися до попередніх станів і працювати над кодом кільком людям одночасно.
- Git — програма на вашому комп'ютері, GitHub — сервіс для зберігання Git-репозиторіїв в інтернеті. Це різні речі.
- Перед першим комітом обов'язково налаштуйте
user.nameіuser.email. - Репозиторій — каталог проєкту разом з історією змін; створюється командою
git initабоgit clone..git— службовий каталог Git усередині проєкту, руками його не чіпають, але саме в ньому живе вся історія. - Зміни проходять три зони: робочий каталог → (
git add) індекс → (git commit) репозиторій. - Коміт — знімок проєкту з хешем, автором, датою, повідомленням і посиланням на попередній коміт.
- Повідомлення коміту пишуть англійською, наказовим способом і по суті зміни:
Fix crash on empty input, а неfix. git status,git log,git diff— три команди, які показують, що відбувається; виконуйтеgit statusперед кожним комітом..gitignoreтримає поза репозиторієм кеш, віртуальне середовище й секрети; сам файл комітять.- Скасувати зміни можна
git restore(до коміту),git commit --amend(останній коміт),git revert(безпечно для опублікованої історії). - Гілка — незалежна лінія розробки; створюється миттєво, ізолює експеримент від робочого коду.
- Конфлікт злиття виникає, коли дві гілки змінили той самий рядок; його розв'язують вручну, прибираючи маркери
<<<<<<<,=======,>>>>>>>. git pushвивантажує коміти на сервер,git pullзабирає їх звідти,git cloneстворює локальну копію віддаленого репозиторію.- Fork — особиста копія чужого репозиторію; Pull Request — запит на злиття ваших змін в оригінальний проєкт із можливістю огляду коду.
- Робочий цикл у команді:
pull→ гілка → коміти →push→ Pull Request → злиття.
Корисні посилання¶
- Книга Pro Git українською — повний безкоштовний підручник
- Офіційна документація Git
- Learn Git Branching — інтерактивний тренажер гілок у браузері
- Документація GitHub
- Генерація SSH-ключа для GitHub
- Шаблони .gitignore для різних мов
- Oh Shit, Git!?! — короткі рецепти для типових аварійних ситуацій
Домашнє завдання¶
Мета — завести власний репозиторій із виконаними практичними роботами й навчитися працювати з ним щодня.
-
Встановіть Git і налаштуйте його своїми даними (
user.name,user.email— та сама пошта, що й на GitHub), скориставшись посиланнями з розділу «Встановлення та початкове налаштування Git». Додайте у звіт вивід командиgit config --list. -
Створіть каталог
python-practice-<ваше прізвище латиницею>, виконайте в ньомуgit initі додайте файлREADME.mdз вашим іменем, групою та коротким описом репозиторію. Зробіть перший коміт із повідомленнямAdd readme. Наведіть вивідgit statusдо і після коміту. -
Скопіюйте в репозиторій свої розв'язки практичних робіт 3–5 і закомітьте їх трьома окремими комітами — по одному на практичну, зі змістовними повідомленнями. Додайте вивід
git log --oneline. -
Створіть
.gitignore, який ігнорує__pycache__/,*.pyc,env/та.vscode/. Переконайтеся, що після цьогоgit statusчистий, і поясніть одним реченням, чому ці файли не варто зберігати в репозиторії. -
Зареєструйтеся на GitHub, налаштуйте SSH-ключ, створіть віддалений репозиторій і вивантажте туди свою роботу (
git remote add,git push -u origin main). У звіті вкажіть посилання на репозиторій і додайте вивідssh -T git@github.com. -
Створіть гілку
add-personal-info, додайте в ній файлabout.py, який друкує ваші ім'я, групу та улюблену мову програмування (латиницею). Зафіксуйте зміни, поверніться вmain, злийте гілку та видаліть її. Наведіть вивідgit log --oneline --graph --allдо і після злиття. -
Конфлікт власноруч. У гілці
mainзмініть уabout.pyрядок привітання на один варіант, а в новій гілціchange-greeting— той самий рядок на інший. Спробуйте злити гілки, отримайте конфлікт, збережіть текст помилки та вміст файлу з маркерами, розв'яжіть конфлікт і закомітьте результат. Опишіть у двох-трьох реченнях, що саме сталося і як ви обрали правильну версію. -
Співпраця. Домовтеся з одногрупником: зробіть fork його репозиторію, створіть гілку, додайте в неї файл
<ваше прізвище>_review.mdіз коротким відгуком про його код, вивантажте гілку й відкрийте Pull Request. Він робить те саме з вашим репозиторієм. У звіті наведіть посилання на створений вами PR і знімок екрана сторінки Files changed.
Знайшли помилку чи бажаєте додати інформацію, щоб покращити курс? Створіть issue на GitHub