Перейти до вмісту

Модуль 0.6: Основи Git — Відстежуйте свою роботу

Складність: [ПОЧАТКІВЕЦЬ]

Час на проходження: 60 хвилин

Передумови: Модуль 0.5 (Редагування файлів)


Що ви зможете зробити

Розділ «Що ви зможете зробити»

Після завершення цього модуля ви зможете:

  • Діагностувати стан репозиторію, інтерпретуючи вивід git status, git diff та git log, замість того, щоб вгадувати, що збереже Git.
  • Формувати сфокусовані коміти, переміщуючи вибрані зміни файлів з робочого каталогу до staging area, а потім — в історію репозиторію.
  • Налаштувати безпечне локальне середовище Git із точною ідентифікацією автора, новим репозиторієм та політикою ігнорування для згенерованих файлів і секретів.
  • Порівнювати часові шкали локального та віддаленого репозиторіїв, щоб вибирати, коли виконувати clone, push, pull, fetch або робити паузу для вирішення конфліктів.
  • Спроєктувати невеликий Git workflow для конфігураційних файлів Kubernetes, який створює придатну для рев’ю історію без витоку облікових даних чи згенерованих артефактів.

Гіпотетичний сценарій: операційна група зберігає маніфести Kubernetes на спільному диску, оскільки кожен може швидко відкрити папку, відредагувати YAML та скопіювати останні файли у скрипт розгортання. Одного ранку production простір імен змінюється у спосіб, якого ніхто не очікував, кластер приймає оновлення, і команда не може визначити, чи є поточний файл потрібною версією, незавершеним експериментом або копією старішої конфігурації. Розслідування збою просувається повільно не тому, що Kubernetes є чимось таємничим, а тому, що команда не має достовірної хронології текстових файлів, які описують її інфраструктуру.

Git розв’язує цю операційну проблему, перетворюючи звичайні файли на обдуману історію, яку можна перевірити. Він записує знімки, авторів, повідомлення та батьківські зв’язки, щоб команда могла порівняти, що змінилося, чому воно змінилося та коли зміна потрапила до спільного запису. Це важливо для вихідного коду, але так само важливо й для хмарної розробки: Deployment, Namespace, модуль Terraform або визначення CI-конвеєра — усе це може змінити поведінку production-середовища, коли автоматизація довіряє репозиторію як єдиному джерелу істини.

Цей модуль починається з локального Git, оскільки впевненість у локальній роботі передує співпраці. Ви ініціалізуєте репозиторій, налаштуєте ідентифікацію, навмисно додасте зміни до індексу, прочитаєте відмінності перед фіксацією та використаєте файл .gitignore, щоб уникнути зайвого шуму в історії. Наприкінці ви маєте не просто пам’ятати список команд; ви маєте Діагностувати, що саме збирається зробити Git, та пояснювати, чи наступною дією має бути git add, git commit, git pull, git push, чи взагалі жодної дії.

Таке діагностичне мислення відрізняє корисного користувача Git від того, хто знає лише ідеальний сценарій. Інструкція працює, коли кожен файл міститься саме там, де цього очікує посібник, але інженерна робота рідко залишається такою ж охайною. У вас можуть бути незавершені редагування, згенеровані журнали, нові віддалені фіксації колеги або локальний файл, який ніколи не повинен залишати вашу машину. Git надає вам точні інструменти для кожного випадку, і цей модуль навчить вас вибирати серед них на основі спостережуваного стану.

Як Git сприймає ваші файли

Розділ «Як Git сприймає ваші файли»

Git часто описують як контроль версій, але початківці іноді чують цю фразу і уявляють хмарний інструмент резервного копіювання, який безперервно синхронізує найновіший вміст файлів. Ця модель призводить до помилок, оскільки Git не намагається віддзеркалювати кожне натискання клавіші на сервер. Git записує обдумані знімки, коли ви його про це просите, зберігає ці знімки в локальній базі даних і дозволяє вам вирішувати, які саме зміни належать одна одній, перш ніж вони стануть частиною історії проєкту.

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

Історично склалося так, що багато систем контролю версій були централізованими. Центральний сервер зберігав авторитетну історію, і клієнти залежали від цього сервера для перевірки історії або створення нових фіксацій. Git є розподіленим: коли ви клонуєте репозиторій, ви отримуєте повну локальну історію, а не лише найновіші файли. Це означає, що ви можете перевіряти фіксації, порівнювати версії та створювати локальні фіксації в автономному режимі, а потім синхронізувати їх з віддаленим сервером, коли з’являється зв’язок і можливість координації команди.

Практичний результат полягає в тому, що Git має дві особистості. Локально — це швидка база даних і механізм порівняння для ваших файлів. Для співпраці — це протокол синхронізації, який дозволяє кільком людям обмінюватися історіями через віддалений репозиторій, такий як GitHub, GitLab або Bitbucket. Хороші звички роботи з Git походять від поваги до обох особистостей: спочатку робіть чисті локальні фіксації, а потім діліться ними лише після того, як перевірите, що вони містять.

Цей локально-орієнтований дизайн особливо корисний у хмарній роботі, оскільки багато інфраструктурних змін потребують ретельного розгляду перед тим, як вони торкнуться кластера. Ви можете відредагувати маніфести, порівняти патч, зафіксувати вузьку зміну та попросити іншого інженера переглянути гілку, ще нічого не застосовуючи до Kubernetes. Git не перевіряє поведінку кластера замість вас, але він дає команді стабільний об’єкт для обговорення. Рецензент може вказати на рядок, фіксацію або гілку замість того, щоб покладатися на розпливчастий опис того, що змінилося.

Git керує вашими файлами через три логічні зони. Назви мають значення, оскільки більшість незрозумілих повідомлень Git — це просто вказівка на те, яка зона містить зміну. Ваш робочий каталог — це місце, де ваш редактор записує файли, індексна зона — це місце, де ви збираєте наступний знімок, а репозиторій — це збережена історія всередині прихованої бази даних .git. Індексна зона — це та частина, яку пропускає багато початківців, але саме вона дозволяє перетворити безладну роботу на чисту фіксацію.

+---------------------+ +---------------------+ +---------------------+
| | | | | |
| Working Directory | ----> | Staging Area | ----> | Repository |
| (Your local files) | | (The loading dock) | | (The saved history) |
| | | | | |
+---------------------+ +---------------------+ +---------------------+
| | |
| 1. Modify files | |
|---------------------------->| |
| | 2. Group changes |
| |---------------------------->|
| | |
| |
|<----------------------------------------------------------|
3. Restore old versions

Робочий каталог — це поточна папка проєкту на диску. Коли ви редагуєте namespace.yaml, створюєте README або видаляєте тимчасовий файл, ви змінюєте робочий каталог. Git може виявити, що відстежувані файли відрізняються від останньої фіксації, і він також може помітити нові невідстежувані файли, але він не вирішить автоматично, що ці зміни належать до наступного знімка. Ось чому git status — це перша діагностична команда, яку варто вивчити.

