- Андрей Куманяев/
- Git: руководства и команды/
- Индекс Git (staging area): полное объяснение ключевой концепции/
Индекс Git (staging area): полное объяснение ключевой концепции
Индекс (staging area) — это одна из самых важных концепций Git, которую часто пропускают новички. Понимание того, зачем нужна эта промежуточная область, делает работу с Git намного эффективнее и осознаннее.
Что такое индекс в Git #
Индекс — это файл (физически .git/index), который содержит информацию о том, какие изменения будут включены в следующий коммит. Это буферная зона между рабочей директорией и репозиторием.
Трёхуровневая архитектура Git:
╔──────────────────────────╗
│ Рабочая директория │ ← вы редактируете файлы здесь
│ (Working Directory) │ git status показывает изменения
╚──────────────────────────╝
↓ git add
╔──────────────────────────╗
│ Индекс (Staging) │ ← подготовленные изменения
│ (Index / Stage Area) │ git diff --staged показывает содержимое
╚──────────────────────────╝
↓ git commit
╔──────────────────────────╗
│ Репозиторий │ ← история проекта
│ (Repository / .git) │ git log показывает коммиты
╚──────────────────────────╝
Синонимы: индекс = staging area = stage = кэш. Все эти термины обозначают одно и то же.
Зачем нужен индекс #
Без индекса каждый git commit включал бы все изменения во всех файлах. Индекс даёт возможность выбирать.
Выбор отдельных файлов для коммита:
# Вы отредактировали 5 файлов, но хотите коммитить только 2
git add файл1.js
git add файл2.js
# файл3.js, файл4.js, файл5.js остаются вне индекса
git commit -m "Fix: исправлена авторизация"
# Коммит содержит только файл1 и файл2
Разделение одного файла на несколько коммитов:
# Вы добавили в один файл две независимые функции
# Хотите сделать два отдельных коммита
git add -p app.js
# Git интерактивно покажет каждое изменение
# Выбираете только первую функцию
git commit -m "feat: добавлена функция авторизации"
git add app.js
git commit -m "feat: добавлена функция поиска"
Проверка перед коммитом:
git diff --staged # посмотреть что именно войдёт в коммит
git commit # если всё правильно, коммитить
Команды работы с индексом #
Добавить в индекс:
git add файл.js # конкретный файл
git add . # все файлы в текущей директории
git add -A # все файлы во всём репозитории
git add -p # интерактивно выбирать части файлов
git add -u # только уже отслеживаемые файлы
Просмотр содержимого индекса:
git status # краткий обзор: что в индексе, что нет
git diff --staged # подробные изменения в индексе
git diff --cached # то же самое (синоним)
git ls-files # список файлов в индексе
Удалить из индекса (не удаляя файл):
git restore --staged файл.js # современный синтаксис (Git 2.23+)
git reset файл.js # классический синтаксис
git reset HEAD файл.js # старый синтаксис (тоже работает)
Жизненный цикл файла #
Untracked (новый файл, Git не знает о нём)
↓ git add
Staged (в индексе, готов к коммиту)
↓ git commit
Committed (в репозитории, в истории)
↓ редактирование файла
Modified (изменён, но не добавлен в индекс)
↓ git add
Staged (снова в индексе)
→ ...и так далее
Практический пример работы с индексом #
# Создаём два файла
echo "console.log('app1')" > app1.js
echo "console.log('app2')" > app2.js
# Проверяем статус (файлы не отслеживаются)
git status
# Untracked files: app1.js, app2.js
# Добавляем только app1.js в индекс
git add app1.js
# Статус после добавления
git status
# Changes to be committed: app1.js ← в индексе
# Untracked files: app2.js ← не в индексе
# Смотрим что в индексе
git diff --staged
# diff --git a/app1.js ...
# Коммитим только app1.js
git commit -m "Add app1.js"
# app2.js всё ещё не в индексе
git status
# Untracked files: app2.js
# Добавляем и коммитим app2.js
git add app2.js
git commit -m "Add app2.js"
Интерактивное добавление частей файла #
Самая мощная возможность индекса — выбирать отдельные «hunks» (части) из одного файла:
git add -p app.js
# Git покажет каждое изменение и спросит:
# y = добавить этот chunk в индекс
# n = пропустить
# s = разделить на меньшие части
# e = редактировать вручную
# q = выйти
# ? = помощь
Это позволяет создавать «чистые» коммиты, когда вы сделали несколько несвязанных изменений в одном файле.
Индекс и .gitignore #
Файлы в .gitignore не добавляются в индекс автоматически:
echo "*.log" > .gitignore
echo "error occurred" > debug.log
git add . # debug.log не будет добавлен
git status # debug.log не показывается
# Если нужно добавить файл из .gitignore принудительно
git add -f debug.log
Физическое расположение индекса #
Индекс хранится в файле .git/index. Это бинарный файл, который содержит: список файлов с их метаданными (права, размер, время изменения), хеши содержимого каждого файла (SHA-1).
# Посмотреть содержимое индекса в читаемом виде
git ls-files
git ls-files --debug # с хешами
git ls-files --eol # с информацией об окончаниях строк
Часто задаваемые вопросы #
Индекс — это то же самое, что staging area? Да, это синонимы. Также используют термины: cache, stage, index — всё одно и то же.
Где физически хранится индекс? В файле .git/index. Это бинарный файл, не открывайте его текстовым редактором.
Можно ли работать без индекса? Нет, это встроенная часть архитектуры Git. Но можно использовать git commit -a для автоматического добавления изменённых файлов, минуя явный git add.
Как удалить файл из индекса, не удаляя с диска? git restore --staged файл.js (Git 2.23+) или git reset файл.js. Файл останется в рабочей директории.
Можно ли удалить файл из индекса, чтобы Git перестал его отслеживать? Да: git rm --cached файл.js. Файл останется на диске, но Git перестанет его отслеживать. Полезно при добавлении файла в .gitignore после того, как он уже был в репозитории.
Заключение #
Индекс — это ключевая концепция Git, которая даёт контроль над тем, что попадает в каждый коммит. Освойте команды git add, git add -p, git status и git diff --staged — и ваши коммиты станут чистыми и логичными.
Следующий шаг — изучите команду git add для понимания всех вариантов добавления файлов, и git commit для понимания, что происходит после подготовки индекса. Шпаргалку по всем основным концепциям смотрите в основах Git.