Середнього розміру фінтех-компанія зберігала файли конфігурації своєї інфраструктури на спільному мережевому диску. Інженери підключали цей диск, відкривали файли у локальних редакторах, вносили зміни та зберігали їх назад у мережу. Одного п’ятничного дня молодшому інженеру доручили оновити тестове середовище. Помилково він відкрив файл payment-processor-deployment.yaml для продуктового середовища замість тестового варіанту. Він змінив тег образу контейнера на експериментальну збірку, зберіг файл і застосував конфігурацію до кластера.
Протягом декількох хвилин система обробки платежів почала втрачати транзакції. Коли старші інженери поспішили розібратися, вони подивилися на файл конфігурації на мережевому диску, але він показував лише поточний, зламаний стан. Оскільки системи контролю версій не було, не існувало історичного запису того, як файл виглядав десять хвилин тому, хто його змінив або чому. Команді довелося вручну відновлювати конфігурацію для продакшну з пам’яті та застарілої документації. Затримка у відновленні сервісу зупинила всі транзакції клієнтів на шість годин, що призвело до мільйонних збитків і серйозної шкоди репутації.
Контроль версій запобігає саме таким сценаріям. Git, галузевий стандарт контролю версій, діє як незнищенна машина часу для вашого коду та конфігурацій. Він фіксує кожну зміну, ідентифікує, хто саме її зробив, і дозволяє миттєво повернутися до будь-якого попереднього стану. У сучасному хмарному світі інфраструктура визначається як код. Якщо ви не можете з абсолютною впевненістю відстежувати, переглядати та скасовувати код вашої інфраструктури, ви працюєте в очікуванні катастрофи. Оволодіння Git не є опціональним для Platform Engineer; це фундаментальна навичка, на якій базується вся надійна автоматизація та співпраця.
Без Git сучасні конвеєри безперервної інтеграції та розгортання (CI/CD) не можуть існувати. Вся концепція автоматизованих розгортань покладається на єдине, довірене джерело істини, яке запускає автоматизацію щоразу, коли виявляється нова, схвалена зміна. Якщо ви не розумієте Git, ви не зможете зрозуміти сучасну доставку програмного забезпечення.
Секція 1: Концепція контролю версій та архітектура Git
Перш ніж вводити будь-які команди, ви повинні зрозуміти, як Git сприймає ваші файли. Багато новачків мають труднощі з Git, тому що ставляться до нього як до простого інструменту резервного копіювання (як Dropbox або Google Drive). Git зовсім інший. Git не просто безперервно синхронізує файли у фоновому режимі; він робить навмисні, незмінні знімки (snapshots) вашого проєкту в конкретні моменти часу, але тільки тоді, коли ви явно даєте йому таку команду.
Уявіть собі Git як відеогру з ручними точками збереження. Ви можете грати в гру, припускатися помилок, отримувати пошкодження та досліджувати глухі кути. Доки ви явно створюєте “точку збереження” перед небезпечним боєм із босом, ви завжди можете перезавантажити той самий стан, якщо щось піде не так. Git працює так само, але для ваших текстових файлів.
Централізований проти розподіленого контролю версій
Історично системи контролю версій, такі як Subversion (SVN) або Team Foundation Server (TFS), були централізованими. Існував один головний сервер, який зберігав історію. Якщо ви хотіли переглянути історію або зробити коміт, ви повинні були бути підключені до інтернету, щоб зв’язатися з цим сервером. Якщо сервер виходив з ладу, ніхто не міг працювати.
Git — це розподілена система контролю версій. Коли ви використовуєте Git, ви не просто завантажуєте останні файли; ви завантажуєте всю історію проєкту. Ваш локальний ноутбук стає повноцінним репозиторієм. Ви можете переглядати історію, порівнювати версії та робити коміти, перебуваючи повністю офлайн у літаку. Інтернет потрібен лише тоді, коли ви хочете синхронізувати свою історію з чиєюсь іншою.
Git керує вашими файлами, переміщуючи їх через три окремі логічні області, які часто називають “деревами”. Розуміння цього конвеєра є ключем до діагностики майже будь-якої проблеми в Git.
Робоча директорія (Working Directory): Це ваш поточний робочий простір на комп’ютері. Вона містить реальні файли, які ви редагуєте, видаляєте або створюєте. Коли ви відкриваєте файл у Vim або VS Code, ви модифікуєте робочу директорію. Git бачить ці зміни, але ще не зберіг їх.
Область індексації (Staging Area / Index): Це важливий проміжний крок, унікальний для Git. Уявіть це як вантажну платформу або майданчик для підготовки до фотосесії. Перш ніж зробити фінальний знімок, ви обираєте, які саме змінені файли розмістити на сцені. Ви можете індексувати одні файли, залишаючи інші. Це дозволяє створювати дуже сфокусовані, логічні коміти, навіть якщо ви змінили п’ятдесят файлів одночасно.
Репозиторій (Repository / Commit History): Це постійна база даних, де Git зберігає ваші знімки (які називаються комітами). Після того, як файли закомічені сюди, вони надійно записані в історії з іменем автора, міткою часу та описовим повідомленням. Коміт математично запечатаний; його не можна таємно змінити, не змінивши його унікальний ідентифікатор.
Зупиніться та подумайте: Ви щойно завершили довгу сесію налагодження. Ви виправили баг підключення до бази даних у db.py, але під час пошуку багу ви також додали тимчасові інструкції виводу (print) у файли auth.py та api.py, які ви не хочете зберігати назавжди. Як архітектура Трьох дерев Git дозволяє вам створити чисту історію в цьому сценарії, не втрачаючи ваш тимчасовий код налагодження в робочій директорії?
Перевірка передбачення: Архітектура Трьох дерев відокремлює ваші робочі файли від того, що зберігається. Ви можете використовувати Область індексації, щоб вибірково додати лише db.py для наступного коміту. Тимчасові інструкції виводу в auth.py та api.py залишаться в безпеці у вашій Робочій директорії, щоб ви могли продовжувати їх використовувати або видалити пізніше, ніколи не забруднюючи постійну історію Репозиторію.
Секція 2: Підготовка сцени: Встановлення та налаштування
Git за своєю суттю є інструментом командного рядка. Хоча існують графічні інтерфейси, вивчення термінальних команд є обов’язковим для Platform Engineering, оскільки ви часто будете використовувати Git на віддалених серверах без графічних можливостей. Більшість сучасних дистрибутивів Linux та macOS постачаються з попередньо встановленим Git, або його можна легко додати за допомогою стандартного менеджера пакетів, такого як apt, yum або brew.
Щоб перевірити встановлення, відкрийте термінал і перевірте версію:
Оскільки Git розроблений для співпраці потенційно тисяч розробників, він відмовляється створювати знімки, доки не дізнається точно, хто їх робить. Кожен коміт потребує імені автора та адреси електронної пошти. Це критично важливо для підзвітності — якщо зміна інфраструктури виведе з ладу продакшн, команді потрібно знати, кого запитати про обґрунтування цієї зміни.
Ви налаштовуєте це за допомогою команди git config. Прапор --global застосовує ці налаштування до всіх репозиторіїв на вашому поточному комп’ютері, записуючи їх у прихований файл у вашій домашній директорії (~/.gitconfig).
Terminal window
# Встановіть своє ім'я (використовуйте справжнє ім'я, воно з'являється в історії)
Щоб наказати Git почати відстеження проєкту, ви повинні ініціалізувати репозиторій у кореневій директорії вашого проєкту. Давайте створимо нову директорію для гіпотетичного Kubernetes проєкту та ініціалізуємо Git у ній.
Terminal window
# Створіть нову директорію
mkdirk8s-webapp
cdk8s-webapp
# Накажіть Git почати відстеження цієї директорії
gitinit
Очікуваний вивід:
Initialized empty Git repository in /home/alex/k8s-webapp/.git/
Що саме зробила команда git init? Вона не сканувала ваш жорсткий диск магічним чином. Вона просто створила приховану директорію з назвою .git всередині вашої папки k8s-webapp. Ця прихована директорія .git і є тим самим “Репозиторієм” з нашої моделі Трьох дерев. Саме тут Git зберігає всі внутрішні об’єкти бази даних, стиснутий вміст файлів, граф історії комітів та локальну конфігурацію для цього конкретного проєкту.
Якщо ви видалите директорію .git, ви видалите всю історію версій проєкту, хоча ваші поточні робочі файли залишаться недоторканими на диску.
Terminal window
# Виведіть список усіх файлів, включаючи приховані
ls-la
Очікуваний вивід:
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 для створення ваших перших комітів.
Секція 3: Життєвий цикл знімка: Add, Commit та Status
Тепер, коли у нас є активний репозиторій, давайте пройдемо через щоденний робочий процес відстеження файлів. Команда, яку ви будете використовувати частіше за будь-яку іншу — сотні разів на день — це git status. Вона діє як ваш компас, повідомляючи вам точно, де знаходяться ваші файли в межах Трьох дерев.
Давайте створимо наш перший файл, базову конфігурацію Kubernetes Namespace.
Terminal window
cat<<'EOF'>namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: webapp-prod
EOF
Запустіть git status, щоб побачити, що Git думає про цей щойно створений файл:
Terminal window
gitstatus
Вивід:
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)
Git розпізнає, що в Робочій директорії існує файл, але позначає його як “Untracked” (невідстежуваний). Це означає, що Git ніколи раніше не бачив цього файлу. Він не стежить за змінами в ньому і не буде автоматично робити його резервну копію. Git відстежує лише те, що ви явно накажете йому відстежувати.
Крок 2: Переміщення в Область індексації (git add)
Щоб повідомити Git, що ми хочемо включити цей файл у наш найперший знімок, ми повинні перемістити його в Область індексації (вантажну платформу) за допомогою команди git add.
Terminal window
gitaddnamespace.yaml
Знову запустіть git status, щоб поспостерігати за зміною стану:
Terminal window
gitstatus
Вивід:
On branch main
No commits yet
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: namespace.yaml
Файл перемістився. Тепер він класифікується як “Changes to be committed” (зміни, що будуть закомічені). Він знаходиться на вантажній платформі, чекаючи, поки фотограф зробить знімок.
Щоб назавжди зберегти індексовані зміни в Репозиторій, ми використовуємо git commit. Кожен коміт вимагає повідомлення (commit message), яке пояснює, чому була зроблена зміна. Написання хороших повідомлень до комітів — це базова професійна навичка. Хороше повідомлення пояснює намір і контекст, а не просто те, які рядки змінилися.
Terminal window
gitcommit-m"feat: add production namespace definition"
Вивід:
[main (root-commit) a1b2c3d] feat: add production namespace definition
1 file changed, 4 insertions(+)
create mode 100644 namespace.yaml
Давайте перевіримо git status останній раз, щоб побачити фінальний результат нашого робочого процесу:
Terminal window
gitstatus
Вивід:
On branch main
nothing to commit, working tree clean
Ваша Робоча директорія тепер описується як “clean” (чиста). Це означає, що кожен файл, який зараз знаходиться на вашому диску, точно відповідає останньому знімку, збереженому в базі даних .git. Очікуваних змін немає.
Молодший розробник тестував додаток локально, для чого був потрібен ключ доступу AWS. Для зручності він жорстко прописав (hardcoded) ключ прямо у свій файл deployment.yaml, просто щоб подивитися, чи запустяться Pods. Це спрацювало. Зрадівши, він запустив git add . (команду, яка без розбору індексує кожен змінений файл у всій директорії), а потім виконав git commit -m "fix deployment".
Потім він відправив код у публічний GitHub репозиторій. Протягом 120 секунд автоматизовані боти безпеки, що сканують публічні репозиторії GitHub, знайшли відкритий ключ AWS. Боти миттєво запустили сотні величезних серверів для майнінгу криптовалюти в декількох регіонах AWS, використовуючи скомпрометовані облікові дані. На той час, як розробник прокинувся наступного ранку, компанія отримала рахунок від хмарного провайдера на 65 000 доларів.
Урок: Ніколи сліпо не використовуйте git add ., якщо ви не впевнені на сто відсотків, що саме ви змінили. Завжди запускайте git status та git diff перед індексацією, щоб переконатися, що ви випадково не комітите паролі, API-ключі, приватні SSH-ключі або тимчасові файли налагодження.
Тепер, коли ви знаєте, як безпечно створювати знімки, вам неминуче знадобиться переглядати минулі знімки або вивчати точні зміни, внесені в окремі файли з часом. У наступному розділі ми заглибимося в команди, які дозволяють аналізувати історію комітів і вивчати точні відмінності у файлах.
Після того, як ви зробили кілька комітів, вам потрібні надійні способи перегляду часової шкали історії та розуміння того, що саме змінилося між різними моментами часу.
Давайте зробимо ще одну зміну в нашому проєкті. Ми оновимо файл Namespace, щоб додати мітку (label) — звичайне завдання в Kubernetes для цілей організації.
Перед тим як індексувати або комітити файл, ви завжди повинні перевірити, які саме рядки ви змінили. Пам’ять може підвести; diff об’єктивний. Команда git diff порівнює вашу поточну Робочу директорію з останнім зробленим знімком.
Terminal window
gitdiff
Вивід:
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:
Заголовки --- a/namespace.yaml та +++ b/namespace.yaml показують дві версії файлів, що порівнюються (стара проти нової).
@@ -2,3 +2,5 @@ — це заголовок фрагмента (chunk). Він надає системі контекст про те, приблизно в якому місці файлу відбулися зміни.
Рядки, що починаються з пробілу, — це незмінені рядки контексту. Git показує їх, щоб допомогти вам зорієнтуватися.
Рядки, що починаються з + (зазвичай підсвічені зеленим), — це абсолютно нові доповнення.
Рядки, що починаються з - (зазвичай підсвічені червоним), — це видалення. Якщо ви змінили рядок, Git представляє це як видалення старого рядка та додавання нового.
Зупиніться та подумайте: Уявіть, що ви запустили git diff для файлу Deployment і побачили наступний вивід:
@@ -10,3 +10,3 @@
spec:
replicas: 3
- image: nginx:1.14
+ image: nginx:1.24
Перш ніж читати далі, що саме зробив інженер у цьому файлі? Будьте точними.
Перевірка передбачення: Інженер не додав повністю новий структурний елемент. Він змінив існуючий рядок. Він видалив рядок, що вказував версію контейнера Nginx 1.14, і замінив його рядком, що вказує версію 1.24. Це означає оновлення версії образу контейнера.
Тепер, коли ми перевірили, що наші зміни правильні та не містять секретів, давайте індексуємо та закомітимо додавання мітки:
Terminal window
gitaddnamespace.yaml
gitcommit-m"chore: add environment label to namespace"
Щоб побачити часову шкалу ваших знімків, використовуйте команду git log. Вона відкриває пейджер (зазвичай less), що показує вашу історію у зворотному хронологічному порядку (найновіші спочатку).
Зверніть увагу на довгий рядок літер і цифр (наприклад, 8f9e0a1b2...). Це хеш коміту (Commit Hash, конкретно SHA-1 хеш). Це математично згенерований унікальний ідентифікатор для цього конкретного знімка. Він охоплює вміст файлів, автора, дату та хеш попереднього коміту. Ви використовуєте цей хеш, якщо вам коли-небудь знадобиться повернути ваш проєкт до цієї конкретної точки в часі.
Для більш компактного вигляду, що особливо корисно при дослідженні репозиторію з тисячами комітів за кілька років, використовуйте прапор --oneline:
Terminal window
gitlog--oneline
Вивід:
8f9e0a1 chore: add environment label to namespace
a1b2c3d feat: add production namespace definition
Ви також можете використовувати git log -p, щоб побачити реальні diff-и, внесені кожним окремим комітом в історії. Це дозволяє бачити не просто те, що коміт відбувся, але й те, які саме рядки були ним змінені.
Оволодіння здатністю орієнтуватися у вашій локальній часовій шкалі дає величезну впевненість при експериментах з кодом інфраструктури. Однак сучасна інженерія — це командна робота; наступний розділ розповість про те, як безпечно ділитися своєю локальною історією з віддаленими серверами для безперешкодної співпраці з іншими.
Секція 5: Співпраця зі світом: Remotes, Push та Pull
До цього моменту все, що ми робили, існувало виключно на жорсткому диску вашого локального ноутбука. Якщо ваш комп’ютер зламається або ви розіллєте на нього каву, вся історія вашого проєкту зникне назавжди. Крім того, ніхто інший у вашій команді не може бачити вашу роботу.
Щоб співпрацювати з іншими та створювати резервні копії вашої роботи, ви повинні підключити свій локальний репозиторій до віддаленого сервера, такого як GitHub, GitLab або Bitbucket.
“Remote” (віддалений репозиторій) — це просто ще один репозиторій Git, розміщений у мережі або інтернеті. Оскільки Git розподілений, кожен має повну самостійну копію історії. “Pushing” (відправлення) та “Pulling” (отримання) — це явні дії, які ми виконуємо для синхронізації нашої локальної часової шкали з віддаленою.
Коли ви створюєте порожній репозиторій на платформі на кшталт GitHub, платформа надає вам URL-адресу для підключення (зазвичай HTTPS або SSH). Ви наказуєте своєму локальному Git підключитися до цієї URL-адреси за допомогою команди git remote add.
За галузевою угодою, основний віддалений сервер за замовчуванням майже завжди називається origin.
Terminal window
# Приклад команди (не запускайте, якщо у вас немає реальної URL-адреси репозиторію)
Якщо ви приєднуєтеся до компанії і хочете завантажити існуючий проєкт, ви не використовуєте git init та git remote add. Замість цього ви використовуєте git clone <url>. Клонування автоматично ініціалізує локальний репозиторій, додає віддалений репозиторій як origin і завантажує всю історію та файли за один крок.
Щоб завантажити ваші локально створені коміти на віддалений сервер, ви робите “push”. Ви повинні вказати назву віддаленого сервера (зазвичай origin) та назву гілки (branch), яку ви відправляєте (часто main або master).
Terminal window
# Відправте вашу гілку main на remote origin вперше
gitpush-uoriginmain
Прапор -u означає “upstream” (висхідний потік). Його потрібно використовувати лише при першому відправленні нової гілки. Він створює стійкий зв’язок відстеження між вашою локальною гілкою main та віддаленою гілкою main. У майбутньому ви зможете просто вводити git push без жодних аргументів, і Git знатиме точно, куди відправляти дані.
Якщо колега вносить зміни, комітить їх локально і відправляє на GitHub, ваш локальний репозиторій не оновиться автоматично. Git ніколи не змінить ваші локальні файли без вашого явного дозволу. Ви повинні самі звернутися до сервера, завантажити їхні нові коміти та інтегрувати їх у свою локальну історію за допомогою git pull.
Terminal window
# Отримайте зміни з віддаленого сервера та злийте їх зі своєю локальною гілкою
gitpulloriginmain
“Під капотом” git pull — це насправді макрос, який запускає дві окремі команди послідовно: git fetch (яка безпечно завантажує нові коміти з віддаленого сервера, не змінюючи ваші робочі файли) та git merge (яка намагається безшовно поєднати завантажені зміни з вашою поточною робочою директорією).
Зупиніться та подумайте: Ви провели ранок, працюючи офлайн, і зробили два локальні коміти. Тим часом ваш колега відправив три коміти в ту саму гілку на віддаленому сервері. Що станеться, якщо ви сліпо запустите git push origin main, коли знову підключитеся до інтернету?
Перевірка передбачення: Відправлення буде відхилено віддаленим сервером. Git розпізнає, що віддалена гілка має коміти, яких немає у вашій локальній гілці, що запобігає ненавмисному перезапису роботи вашого колеги. Ви повинні спочатку запустити git pull, щоб отримати та інтегрувати їхні зміни у вашу локальну історію, перш ніж ви зможете успішно відправити свою об’єднану часову шкалу.
У будь-якому реальному проєкті програмного забезпечення або інфраструктури є численні файли, які ви ніколи не хочете комітити в систему контролю версій. До них належать:
Скомпільовані бінарні файли, виконувані файли або артефакти збірки (наприклад, .exe, .jar, директорії /dist/).
Лог-файли, згенеровані вашим додатком під час тестування.
Приховані файли операційної системи (наприклад, .DS_Store, що генерується macOS Finder).
Секрети, API-ключі, паролі до баз даних та локальні змінні середовища (наприклад, файли .env).
Якщо ви випадково закомітите їх, ви роздуєте розмір репозиторію або, що ще гірше, спричините серйозне порушення безпеки. Щоб наказати Git вдавати, що цих файлів взагалі не існує, ви створюєте звичайний текстовий файл із назвою .gitignore у кореневій папці вашого проєкту.
Давайте створимо .gitignore, адаптований для нашого хмарного середовища.
Terminal window
cat<<'EOF'>.gitignore
# Ігнорувати файли, згенеровані операційною системою
.DS_Store
Thumbs.db
# Ігнорувати локальні файли секретів та облікових даних
.env
secret-keys.yaml
kubeconfig-local
# Ігнорувати файли стану terraform (якщо ми додамо Infrastructure as Code пізніше)
*.tfstate
*.tfstate.backup
.terraform/
EOF
Git читає цей файл зверху вниз. Будь-який файл, що відповідає шаблону, вказаному в .gitignore, ніколи не з’явиться в git status як невідстежуваний. Це робить неможливим випадкове індексування такого файлу за допомогою універсальної команди на кшталт git add ..
Зупиніться та подумайте: Враховуючи наведений вище файл .gitignore, який із трьох наступних щойно створених файлів все одно відображатиметься як “Untracked” при запуску git status? 1) main.tfstate, 2) secret-keys.yaml, 3) secret-keys.txt.
Перевірка передбачення: Тільки secret-keys.txt з’явиться як невідстежуваний. main.tfstate ігнорується шаблоном *.tfstate, а secret-keys.yaml явно ігнорується за назвою. secret-keys.txt не відповідає жодному шаблону ігнорування, тому Git продовжуватиме позначати його як невідстежуваний файл.
Зупиніться та подумайте: У вас є файл з назвою database-creds.txt, який ви створили минулого тижня. Ви закомітили його в Git кілька днів тому. Сьогодні ви усвідомлюєте свою помилку і додаєте database-creds.txt у свій файл .gitignore. Ви змінюєте файл з обліковими даними і запускаєте git status. Чи ігноруватиме Git ці зміни?
Перевірка передбачення: Ні, Git не ігноруватиме зміни. Файл .gitignore запобігає додаванню в базу даних лише невідстежуваних файлів. Якщо файл вже відстежується (закомічений), Git продовжуватиме відстежувати його незалежно від того, що написано в .gitignore. Ви повинні явно видалити його з відстеження за допомогою git rm --cached database-creds.txt, перш ніж правило ігнорування почне діяти.
Git був створений за два тижні. У 2005 році спільнота ядра Linux раптово втратила безкоштовну ліцензію на пропрієтарну систему контролю версій. Лінус Торвальдс, творець Linux, негайно потребував заміни. Не вражений існуючими варіантами, він написав початкову версію Git всього за 14 днів, а величезна кодова база ядра Linux перейшла на неї через два місяці.
Назва — це самокритична образа. Торвальдс, відомий своїм різким гумором, назвав систему “Git” (британське сленгове слово для впертої, неприємної або некомпетентної людини). Він відомо пожартував на конференції: “Я егоїстичний покидьок, і називаю всі свої проєкти на свою честь. Спочатку Linux, тепер Git”.
Git не відстежує порожні директорії. Через архітектуру своєї бази даних, яка зіставляє шляхи безпосередньо з вмістом файлів, Git відстежує лише файли. Якщо ви створите порожню директорію і запустите git status, Git повністю її проігнорує. Розробники обходять це обмеження, розміщуючи прихований порожній файл (часто за домовленістю з назвою .gitkeep) всередині директорії, щоб змусити Git відстежувати факт існування папки.
Колосальна стійкість до колізій. Хеші, що ідентифікують ваші коміти (рядки SHA-1), — це 40-символьні шістнадцяткові числа. Математична ймовірність того, що два різні знімки згенерують однаковий хеш (колізія хешів), астрономічно низька. Статистично у вас набагато більше шансів бути враженим блискавкою і одночасно виграти в лотерею, ніж зіткнутися з випадковою колізією хешів Git у вашому репозиторії.
Використання нерозбірливої команди git add . без попередньої перевірки git status, випадкове затягування файлу .env в область індексації.
Якщо ще не відправлено (unpushed): git reset HEAD~1, щоб скасувати коміт локально. Якщо відправлено — секрет скомпрометовано. Ви повинні негайно відкликати/змінити облікові дані. Не просто видаляйте їх у новому коміті; історія постійна.
”fatal: refusing to merge unrelated histories”
Ви ініціалізували репозиторій локально і окремо на GitHub з дефолтним README, а потім спробували зробити pull. Git вважає їх двома абсолютно різними, непов’язаними проєктами.
Запустіть git pull origin main --allow-unrelated-histories, щоб примусово наказати Git поєднати дві різні часові шкали в одну.
”Updates were rejected because the remote contains work that you do not have locally”
Колега відправив нові коміти на сервер GitHub, поки ви працювали офлайн. Git відмовляється дозволити вам зробити push і перезаписати їхню роботу.
Запустіть спочатку git pull, щоб завантажити та інтегрувати їхні зміни у вашу локальну гілку. Вирішіть потенційні конфлікти злиття, потім запустіть git push.
Порожні або безглузді повідомлення до комітів
Поспіх. Використання розпливчастих повідомлень на кшталт git commit -m "update" або git commit -m "fixed stuff".
Використовуйте git commit --amend -m "нове краще повідомлення", якщо ви ще не зробили push. Виробляйте професійну звичку писати “Чому”, а не просто “Що”.
Забування індексувати файли перед комітом
Запуск git commit -m "message", коли ваші зміни все ще знаходяться в Робочій директорії, повністю минаючи Область індексації.
Запустіть git status, щоб побачити, що не індексовано. Виконайте git add <file>, щоб перемістити зміни в індекс, потім повторіть команду git commit.
Коміт величезних бінарних файлів
Випадкове додавання скомпільованих артефактів, дампів пам’яті баз даних або великих відео в репозиторій. Git розроблений для відстеження тексту, а не великих бінарних файлів.
Видаліть файл з бази відстеження за допомогою git rm --cached <file>, закономіть видалення та негайно додайте цей тип файлу у ваш .gitignore.
1. Ваша команда щойно розгорнула нову конфігурацію Kubernetes, і кластер негайно вийшов з ладу. Вам потрібно швидко побачити, хто вніс останню зміну і яким було повідомлення до коміту. Яку команду ви запустите?
Ви повинні запустити `git log` або `git log --oneline`. Ця команда відображає історію комітів у зворотному хронологічному порядку, показуючи автора, мітку часу та повідомлення до кожного знімка. Аналізуючи цей вивід, ви зможете миттєво визначити, хто вніс останні зміни, і прочитати їхнє пояснення того, чому ця зміна була необхідною. Така швидка історична видимість — саме те, чому контроль версій критично важливий під час інцидентів на продакшні.
2. Ви змінили файл `service.yaml` на своєму ноутбуці, щоб відкрити новий порт. Ви вводите `git commit -m "expose port 8080"`, але Git повертає повідомлення "nothing added to commit but untracked files present". Що ви забули зробити?
Ви забули перемістити файл із Робочої директорії в Область індексації за допомогою команди `git add`. Архітектура Git вимагає від вас явного вибору файлів, які мають бути включені в наступний знімок. Оскільки ви оминули Область індексації, Git побачив ваш змінений файл, але відмовився автоматично включити його в репозиторій. Ви повинні запустити `git add service.yaml`, перш ніж намагатися зробити коміт знову.
3. Ви збираєтеся індексувати `configMap.yaml`, але не можете згадати, чи встановили ви пароль для тестування, чи залишили пароль для продакшну. Яку команду слід запустити, щоб перевірити точні рядки, які ви змінили, перед індексацією?
Ви повинні запустити `git diff`, щоб переглянути точні рядкові зміни. Ця команда порівнює вашу поточну Робочу директорію з останнім збереженим знімком у репозиторії. Вона відобразить видалені рядки червоним кольором, а додані — зеленим, дозволяючи вам об'єктивно перевірити вміст файлу. Використання цієї команди запобігає випадковому коміту секретів продакшну в постійний граф історії.
4. Ви щойно приєдналися до нового проєкту. Ви клонуєте репозиторій, але коли запускаєте `git push`, термінал запитує ваше ім'я користувача та електронну пошту і каже запустити `git config`. Чому це необхідно?
Git вимагає ідентифікації автора для кожного коміту, щоб забезпечити підзвітність і простежуваність у середовищах спільної розробки. Без налаштування ваших `user.name` та `user.email` Git відмовляється створювати знімки, оскільки не може приписати зміни конкретній людині. Ця ідентифікаційна інформація назавжди вбудовується в криптографічний хеш коміту. У разі збою інфраструктури це авторство дозволяє команді негайно дізнатися, до кого звернутися за контекстом щодо внесених змін.
5. Ви створили файл з назвою `aws-credentials.json` на своїй локальній машині для тестування скрипта. Ви ніколи не хочете, щоб цей файл був закомічений у репозиторій компанії. Що саме ви повинні зробити, щоб він ігнорувався назавжди?
Ви повинні створити звичайний текстовий файл із назвою `.gitignore` у корені вашого репозиторію, якщо він ще не існує. Всередині цього файлу потрібно додати точну назву файлу `aws-credentials.json` з нового рядка. Git читає цей конфігураційний файл зверху вниз і автоматично відфільтровуватиме будь-які відповідні файли зі свого радара відстеження. Це гарантує, що файл з обліковими даними ніколи випадково не буде індексований або закомічений, запобігаючи серйозному порушенню безпеки.
6. Молодший розробник намагається "скинути" зламаний проєкт, щоб почати спочатку. Він відкриває провідник файлів, видаляє приховану папку `.git`, а потім вводить `git status` у своєму терміналі, очікуючи, що Git зрозуміє, що проєкт був скинутий, і покаже порожню історію. Що насправді станеться і чому?
Коли розробник введе `git status`, термінал поверне помилку "fatal: not a git repository", тому що він повністю знищив систему контролю версій для цієї папки. Прихована директорія `.git` — це не просто конфігураційний файл; це ціла база даних репозиторію, що містить усі коміти, гілки та історичні знімки. Видаливши її, він не скинув історію — він назавжди стер її локально, перетворивши свій проєкт назад на звичайну, невідстежувану папку в операційній системі. Робочі файли на його диску залишаться недоторканими, але Git більше не керуватиме ними.
7. Ви та ваш колега обидва змінюєте один і той самий файл `nginx-deployment.yaml`. Він відправляє зміну, яка встановлює `replicas: 5`, поки ви перебуваєте офлайн. Ви локально змінюєте той самий рядок на `replicas: 2` і намагаєтеся зробити push. Git відхиляє ваш push, тому ви запускаєте `git pull`. Що станеться далі і як це вирішити?
Git спробує автоматично злити зміни, але оскільки ви обидва змінили один і той самий рядок, він зупиниться і оголосить про конфлікт злиття (merge conflict). Він не може впевнено вгадати, чи має розгортання мати 5 реплік чи 2, тому залишає рішення людині. Щоб вирішити конфлікт, ви повинні відкрити файл у редакторі та знайти маркери конфлікту (які виглядають як `<<<<<<< HEAD` та `>>>>>>>`). Після ручного редагування файлу до бажаного стану та видалення маркерів, ви повинні використати `git add` та `git commit`, щоб завершити злиття перед відправленням (push).
У цій вправі ви створите локальний репозиторій з нуля, змоделюєте стандартний інженерний робочий процес, зробивши кілька логічних комітів, і проаналізуєте отриману історію. Ми будемо використовувати фіктивні файли конфігурації Kubernetes для симуляції реального процесу роботи з інфраструктурою.
Відкрийте 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
# Змініть файл за допомогою вашого улюбленого редактора (nano, vim або cat)
Запустіть команду для перегляду повної історії комітів у компактному однорядковому форматі. Переконайтеся, що всі три ваші коміти присутні в хронологічному порядку.
Команда перегляду історії виконана.
Три окремі коміти видно у виводі.
Рішення: Завдання 5
Terminal window
gitlog--oneline
Вивід має виглядати приблизно так:
3b2a1c4 fix: set deployment replicas to 3
9f8e7d6 feat: add web deployment skeleton
1a2b3c4 docs: add initial readme
Завдання 6: Бонусне завдання — Просунуті правила ігнорування
Ви працюєте над новим додатком, який генерує численні лог-файли, що закінчуються на .log, у різних директоріях. Ви хочете, щоб Git ігнорував їх усі для економії місця, але ви повинні переконатися, що один конкретний файл з назвою audit-trail.log у кореневій директорії завжди відстежується з міркувань відповідності стандартам.
Створіть файл .gitignore, який реалізує саме таку конфігурацію. Перевірте своє рішення, створивши фіктивні файли (наприклад, app.log, database.log та audit-trail.log) і перевіривши git status, щоб переконатися, що лише audit-trail.log готовий до відстеження.
Файл .gitignore створено з відповідними шаблонами та правилами виключення.
Створено фіктивні файли для тестування правил.
git status підтверджує, що тільки потрібний файл не відстежується.
Рішення: Завдання 6
Terminal window
# Створіть файл .gitignore
cat<<'EOF'>.gitignore
*.log
!audit-trail.log
EOF
# Створіть фіктивні файли
touchapp.log
touchdatabase.log
touchaudit-trail.log
# Перевірте статус
gitstatus
Git покаже .gitignore та audit-trail.log як невідстежувані файли. Інші файли .log будуть успішно проігноровані.
Наступний модуль: Модуль 0.7: Що таке мережі? — Тепер, коли ви можете відстежувати файли, настав час зрозуміти, як комп’ютери насправді розмовляють один з одним через мережеві з’єднання.