Індексна зона, яку також називають індексом, — це свідомий вибір того, що міститиме наступна фіксація. Ви можете додати до індексу один файл, залишивши інший змінений файл поза індексом, або навіть додати лише окремі фрагменти з файлу за допомогою складніших команд пізніше. Такий поділ є цінним, коли реальна робота буває хаотичною. Сеанс налагодження може зачепити автентифікацію, розгортання YAML та локальні нотатки, але фіксація повинна фіксувати одну логічну причину зміни.

Репозиторій — це постійна локальна база даних, яка зберігається всередині .git, де живуть фіксації. Фіксація реєструє вміст файлу, метадані автора, повідомлення, мітку часу та вказівник на батьківську фіксацію. У звичайних репозиторіях кожна фіксація має назву у вигляді хешу, наприклад, ідентифікатора об’єкта SHA-1, а новіші версії Git також можуть підтримувати репозиторії SHA-256. Важлива ідея для початківців є простішою за криптографію: якщо змінюється вміст або метадані, змінюється й ідентифікатор.

Зупиніться та подумайте: ви виправили помилку підключення до бази даних у db.py, але під час її пошуку ви також додали тимчасові виклики print до auth.py та api.py. Яка частина Git дозволяє вам зберегти лише справжнє виправлення, залишаючи тимчасовий код налагодження на диску? Відповідь — індексна зона, оскільки вона відокремлює файли, які ви все ще редагуєте, від файлів, які ви готові зберегти як наступний знімок.

Налаштувати Git та Створити репозиторій

Розділ «Налаштувати Git та Створити репозиторій»

Git — це насамперед інструмент командного рядка, навіть коли команди використовують навколо нього графічні клієнти або веб-інтерфейси. Платформні інженери повинні вільно володіти термінальною версією, оскільки багато робочих процесів відбуваються через SSH, у журналах автоматизації або на машинах, де графічний клієнт недоступний. Мета полягає не в тому, щоб запам’ятати кожен параметр. Мета — стати настільки вільним, щоб стан репозиторію був видимим, а не таємничим.

Почніть з перевірки, чи встановлений Git. Ваша точна версія може відрізнятися від прикладу, і це нормально. Номер версії має значення, коли ви вирішуєте проблеми з функціями, але базові команди в цьому модулі залишаються стабільними вже багато років. Якщо ця команда завершується помилкою, встановіть Git за допомогою менеджера пакетів вашої операційної системи, перш ніж продовжити, а потім знову відкрийте термінал, щоб виконуваний файл був доступний у вашому PATH.

Terminal window
git --version

Очікуваний вивід має містити версію Git, встановлену на вашій машині; точний номер може відрізнятися від цього прикладу.

git version 2.39.2

Перш ніж створювати фіксації, налаштуйте ідентифікацію, яку Git поміщатиме в метадані фіксації. Це не те саме, що автентифікація на GitHub під час push-запиту. Ім’я та електронна адреса, налаштовані тут, відповідають на запитання: «Хто автор цього знімка?» Віддалена автентифікація відповідає на інше запитання: «Чи дозволено цій особі завантажувати дані на цей сервер?» Відокремлення цих концепцій запобігає плутанині, коли фіксація успішно виконується локально, але пізніше під час push з’являється запит на введення облікових даних.

Замініть ім’я та електронну адресу в прикладі нижче на ваші власні реальні дані перед запуском команд.

Terminal window
# Set your name (use your real name, this appears in the history)
git config --global user.name "Your Name"
# Set your email address
git config --global user.email "you@example.com"

Прапорець --global записує до конфігурації, пов’язаної з вашим обліковим записом користувача на цьому комп’ютері, зазвичай у ~/.gitconfig. Ви також можете встановити конфігурацію для конкретного репозиторію без прапорця --global, що корисно, коли один ноутбук використовується для особистих і робочих репозиторіїв. Наразі достатньо глобального налаштування для початківців, і ви можете перевірити його за допомогою команди, яка виводить параметри, що їх бачить Git.

Terminal window
git config --list

Тепер створіть невеликий каталог проєкту для прикладів. Проєкт використовує імена файлів у стилі Kubernetes, оскільки конфігурація інфраструктури — це та сфера, де звички Git швидко перетворюються на операційні звички. Наведені нижче команди створюють каталог, входять до нього та ініціалізують репозиторій. Запускайте їх у навчальному місці, наприклад, у своєму домашньому каталозі або тимчасовій папці, а не всередині реального робочого репозиторію.

Terminal window
# Create a new directory
mkdir k8s-webapp
cd k8s-webapp
# Tell Git to start tracking this directory
git init --initial-branch=main

Очікуваний вивід має підтвердити, що Git створив порожню базу даних репозиторію у прихованому каталозі .git.

Initialized empty Git repository in /home/alex/k8s-webapp/.git/

Що саме змінилося? Git створив прихований каталог .git всередині k8s-webapp. Цей прихований каталог не є декоративним; це база даних репозиторію для цього проєкту. Він містить об’єкти, посилання, локальну конфігурацію та механізми, які Git використовує, щоб знати, на якій гілці ви перебуваєте. Якщо ви видалите .git, ваші поточні файли можуть залишитися на диску, але локальна історія, гілки та ідентифікація репозиторію зникнуть.

Terminal window
# List all files, including hidden ones
ls -la

Очікуваний вивід має показати прихований каталог .git поруч зі звичайними записами поточного та батьківського каталогів.

total 12
drwxr-xr-x 3 alex alex 4096 Oct 12 10:00 .
drwxr-xr-x 5 alex alex 4096 Oct 12 09:59 ..
drwxr-xr-x 7 alex alex 4096 Oct 12 10:00 .git

Перш ніж запускати наступну команду в будь-якому новому репозиторії, візьміть за звичку запитувати себе, який стан ви очікуєте побачити від Git. У зовсім новому репозиторії, де немає відстежуваних файлів і жодної фіксації, git status повинен повідомити вам, що фіксацій ще немає і що Git не має нічого в індексі. Ця звичка прогнозування є ціннішою, ніж здається, оскільки кожне подальше завдання з відновлення в Git починається з порівняння очікуваного стану з фактично спостережуваним.

Формуйте коміти усвідомлено

Розділ «Формуйте коміти усвідомлено»

Команда, яку ви використовуватимете найчастіше, — це git status, оскільки це найбезпечніший спосіб запитати Git, що він бачить. Вона не змінює файли, не створює коміти і не звертається до віддаленого репозиторію. Вона просто повідомляє, на якій гілці ви перебуваєте, чи є в робочому каталозі змінені файли, які зміни додано до індексу (staged), а які файли не відстежуються (untracked). Ставтеся до неї як до свого компаса перед кожним рішенням щодо додавання в індекс, створення коміту, виконання pull чи push.

Є ще одна неявна причина, чому git status має значення: вона навчає вас словнику Git у контексті. «Untracked» означає, що Git бачить файл, але не має для нього зафіксованого базового стану. «Changes not staged» означає, що Git відстежує файл, але поточна робоча копія відрізняється від останнього коміту. «Changes to be committed» означає, що індекс вже містить вміст для наступного знімка. Ці повідомлення — не просто шум; це компактний звіт про стан системи.

