Git: staged vs unstaged — яка різниця?
Супермаркет з кошиком продуктів касовою стрічкою та оплатою — аналогія Git staging area
Ти набираєш git add . перед кожним комітом, але чи розумієш, що саме відбувається між "я змінив файл" і "я зберіг зміни в історію"? Між цими двома моментами є staging area — одна з найважливіших концепцій Git, яку більшість новачків пропускають.
Давай розберемось раз і назавжди.
Каса в супермаркеті
Уяви, що ти в супермаркеті:
- Кошик — ти ходиш по магазину і кидаєш у кошик все, що побачив: молоко, хліб, сир, шоколадку. Це твоя робоча директорія (working directory) — тут живуть усі зміни, які ти зробив у файлах
- Касова стрічка — підходиш до каси і кладеш на стрічку тільки молоко і хліб. Сир і шоколадку вирішив не брати. Стрічка — це staging area: ти обираєш, що саме потрапить у покупку
- Чек — касир пробиває товари зі стрічки. Чек — це твій commit: зафіксований факт, який не зміниш
Аналогія Git зі staging area: кошик — касова стрічка — чек
Ключовий момент: не все з кошика потрапляє на стрічку. Ти обираєш. Саме це дає staging area — контроль над тим, що саме входить у коміт.
Три зони Git
Кожен файл у Git-проєкті існує в одній з трьох зон:
Три зони Git: Working Directory, Staging Area, Repository
- Working Directory — файли на твоєму диску. Все, що ти редагуєш у VS Code
- Staging Area — "чернетка" наступного коміту. Сюди потрапляють зміни після
git add - Repository — збережена історія. Після
git commitзміни стають частиною проєкту назавжди
Цікавий факт: всередині Git staging area називається index — це бінарний файл .git/index. Назву "staging area" придумали пізніше, бо "index" нікому нічого не пояснював. В деяких командах ти побачиш прапорець --cached — це теж про staging area. Три назви для одного і того ж.
Бачимо це в терміналі
Створимо простий проєкт і подивимось, як це працює:
mkdir demo && cd demo
git init
echo "Привіт" > index.html
echo "body { margin: 0 }" > style.css
Перевіряємо статус:
git status
Untracked files:
index.html
style.css
Обидва файли untracked — Git їх бачить, але не відстежує. Додамо тільки один:
git add index.html
git status
Changes to be committed:
new file: index.html ← staged (на стрічці)
Untracked files:
style.css ← не staged (в кошику)
Тепер index.html — staged, а style.css — ні. Якщо зробити git commit зараз, збережеться лише index.html.
Один файл — два стани одночасно
Це момент, який плутає навіть досвідчених розробників. Один файл може бути одночасно staged і unstaged:
git add index.html # staged: "Привіт"
echo "Бувай" >> index.html # додали рядок ПІСЛЯ staging
git status
Changes to be committed:
modified: index.html ← staged версія ("Привіт")
Changes not staged for commit:
modified: index.html ← нові зміни ("Бувай")
Git зберіг знімок файлу на момент git add. Подальші зміни — вже нова історія. Щоб додати і їх, потрібен ще один git add.
Як подивитися різницю
Дві команди, які варто запам'ятати:
git diff # що змінено, але НЕ staged (кошик)
git diff --staged # що staged і піде в коміт (стрічка)
git diff — це "що в кошику, але ще не на стрічці". git diff --staged — "що вже на стрічці і чекає на касира".
Основні команди
| Дія | Команда |
|---|---|
| Додати файл на стрічку | git add файл |
| Додати все | git add . (обережно!) |
| Додати частину файлу | git add -p файл |
| Зняти зі стрічки | git restore --staged файл |
| Скасувати зміни у файлі | git restore файл |
| Подивитися unstaged зміни | git diff |
| Подивитися staged зміни | git diff --staged |
git add -p — це суперсила: Git покаже кожну зміну окремо і запитає "додати це?". Можна закомітити лише 3 рядки з 50 змінених. Спробуй — це змінює підхід до комітів.
Типова помилка новачків
git add .
git commit -m "все разом"
Знайоме? git add . додає абсолютно все — і виправлення бага, і новий footer, і випадково змінений .env з паролями. Один гігантський коміт, в якому неможливо розібратися.
Натомість:
git add src/auth.js
git commit -m "Виправив помилку авторизації"
git add src/components/Footer.tsx
git commit -m "Додав footer з посиланнями"
Два чистих коміти, кожен про одну річ. Якщо footer зламає щось — відкотиш тільки його, не чіпаючи виправлення бага.
Навіщо Лінус це придумав?
Лінус Торвальдс створив Git у 2005 році для розробки ядра Linux. Над ядром працюють тисячі людей. Уяви хаос, якщо кожен коміт містить 15 різних змін і неможливо зрозуміти, яка з них зламала систему.
Staging area вирішує цю проблему: ти контролюєш, що саме потрапляє в кожен коміт. Це як різниця між "кинути все в коробку і заклеїти" та "акуратно скласти речі по категоріях". Коли потрібно буде щось знайти — подякуєш собі.
Лінус пізніше зізнавався, що пишається staging area навіть більше, ніж іншими частинами Git — це не просто технічна необхідність, а свідоме рішення, яке робить щоденну роботу зручнішою.
Що далі?
Staging area — це фундамент щоденної роботи з Git. Якщо ти тільки починаєш — пройди наш урок з основ Git, де ми крок за кроком створюємо перший репозиторій. Потім переходь до GitHub та віддалених репозиторіїв — дізнаєшся, як працювати з кодом у команді. А Git-шпаргалка завжди під рукою.
Наступного разу перед git add . зупинись на секунду. Подумай, що саме має бути на касовій стрічці. Твоє майбутнє "я" скаже дякую.