Створіть перший файл у навчальному репозиторії. Цей файл визначає простір імен (Namespace) Kubernetes — простий об’єкт, який дозволяє нам зосередитися на поведінці Git без необхідності мати запущений кластер. Вміст є валідним YAML, але головне тут — робочий процес: написати файл, перевірити стан репозиторію, додати файл до індексу та зафіксувати цей підготовлений знімок за допомогою повідомлення, яке пояснює намір.

Terminal window
cat << 'EOF' > namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: webapp-prod
EOF

Одразу виконайте git status. Новачки часто пропускають цей крок, оскільки вважають, що й так знають, що змінилося, але пам’ять — це слабка система аудиту. Звіт Git — це об’єктивний стан. У промисловій розробці саме ця об’єктивність запобігає випадковому потраплянню тимчасових нотаток, згенерованих файлів або секретних даних в історію.

Terminal window
git status

Вивід має класифікувати новий файл як невідстежуваний (untracked), оскільки він існує на диску, але не є частиною наступного знімка.

On branch main
No commits yet
Untracked files:
(use "git add <file>..." to include in what will be committed)
namespace.yaml
nothing added to commit but untracked files present (use "git add" to track)

Файл є невідстежуваним (untracked), що означає, що Git бачить його в робочому каталозі, але йому ще не сказали включити його в систему контролю версій. Невідстежувані файли не є частиною наступного коміту, і Git не порівнюватиме майбутні редагування з ними, доки ви не додасте їх до індексу та не зафіксуєте комітом. Така поведінка є навмисною. Каталог часто містить нотатки, згенеровані артефакти або локальні тестові файли, які не повинні автоматично ставати історією проєкту.

Перемістіть файл до індексу за допомогою git add. Цю команду легко недооцінити, оскільки звучить так, ніби ви додаєте файл до Git назавжди. Точніше кажучи, ви додаєте поточний вміст цього файлу до індексу для наступного коміту. Якщо ви знову відредагуєте файл після його додавання до індексу, нове редагування не буде проіндексоване (unstaged), доки ви не додасте і його.

Terminal window
git add namespace.yaml

Знову виконайте git status і порівняйте формулювання. Файл перемістився з «Untracked files» до «Changes to be committed». Це формулювання говорить вам, що наступний коміт включатиме файл у тому вигляді, в якому він існував на момент додавання до індексу. Нічого ще не збережено назавжди; ви лише підготували наступний знімок.

Terminal window
git status

Тепер вивід повинен показувати файл у розділі змін, готових до фіксації (changes to be committed), що означає, що він доданий до індексу (staged).

On branch main
No commits yet
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: namespace.yaml

Зафіксуйте підготовлену зміну. Повідомлення має пояснювати причину створення знімка на рівні, корисному для майбутнього рецензента. Повідомлення на кшталт «update» змушує людей переглядати diff лише для того, щоб зрозуміти намір. Повідомлення типу «feat: add production namespace definition» дає читачеві короткий підсумок і водночас дозволяє відкрити diff для детального ознайомлення за потреби.

Terminal window
git commit -m "feat: add production namespace definition"

Вивід має повідомити про кореневий коміт (root commit), тему коміту та кількість доданих рядків.

[main (root-commit) a1b2c3d] feat: add production namespace definition
1 file changed, 4 insertions(+)
create mode 100644 namespace.yaml

Перевірте стан після коміту. Чисте робоче дерево (clean working tree) означає, що відстежувані файли у вашому робочому каталозі збігаються з останнім зафіксованим знімком, і немає нічого підготовленого для наступного коміту. Чисте дерево не означає, що проєкт правильний, безпечний чи готовий до продакшену. Це лише означає, що Git не має невідстежуваних змін для звітування.

Terminal window
git status

Тепер вивід повинен повідомляти про чисте робоче дерево, оскільки підготовлений вміст було зафіксовано.

On branch main
nothing to commit, working tree clean

Сценарій вправи: під час локального тестування учень поміщає справжній токен доступу у файл YAML, бачить, що застосунок запускається, а потім виконує загальну команду додавання до індексу, не читаючи diff. Операційний урок тут прямий: коміт — це не приватна чернетка після того, як ним поділилися, і видалення секрету в пізнішому коміті не видаляє його з попередньої історії. Завжди перевіряйте стан і diff перед тим, як робити коміт, особливо коли йдеться про конфігураційні файли, які можуть містити облікові дані.

Більш безпечна професійна звичка полягає в тому, щоб кожен коміт заслуговував на своє місце в історії. Перед додаванням до індексу запитайте себе, чи має цей патч одну причину, яку зможе оцінити рецензент. Перед створенням коміту переконайтеся, що підготовлений вміст — це саме той вміст, який ви хочете прикріпити до повідомлення. Перед виконанням push перевірте, чи містить гілка лише ту роботу, якою ви готові поділитися. Ці питання затримують вас на лічені секунди, але можуть заощадити години на очищення, коли репозиторій стає вхідними даними для автоматизації розгортання.

Тепер змініть простір імен, додавши мітку (label). Це реалістичний вид редагування інфраструктури, оскільки мітки допомагають командам організовувати об’єкти, вибирати ресурси та керувати автоматизацією. Однак робочий процес Git залишається незмінним: внести зміну, перевірити різницю, додати до індексу лише потрібний вміст і зафіксувати цілеспрямований знімок.

Terminal window
cat << 'EOF' > namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: webapp-prod
labels:
environment: production
EOF

Перед тим як додати зміну до індексу, прочитайте diff. git diff порівнює робочий каталог з останнім зафіксованим знімком для змін, які не були додані до індексу. Це одна з найбільш захисних команд у вашому інструментарії, оскільки вона показує точні рядки, які здивували б рецензента, якби ви зробили коміт без перевірки. Вона також привчає вас мислити патчами, які є одиницею перевірки в більшості професійних робочих процесів Git.

Terminal window
git diff

Вивід має показати лише нові рядки міток як додані, з навколишнім незміненим YAML для контексту.

diff --git a/namespace.yaml b/namespace.yaml
index e46b825..8394c41 100644
--- a/namespace.yaml
+++ b/namespace.yaml
@@ -2,3 +2,5 @@ apiVersion: v1
kind: Namespace
metadata:
name: webapp-prod
+ labels:
+ environment: production

Вивід diff має компактну граматику. Рядки --- та +++ називають стару та нову сторони порівняння. Заголовок фрагмента (chunk header), що починається з @@, повідомляє Git і читачеві, де саме у файлі з’являється зміна. Рядки, що починаються з пробілу, є контекстом, рядки, що починаються з +, є додаваннями, а рядки, що починаються з -, є видаленнями. Змінений рядок представлений як одне видалення та одне додавання, саме тому порядкова перевірка є більш точною, ніж «я змінив файл».

Коли ви переглядаєте diff для інфраструктурних файлів, читайте його як план розгортання, а не як перевірку орфографії. Зміна тегу образу (image) в одному рядку може перевести робочі навантаження (workloads) на інший бінарний файл. Зміна кількості реплік може вплинути на вартість, доступність і навантаження на залежності. Зміна простору імен або мітки може вплинути на автоматизацію, яка вибирає об’єкти за метаданими. Формат diff у Git простий, але операційна інтерпретація цих рядків вимагає уваги до того, чим керують змінені поля.

Зупиніться та подумайте: уявіть, що наступний diff з’являється у файлі Deployment. Перш ніж читати відповідь, вирішіть, чи це нове поле, видалене поле чи змінене значення, і опишіть операційний ефект простою мовою.

@@ -10,3 +10,3 @@
spec:
replicas: 3
- image: nginx:1.14
+ image: nginx:1.24

Інженер змінив наявне значення образу з nginx:1.14 на nginx:1.24. Це не просто оновлення форматування; воно змінює те, який контейнерний образ Kubernetes намагатиметься запустити. Під час реальної перевірки ви б запитали, чи є цей стрибок версії навмисним, чи існує такий тег, і чи був застосунок протестований на цій версії.

Після підтвердження того, що зміна мітки є саме тою, яку ви хотіли внести, додайте її до індексу та зафіксуйте. Зверніть увагу, що повідомлення коміту стосується безпосередньо мітки. У ньому не написано «fix stuff» або «update namespace», оскільки такі повідомлення швидко втрачають цінність, коли хтось сканує історію під час інциденту. Повідомлення коміту — це крихітна частина операційної документації, прикріплена до точного патчу, який вона описує.

Terminal window
git add namespace.yaml
git commit -m "chore: add environment label to namespace"

Перевіряйте історію та діагностуйте стан

Розділ «Перевіряйте історію та діагностуйте стан»

Коли репозиторій має більше одного коміту, історія стає інструментом для діагностики. git log показує хронологію знімків, за замовчуванням найновіші спочатку, включаючи ідентифікатори комітів, інформацію про автора, дати та повідомлення. Під час усунення несправностей це дозволяє відповісти на питання, хто щось нещодавно змінював і яке пояснення залишив. Під час перевірки коду це дає змогу оцінити, чи формує історія гілки зв’язну розповідь.

Історія найбільш корисна, коли коміти достатньо малі для перевірки, а повідомлення достатньо конкретні для пошуку. Якщо гілка містить один гігантський коміт, який одночасно змінює простори імен, розгортання (deployments), скрипти та документацію, його скасування або перегляд стає ризикованим, оскільки всі проблеми переплетені. Якщо гілка містить вузькоспрямовані коміти, ви можете перевірити зміну розгортання окремо від зміни документації. Git не змушує дотримуватися цієї дисципліни, але він винагороджує за неї щоразу, коли вам потрібно розмірковувати під тиском.

Terminal window
git log

Вивід має показувати найновіший коміт першим, а за ним — попередній кореневий коміт.

commit 9f8e7d6c5b4a39281716151413121110abcdef12 (HEAD -> main)
Author: Your Name <you@example.com>
Date: Wed Oct 12 10:45:12 2023 -0400
chore: add environment label to namespace
commit a1b2c3d4e5f60718293a4b5c6d7e8f9012345678
Author: Your Name <you@example.com>
Date: Wed Oct 12 10:15:30 2023 -0400
feat: add production namespace definition

Довгі шістнадцяткові рядки — це ідентифікатори комітів. У багатьох репозиторіях вони є іменами об’єктів SHA-1, які зазвичай відображаються як довгі хеші та скорочуються в інтерфейсах користувача, коли короткий префікс є однозначним. Вам не потрібно самостійно обчислювати хеш, але ви повинні розпізнавати його як точний вказівник на знімок. Сказати «коміт з міткою простору імен» корисно в розмові; використання ідентифікатора коміту — це те, як інструменти перевіряють або порівнюють точний коміт.

Для щоденного використання компактний формат журналу легше сканувати очима. Опція --oneline показує скорочені ідентифікатори комітів та їхні теми по одному на рядок. Цього часто достатньо, коли ви хочете перевірити, чи існують очікувані коміти в очікуваному порядку, перш ніж відправляти гілку (push) або просити когось про перевірку.

Terminal window
git log --oneline

Компактний вивід повинен зберігати той самий порядок, скорочуючи кожен коміт до короткого ідентифікатора та теми.

9f8e7d6 chore: add environment label to namespace
a1b2c3d feat: add production namespace definition

Ви також можете використовувати git log -p для перевірки патчу, доданого кожним комітом. Це корисно, коли виникає запитання не лише «Коли це змінилося?», але й «Які саме рядки додав чи видалив цей коміт?». У міру зростання репозиторіїв ви вивчатимете більш цілеспрямовані інструменти для роботи з історією, але status, diff та log вже дають вам міцний цикл діагностики: поточний стан, не збережені зміни в рядках та зафіксована хронологія.

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

Найважливіша звичка — читати ці команди як набір. Якщо git status каже, що файл змінено, git diff пояснює цю не проіндексовану зміну. Якщо робоче дерево чисте, але поведінка нещодавно змінилася, git log підкаже, які коміти варто перевірити. Якщо файл не відстежується, ніяка кількість git commit не включить його, доки ви не додасте його до індексу. Інструмент є послідовним; плутанина зазвичай виникає через те, що правильне питання ставлять не тому дереву.

Перш ніж запустити це у своєму власному навчальному репозиторії, який вивід від git status ви очікуєте побачити після другого коміту? Якщо ви нічого не редагували з моменту коміту, команда повинна повідомити про чисте робоче дерево. Якщо цього не сталося, зупиніться та перевірте залишені зміни, замість того щоб одразу робити ще один коміт, оскільки ця невідповідність говорить про те, що ще є стан, який ви не врахували.

Робота з віддаленими репозиторіями без втрати контролю

Розділ «Робота з віддаленими репозиторіями без втрати контролю»

До цього моменту все відбувалося на вашій локальній машині. Цього достатньо для практики з Git, але недостатньо для командної роботи або резервного копіювання. Віддалений репозиторій (remote) — це ще один репозиторій, доступний через мережу, який зазвичай розміщується на сервісах на кшталт GitHub, GitLab або Bitbucket. Оскільки Git є розподіленим, віддалений репозиторій не є чимось магічним; це ще одна копія історії репозиторію, з якої ваш локальний репозиторій може завантажувати зміни (fetch) та в яку може їх надсилати (push), коли їхні історії сумісні.

+-----------------------+ +-----------------------+
| | | |
| Local Repository | | Remote Repository |
| (Your Laptop) | | (GitHub/GitLab) |
| | | |
| commit C (HEAD) | ==== git push ===> | commit C |
| commit B | | commit B |
| commit A | <=== git pull ==== | commit A |
| | | |
+-----------------------+ +-----------------------+

Коли ви створюєте порожній репозиторій на хостинговій платформі, вона надає вам URL-адресу. Ви підключаєте свій локальний репозиторій до цієї URL-адреси за допомогою git remote add. За домовленістю перший і основний віддалений репозиторій називається origin, але ця назва — лише локальний псевдонім. URL-адреса вказує, куди надсилаються дані; назва віддаленого репозиторію — це те, як ви посилаєтеся на цю URL-адресу в командах.

Terminal window
# Example command (do not run unless you have a real repository URL prepared)
git remote add origin https://github.com/yourusername/k8s-webapp.git

Якщо репозиторій вже існує на сервері, не створюйте новий локальний репозиторій і не намагайтеся склеїти їхні історії докупи. Натомість скористайтеся командою git clone <url>. Клонування ініціалізує локальний каталог .git, завантажує історію репозиторію, розгортає робоче дерево файлів (working tree) і записує віддалений репозиторій як origin. Більшість професійної роботи починається саме з клонування, оскільки історія команди вже існує до вашого приходу.

Push-операція (виштовхування) завантажує ваші локальні коміти у віддалену гілку. Перше надсилання нової гілки часто включає прапорець -u, який встановлює зв’язок для відстеження (upstream tracking), щоб майбутні команди git push та git pull могли самостійно визначати віддалену гілку. Ця зручність корисна, але тільки після того, як ви зрозумієте, що саме відстежується. Якщо зв’язок гілок неправильний, Git може надіслати дані кудись не туди або попросити вас бути точнішими.

Terminal window
# Push your main branch to the origin remote for the first time
git push -u origin main

Pull-операція (стягування) завантажує віддалені коміти та інтегрує їх у вашу поточну гілку. Концептуально git pull — це git fetch, за яким слідує крок інтеграції, наприклад, merge (злиття) або rebase (перебазування), залежно від конфігурації. Початківці можуть сприймати це як “перенести віддалену гілку в мою локальну”, але варто пам’ятати про цю двоскладову природу, оскільки використання лише git fetch є безпечнішим, коли ви хочете просто перевірити віддалені зміни перед модифікацією своєї робочої гілки.

Terminal window
# Fetch changes from the remote and merge them into your local branch
git pull origin main

Зупиніться та подумайте: ви зробили два локальні коміти в офлайні, а колега надіслав три коміти в ту ж саму віддалену гілку до того, як ви відновили з’єднання. Що станеться, якщо ви відразу спробуєте виконати git push origin main? Найімовірнішим результатом буде відхилення (rejected push), оскільки віддалений репозиторій містить коміти, яких ще немає у вашій локальній гілці. Git відмовляється дозволити вашому push-запиту випадково перезаписати віддалену часову шкалу, тому ви повинні виконати fetch або pull, оглянути об’єднану історію, вирішити конфлікти, якщо це необхідно, і лише потім виконати push.

Цей захист є однією з причин, чому Git є безпечнішим за просте копіювання файлів через спільну папку, але він не замінює спілкування. Якщо двоє людей редагують один і той самий рядок в одному файлі, Git може виявити конфлікт, але він не може визначити правильний бізнес- або операційний результат. У маніфестах Kubernetes це може означати вибір правильної кількості реплік, тегу образу, namespace або обмеження ресурсів. Рішення людини все ще має значення; Git просто запобігає тихому перезаписуванню даних.

Існує також різниця між синхронізацією з віддаленим репозиторієм та розгортанням (deployment). Надсилання маніфесту до репозиторію робить код доступним для команди і може запустити автоматизацію, якщо в проєкті налаштовано CI/CD, але сам по собі Git не є Kubernetes і не застосовує ресурси до кластеру. Ця межа є важливою. Чиста історія Git робить автоматизацію розгортання придатною для аудиту, проте вам усе ще потрібні окремі перевірки, рев’ю та зворотний зв’язок від кластера, щоб знати, чи є зміна інфраструктури безпечною.

Ігнорування шуму та захист секретів

Розділ «Ігнорування шуму та захист секретів»

Реальні проєкти генерують файли, яким не місце в системі контролю версій. Каталоги збірки, логи, локальні файли кешу, метадані операційної системи, файли підкачки редакторів (swap), завантажені залежності, стан Terraform та файли з приватним середовищем — усе це може з’явитися поруч із вихідними файлами. Якщо ці файли потраплять в історію Git, вони завдадуть різної шкоди: великі бінарні файли роздують репозиторій, згенеровані файли спричинять шум під час рев’ю, а секрети призведуть до негайних інцидентів безпеки.

Git справляється з цим за допомогою .gitignore — простого текстового файлу, який зазвичай зберігається в корені репозиторію. Кожен рядок є шаблоном для файлів, які Git повинен ігнорувати, коли вони не відстежуються (untracked). Частина “коли вони не відстежуються” є критично важливою. .gitignore запобігає тому, щоб нові файли, які відповідають шаблону, розглядалися як кандидати на додавання в індекс (staging), але він не змушує Git забути про файл, який вже відстежується в історії. Якщо секрет був закомічений, ви повинні ставитися до нього як до скомпрометованого і провести його ротацію, а не просто додати його в .gitignore.

Створіть файл ігнорування для вашого тренувального репозиторію. Наведені нижче шаблони навмисно короткі, щоб ви могли легко їх проаналізувати. Вони демонструють шум від операційної системи, локальні секрети, локальний файл у стилі kubeconfig та стан Terraform. У продакшен-репозиторії ви б адаптували шаблони до інструментів, які фактично використовуються в проєкті, і переглядали б їх так само ретельно, як і будь-яку іншу інфраструктурну політику.

Terminal window
cat << 'EOF' > .gitignore
# Ignore operating system generated files
.DS_Store
Thumbs.db
# Ignore local secret and credential files
.env
secret-keys.yaml
kubeconfig-local
# Ignore terraform state files (if we add Infrastructure as Code later)
*.tfstate
*.tfstate.backup
.terraform/
EOF

Git читає шаблони ігнорування і зазвичай приховує відповідні невідстежувані файли від виводу команди git status. Це зменшує ймовірність того, що масова команда додавання в індекс захопить файли, призначені лише для локального використання. Це не усуває необхідності читати вивід git status та git diff, оскільки файли ігнорування можуть бути неповними, а файли, що відстежуються, залишатимуться такими, навіть якщо їхні імена згодом почнуть відповідати правилу ігнорування.

Зупиніться та подумайте: з наведеним вище файлом ігнорування, який із цих нових файлів усе ще відображатиметься як невідстежуваний: main.tfstate, secret-keys.yaml чи secret-keys.txt? Лише secret-keys.txt має з’явитися, оскільки main.tfstate відповідає підстановочному знаку *.tfstate, а secret-keys.yaml збігається з точним шаблоном. Файл із розширенням .txt не відповідає жодному з перелічених шаблонів, тому Git усе одно повідомляє про нього.

Тепер розглянемо ситуацію із запізнілим правилом ігнорування. Минулого тижня ви закомітили файл database-creds.txt, а сьогодні додаєте його ім’я до .gitignore і редагуєте сам файл. Git усе одно повідомить про його модифікацію, оскільки файл уже відстежується. Щоб припинити відстеження файлу, зберігши при цьому його локальну копію, вам знадобиться команда на кшталт git rm --cached database-creds.txt, за якою слідує commit, і вам усе одно доведеться провести ротацію будь-яких облікових даних, які коли-небудь були закомічені.

Ось чому надійний робочий процес у Git є як технічним, так і поведінковим. Технічні засоби контролю — це .gitignore, git status, git diff та сканування секретів на стороні сервера. Поведінка ж є повільнішою та більш обдуманою: не додавайте файли в індекс наосліп, не зберігайте реальні облікові дані в навчальних маніфестах і не припускайте, що пізніший коміт з очищенням зітре факт їх розкриття. Історія Git корисна тим, що вона все пам’ятає, і саме ця властивість робить витік секретів незворотним у часі.

Для проєктів Kubernetes та хмарних сервісів корисна політика .gitignore зазвичай з’являється до першого серйозного коміту. Локальні файли kubeconfig, згенеровані маніфести, тимчасові логи, робочі каталоги Terraform та кеші завантажених інструментів можуть накопичуватися дуже швидко. Деякі з цих файлів є нешкідливим шумом, тоді як інші можуть містити облікові дані або стан, специфічний для середовища. Їх раннє ігнорування дозволяє зосередити увагу під час рев’ю виключно на вихідних файлах і зменшує ймовірність того, що специфіка локальної робочої станції стане частиною постійної історії команди.

Патерни та антипатерни

Розділ «Патерни та антипатерни»

Патерни Git є корисними, коли вони роблять історію легшою для рев’ю та безпечнішою для автоматизації. Спільною рисою є усвідомленість: усвідомлено додавайте файли до індексу, робіть коміт однієї логічної зміни за раз і тримайте згенеровані або чутливі файли поза репозиторієм. Антипатерни, наведені нижче, зазвичай виникають через поспіх, але згодом вони призводять до повільнішого відновлення, оскільки історія перестає давати відповіді на операційні запитання.

Патерн або антипатернКоли з’являєтьсяЧому це важливоКраща звичка
Патерн: огляд перед додаванням до індексуБудь-яка зміна в коді, YAML, скриптах або документаціїВи перехоплюєте випадкові редагування, відлагоджувальний вивід та секрети до того, як вони потраплять в історію.Запустіть git status, потім git diff, і лише після цього додавайте конкретні файли до індексу.
Патерн: сфокусовані комітиЗавдання зачіпає кілька файлів з різних причинРецензенти можуть зрозуміти і відкотити одну логічну зміну, не тягнучи за собою непов’язану роботу.Закомітьте зміну namespace окремо від редагувань README або локальних експериментів.
Патерн: .gitignore у корені репозиторіюПроєкт має згенеровані файли, логи, файли стану або локальні облікові даніСпільна політика ігнорування запобігає появі типового локального шуму в кожного контриб’ютора.Переглядайте шаблони ігнорування з такою ж ретельністю, як і конфігурацію збірки чи розгортання.
Антипатерн: масове додавання в індекс на автоматіУчень вводить git add . після кожного редагуванняGit може додати файли, про існування яких учень забув, включаючи згенеровані файли або локальну конфігурацію.Спочатку використовуйте конкретні імена файлів; використовуйте масове додавання лише після уважного читання status та diff.
Антипатерн: розмиті повідомлення комітівГілка містить повідомлення на кшталт “update” або “fix”Розслідування інцидентів уповільнюється, оскільки історія більше не пояснює намірів.Напишіть коротку тему, яка називає операційну причину створення цього знімка (snapshot).
Антипатерн: ставлення до pull як до безпечної операціїЛокальна гілка має незакомічену роботу, а віддалена просунулася впередPull може створити конфлікти або коміти злиття (merge commits) до того, як учень розбереться з локальним станом.Почніть із git status; свідомо виконайте коміт, збережіть у stash або відкиньте локальну роботу перед інтеграцією віддаленої історії.

Фреймворк прийняття рішень

Розділ «Фреймворк прийняття рішень»

Коли робота з Git здається заплутаною, вибирайте наступну команду на основі стану, який вам потрібно перевірити або змінити, а не на основі завченої послідовності. Один і той самий репозиторій може потребувати різних команд залежно від того, чи полягає проблема в невідстежуваних файлах, незбережених редагуваннях, змінах в індексі, відсутніх віддалених комітах або гілці, яка ще жодного разу не була надіслана. Ця таблиця містить шлях прийняття рішень для початківців, який є достатньо консервативним для інфраструктурної роботи.

СитуаціяБільш безпечне перше запитанняКоманда для початкуЩо робити далі
Ви відредагували файли і хочете знати, що бачить GitЯке дерево (tree) містить зміну?git statusПрочитайте, чи є файли невідстежуваними, зміненими чи вже в індексі.
Ви хочете переглянути точні зміни в рядкахЩо б здивувало рецензента?git diffДодайте до індексу лише потрібні файли після прочитання патчу.
Ви вже додали зміни в індекс, але хочете перевірити їхній вмістЩо міститься в наступному знімку (snapshot)?git diff --stagedЗробіть коміт, якщо все правильно, або приберіть з індексу та виправте.
Ви хочете створити локальну точку збереженняЧи має додана зміна одну логічну причину?git commit -m "повідомлення"Напишіть повідомлення, яке пояснює намір, а не лише механіку дії.
Вам потрібна робота з віддаленого репозиторіюЧи є в моїй локальній гілці незакомічена робота?git status, потім git pullВиконуйте pull лише тоді, коли локальний стан зрозумілий і готовий до цього.
Вам потрібно поділитися локальними комітамиЧи є у віддаленому репозиторії робота, якої в мене немає?git push або явна git push -u origin mainЯкщо запит відхилено, виконайте fetch або pull, інтегруйте та надішліть знову.

Використовуйте git init, коли ви створюєте абсолютно новий локальний репозиторій у каталозі, який ще не має історії. Використовуйте git clone, коли проєкт уже існує десь в іншому місці і ви хочете, щоб ваша локальна копія поділяла цю наявну історію. Використовуйте .gitignore до того, як накопичаться локальні файли, особливо коли проєкт стосується облікових даних або згенерованих артефактів. Використовуйте git log, коли змінилася поведінка і вам потрібна хронологія, а не тоді, коли ви намагаєтеся перевірити незакомічені зміни.

Цей фреймворк також допоможе вам уникнути деструктивних команд на початку вашого шляху в Git. Існують команди, які переписують історію, відкидають зміни або видаляють файли з індексу, і ви вивчите деякі з них пізніше. На цьому етапі віддавайте перевагу командам спостереження. Чиста діагностика за допомогою status, diff та log робить команди відновлення безпечнішими, оскільки ви точно знаєте, який саме стан намагаєтеся змінити.

  1. Git був створений у 2005 році під величезним тиском. Проєкт ядра Linux втратив безкоштовний доступ до BitKeeper, що підштовхнуло Лінуса Торвальдса та контриб’юторів швидко створити заміну для дуже великого розподіленого проєкту.
  2. Назва є навмисно зухвалою. Торвальдс жартував про назву “Git” на публічних виступах та в інтерв’ю, і ця назва прижилася, оскільки інструмент вирішив реальну проблему співпраці краще, ніж альтернативи, доступні спільноті розробників ядра.
  3. Git не відстежує порожні каталоги. Git відстежує вміст файлів, тому команди, яким потрібен інакше порожній каталог, зазвичай додають невеликий файл-заповнювач, наприклад .gitkeep, за домовленістю.
  4. Ідентифікатори об’єктів є частиною моделі цілісності Git. Багато репозиторіїв усе ще відображають 40-символьні імена об’єктів SHA-1, тоді як сучасний Git також підтримує репозиторії SHA-256 для більшої стійкості до колізій у довгостроковій перспективі.
ПомилкаЧому це трапляєтьсяЯк це виправити
Випадковий коміт пароля або секретуСтудент масово додає файли до індексу, не читаючи git status та git diff, тому локальний файл .env або файл з обліковими даними потрапляє до коміту.Якщо його було відправлено (pushed), негайно замініть облікові дані та дотримуйтесь процесу видалення секретів у репозиторії. Якщо він залишився лише локально, видаліть його з історії перед поширенням та додайте правило ігнорування.
Повідомлення “fatal: refusing to merge unrelated histories”Репозиторій було ініціалізовано локально, тоді як хостинг-сервіс також створив свій власний перший коміт, наприклад, README.Надавайте перевагу клонуванню наявного віддаленого (remote) репозиторію. Якщо об’єднання історій дійсно є бажаним, використовуйте явну опцію unrelated-histories лише після з’ясування причин, чому історії відрізняються.
Повідомлення “updates were rejected” під час pushВіддалена гілка має коміти, яких бракує локальній гілці, часто через те, що хтось зробив push, поки ви були офлайн.Виконайте fetch або pull для отримання віддаленої роботи, вирішіть будь-які конфлікти, перевірте об’єднану історію та знову виконайте push лише після того, як локальна гілка включатиме віддалені коміти.
Написання порожніх або беззмістовних повідомлень комітівСтудент розглядає коміти як контрольні точки для себе, а не як повідомлення для майбутніх супровідників.За потреби змінюйте (amend) повідомлення невідправленого (unpushed) коміту та практикуйте пояснення операційної причини створення кожного знімка.
Забуття додавання файлів до індексу перед комітомРобоча директорія містить зміни, але область індексування (staging area) порожня під час виконання git commit.Запустіть git status, додайте потрібні файли до індексу за допомогою git add <file>, перевірте ще раз і повторіть спробу коміту.
Коміт згенерованих або бінарних артефактівРезультати збірки та журнали містяться поруч із вихідними файлами, а репозиторій ще не має політики ігнорування.Видаліть випадково відстежувані артефакти за допомогою відповідної команди Git, зафіксуйте очищення у коміті та додайте шаблони до .gitignore перед продовженням роботи.
Додавання правила ігнорування після того, як файл уже відстежуєтьсяСтудент очікує, що .gitignore перевизначить історію для вже зафіксованих у коміті файлів.Вилучіть файл з відстеження за допомогою видалення лише з індексу, наприклад git rm --cached <file>, зафіксуйте цю зміну в коміті та замініть секрети, якщо конфіденційний вміст коли-небудь потрапляв до коміту.

Контрольні запитання

Розділ «Контрольні запитання»
1. Ваша команда розгорнула конфігурацію Kubernetes, і поведінка негайно змінилася. Вам потрібно визначити останні коміти, авторів та повідомлення, перш ніж вирішувати, що перевіряти далі. Яка команда Git надає вам часову шкалу, і чому це правильна відправна точка?

Використовуйте git log або git log --oneline, коли вам потрібен компактний огляд. Журнал показує історію комітів у зворотному хронологічному порядку, тому він відповідає на запитання, хто створив останні знімки та які повідомлення вони залишили. Команда git status описує лише незафіксований локальний стан, а git diff показує лише неіндексовані зміни рядків. Під час розслідування інцидентів часова шкала звужує пошук, перш ніж ви почнете перевіряти окремі патчі.

2. Ви змінили `service.yaml` і запустили `git commit -m "expose port 8080"`, але Git повідомив, що нічого не додано до коміту. Який стан ви забули змінити, і як вам слід діяти далі?

Файл усе ще знаходився в робочій директорії і не був переміщений до області індексування (staging area). Git не включає автоматично кожен змінений файл до коміту, оскільки область індексування — це місце, де ви обираєте вміст наступного знімка. Запустіть git status, щоб підтвердити стан файлу, потім git add service.yaml, знову перевірте статус і повторіть коміт. Це зберігає усвідомлену двокрокову модель, яка утримує непов’язані зміни поза історією.

3. Ви збираєтесь додати `configMap.yaml` до індексу, але не впевнені, чи справжній пароль до бази даних усе ще присутній у відредагованих рядках. Що слід перевірити перед індексуванням, і яке рішення має бути прийнято після цього?

Запустіть git diff перед індексуванням, щоб ви могли перевірити точні зміни неіндексованих рядків. Якщо diff містить справжній пароль, не додавайте його до індексу і не комітьте; видаліть секрет, замініть його безпечним заповнювачем або зовнішнім посиланням і знову перевірте diff. Команда git log не допоможе, оскільки ризикований вміст ще не зафіксовано в коміті. Найбезпечніше рішення — зробити патч чистим до того, як він потрапить до області індексування.

4. Ви клонували репозиторій, і Git просить вас налаштувати `user.name` та `user.email` перед комітом. Пізніше `git push` запитує віддалені облікові дані. Чому ці два запити відрізняються?

user.name та user.email — це локальні метадані коміту, які ідентифікують автора, записаного всередині нових комітів. Віддалені облікові дані доводять хостинг-сервісу, що вам дозволено завантажувати коміти до цього репозиторію. Перше налаштування впливає на атрибуцію збереженого знімка, тоді як друге контролює доступ до мережі. Плутання їх призводить до того, що студенти вважають, ніби успішний локальний коміт означає, що віддалений репозиторій також прийме push, що не гарантується.

5. Ви створили `aws-credentials.json` для локального тесту і ніколи не хочете його комітити. Що ви повинні зробити перед індексуванням іншої роботи, і про яке обмеження ви маєте пам'ятати?

Додайте aws-credentials.json до файлу .gitignore репозиторію перед масовим індексуванням, а потім запустіть git status, щоб підтвердити, що файл більше не відображається як невідстежуваний кандидат. Обмеження полягає в тому, що .gitignore застосовується лише до невідстежуваних файлів. Якщо файл уже був зафіксований у коміті, Git продовжуватиме відстежувати його, доки ви явно не видалите його з індексу, і будь-який справжній секрет всередині слід вважати розкритим. Більш безпечний робочий процес полягає в запобіганні відстеженню до того, як файл коли-небудь потрапить до коміту.

6. Студент видаляє приховану директорію `.git`, щоб "скинути" зламаний проєкт, а потім запускає `git status`. Що відбувається, і чому це не є безпечним методом відновлення?

Git повідомляє, що директорія не є репозиторієм Git, оскільки директорія .git містила базу даних репозиторію, гілки, посилання та локальну історію. Її видалення не створює чистої історії Git; це знищує локальні метадані репозиторію, залишаючи при цьому звичайні робочі файли. Більш безпечне відновлення починається з команд спостереження та чіткої мети, наприклад, зняття файлу з індексу (unstage) або скасування коміту (revert). Видалення .git не слід розглядати як звичайний крок для усунення несправностей.

7. Ви та ваш колега змінили один і той самий рядок `replicas` у `nginx-deployment.yaml`. Їхня зміна досягла віддаленого репозиторію першою, ваш push відхилено, і потім ви виконуєте pull. Чого слід очікувати і як ви це вирішуєте?

Git може зупинитися через конфлікт злиття (merge conflict), оскільки дві історії змінили один і той самий рядок по-різному, і він не може знати, яка кількість реплік є операційно правильною. Відкрийте файл, прочитайте маркери конфлікту, виберіть або об’єднайте потрібне значення та видаліть маркери. Потім додайте вирішений файл до індексу та завершіть коміт злиття (merge commit) перед виконанням push. Важливим моментом є те, що Git виявляє небезпечне перекриття, але людина все одно залишається відповідальною за інфраструктурне рішення.

У цій вправі ви створите локальний репозиторій з нуля, зімітуєте стандартний інженерний робочий процес, зробивши кілька логічних комітів, і проаналізуєте отриману історію. Файли є невеликими прикладами в стилі Kubernetes, щоб ви могли зосередитися на змінах стану Git, а не на поведінці кластера. Працюйте в тимчасовій директорії, читайте вивід git status після кожного вагомого кроку і ніде не використовуйте справжні облікові дані у файлах для практики.

Завдання 1: Ініціалізація

Розділ «Завдання 1: Ініціалізація»

Створіть нову директорію з назвою dojo-k8s-project, перейдіть до неї та ініціалізуйте порожній репозиторій Git, щоб ви могли побачити перший звіт про статус із чистого робочого простору для практики.

  • Директорію створено, і виконано перехід до неї.
  • Репозиторій Git ініціалізовано.
Рішення: Завдання 1
Terminal window
mkdir dojo-k8s-project
cd dojo-k8s-project
git init --initial-branch=main
git status

Завдання 2: Перший коміт

Розділ «Завдання 2: Перший коміт»

Створіть файл README.md з текстом ”# KubeDojo Project”. Додайте файл до індексу та зафіксуйте його в коміті з повідомленням “docs: add initial readme”. Це завдання перевіряє, чи можете ви провести новий файл через робочу директорію, область індексування та історію репозиторію без пропуску перевірок стану.

  • Файл створено з правильним вмістом.
  • Файл додано до області індексування.
  • Коміт успішно створено.
Рішення: Завдання 2
Terminal window
echo "# KubeDojo Project" > README.md
git status
git add README.md
git status
git commit -m "docs: add initial readme"

Завдання 3: Імітація розробки інфраструктури

Розділ «Завдання 3: Імітація розробки інфраструктури»

Створіть файл з назвою deployment.yaml і додайте наступний тестовий вміст, щоб у репозиторії був інфраструктурний файл для відстеження:

apiVersion: apps/v1
kind: Deployment
metadata:
name: web

Додайте цей файл до індексу та зафіксуйте його в коміті з повідомленням “feat: add web deployment skeleton” після того, як переконаєтеся, що Git повідомляє про файл як невідстежуваний.

  • Файл створено.
  • Коміт успішно створено з правильним повідомленням.
Рішення: Завдання 3
Terminal window
cat << 'EOF' > deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
EOF
git status
git add deployment.yaml
git commit -m "feat: add web deployment skeleton"

Завдання 4: Зміна наявних файлів

Розділ «Завдання 4: Зміна наявних файлів»

Відкрийте deployment.yaml і додайте replicas: 3 під блоком spec:, а потім перевірте отриману зміну рядка, перш ніж додавати її до індексу:

apiVersion: apps/v1
kind: Deployment
metadata:
name: web
spec:
replicas: 3

Використовуйте команду для перегляду точних відмінностей перед індексуванням. Потім додайте зміну до індексу і зафіксуйте її в коміті з повідомленням “fix: set deployment replicas to 3”.

  • Файл змінено.
  • Відмінності (diff) успішно переглянуто.
  • Зміну додано до індексу та зафіксовано в коміті.
Рішення: Завдання 4
Terminal window
# Modify the file using your preferred editor (nano, vim, or cat override)
cat << 'EOF' > deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
spec:
replicas: 3
EOF
# View the diff
git diff
# Stage and commit
git add deployment.yaml
git commit -m "fix: set deployment replicas to 3"

Завдання 5: Огляд часової шкали

Розділ «Завдання 5: Огляд часової шкали»

Виконайте команду для перегляду повної історії комітів у компактному однорядковому форматі. Переконайтеся, що всі три ваші коміти присутні, причому найновіший іде першим (за замовчуванням для git log --oneline). Якщо якийсь коміт відсутній, використовуйте git status, щоб визначити, чи зміна все ще не індексована, чи додана до індексу, чи ніколи не була створена.

  • Команду історії виконано.
  • У виводі видно три окремі коміти.
Рішення: Завдання 5
Terminal window
git log --oneline

Вивід має виглядати приблизно так:

3b2a1c4 fix: set deployment replicas to 3
9f8e7d6 feat: add web deployment skeleton
1a2b3c4 docs: add initial readme

Завдання 6: Бонусний виклик — Розширені правила ігнорування

Розділ «Завдання 6: Бонусний виклик — Розширені правила ігнорування»

Ви працюєте над новим застосунком, який генерує численні файли журналів із закінченням .log у різних директоріях. Ви хочете, щоб Git ігнорував їх усі задля економії місця, але ви повинні гарантувати, що один конкретний файл з назвою audit-trail.log у кореневій директорії завжди відстежується з міркувань відповідності вимогам (compliance). Створіть файл .gitignore, який досягає саме такої конфігурації, а потім перевірте результат за допомогою тестових файлів і git status.

  • Файл .gitignore створено з відповідними символами підстановки (wildcards) та правилами виключення.
  • Тестові файли створено для перевірки правил.
  • git status підтверджує, що лише необхідний файл є невідстежуваним.
Рішення: Завдання 6
Terminal window
# Create the .gitignore file
cat << 'EOF' > .gitignore
*.log
!audit-trail.log
EOF
# Create dummy files
touch app.log
touch database.log
touch audit-trail.log
# Check status
git status

Git покаже .gitignore та audit-trail.log як невідстежувані файли. Інші файли .log будуть успішно проігноровані.

  • Ви можете пояснити різницю між робочою директорією, областю індексування та історією репозиторію, використовуючи власні файли для практики.
  • Ви створили щонайменше три цілеспрямовані коміти зі змістовними повідомленнями.
  • Ви перевірили відмінності (diff) перед додаванням до індексу зміни в YAML у стилі Kubernetes.
  • Ви використали git log --oneline для перевірки отриманої історії.
  • Ви створили та протестували правило .gitignore, яке ігнорує широкий шаблон, але дозволяє один виняток.

Модуль 0.7: Що таке мережі? — Тепер, коли ви вмієте відстежувати файли, настав час зрозуміти, як комп’ютери спілкуються один з одним через мережі.