Три места, где живёт файл
Коммит в Git — это снимок всех файлов проекта в определённый момент, который Git запоминает навсегда вместе с автором, датой и вашей подписью. Сегодня вы сделаете первый коммит: подготовите index.html командой git add и зафиксируете его командой git commit.
В прошлый раз Git увидел index.html, но отнёсся к нему как к неотслеживаемому: в историю файл не попал. Чтобы это изменить, нужно понять, через какие три места проходит файл.
Простыми словами
Представьте, что вы собираете фотоальбом. Фотографии лежат у вас на столе. Те, что хотите отправить, вы кладёте в коробку. Когда коробка собрана, вы запечатываете её, подписываете и отправляете в архив. После этого архивная запись остаётся навсегда, а на столе вы можете спокойно продолжать раскладывать новые фото.
| Место | Аналогия | Официальное название |
|---|---|---|
| Где вы работаете с файлами | Стол | Рабочая папка (working tree) |
| Что войдёт в следующий снимок | Коробка для отправки | Индекс (staging area, «сцена») |
| Сохранённая история | Архив с подписанными коробками | Репозиторий, коммиты |
Официальный термин
Рабочая папка — ваши обычные файлы в папке проекта, те, что вы открываете в VS Code. Индекс — список того, что попадёт в следующий коммит. Коммит (commit) — сохранённый снимок проекта в истории. Двигают файл между этими местами две команды:
рабочая папка --git add--> индекс --git commit--> история
(ваши файлы) (черновик (снимки проекта,
коммита) коммиты)
На схеме стрелки показывают путь файла: сначала git add перекладывает его из рабочей папки в индекс, затем git commit превращает содержимое индекса в коммит.
Частая путаница: коммит и «сохранить файл»
Ctrl+S сохраняет файл на диск — и всё. Коммит делает другое: запоминает состояние всех подготовленных файлов в истории, с подписью и датой, и к этому состоянию можно вернуться потом. Файл сохранён на диск, но не закоммичен — в истории его нет.
git add: положить в индекс
Команда git add (add — «добавить») кладёт файл в индекс, то есть в коробку для отправки. Ей нужно сказать, какой файл:
$ git add index.html
$ git status
On branch main
No commits yet
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: index.html
Разбор по строкам
git add index.html— добавить файл в индекс. Если всё в порядке, команда молчит: в консоли Git тишина обычно значит успех.Changes to be committed— «изменения, которые войдут в коммит». Это содержимое индекса.new file: index.html— Git считает файл новым и готов записать его в историю целиком. С этого момента файл отслеживаемый: Git о нём знает, хотя в истории его ещё нет — туда он попадёт с коммитом.- В скобках Git подсказывает, как убрать файл из индекса (
git rm --cached). Отмена — тема следующего модуля, пока запомните только, что такой выход есть.
Так же можно добавить все файлы сразу: git add . (точка — «всё в текущей папке и глубже»). Это удобно, но опасно: в индекс попадут и случайные файлы, которые вы вообще не собирались фиксировать. Поэтому перед git add . всегда смотрите на git status.
Подробно — в документации: git add.
git commit -m: сделать снимок
Теперь содержимое индекса можно превратить в коммит. Команда git commit с флагом -m (message, «сообщение») делает снимок и сразу записывает подпись, которую вы пишете в кавычках:
$ git commit -m "Добавить главную страницу"
[main (root-commit) 027a150] Добавить главную страницу
1 file changed, 15 insertions(+)
create mode 100644 index.html
Разбор по строкам
[main (root-commit) 027a150]— коммит сделан на веткеmain. Словоroot-commitозначает «корневой», то есть самый первый коммит, у которого нет предыдущего. Он будет в выводе только один раз.027a150— короткий номер коммита (хеш). По нему коммит можно найти в истории; что это такое, разберём, когда будем читать историю проекта. У вас этот номер будет другим — это нормально.Добавить главную страницу— ваше сообщение, подпись снимка.1 file changed, 15 insertions(+)— «изменён 1 файл, добавлено 15 строк». Для нового файла все его строки считаются добавленными.create mode 100644 index.html— Git запомнил, что в проекте появился новый файл. Число100644означает «обычный файл», вдаваться в него не нужно.
Проверьте результат через git status:
$ git status
On branch main
nothing to commit, working tree clean
working tree clean — «рабочая папка чиста»: все файлы совпадают с последним коммитом, нет ни новых, ни изменённых, ни подготовленных. Это то состояние, к которому вы будете возвращаться после каждого коммита.
Что именно хранится в коммите
В коммите лежит не «разница с прошлым разом», а снимок всех отслеживаемых файлов на этот момент, плюс автор (имя и почта из настроек), время и сообщение. Поэтому имя и почту мы настраивали в самом начале: без них Git не знает, кого записать автором.
Подробно — в документации: git commit.
Сообщение коммита
Сообщение — это подпись к снимку, и читать её будете вы сами через месяц, а то и другие люди. Хорошее сообщение отвечает на вопрос «что делает этот коммит?». В курсе мы пишем так: по-русски, начинаем с глагола в неопределённой форме (инфинитиве) с заглавной буквы, без точки в конце, коротко. Удобная проверка: фраза должна подходить к началу «Этот коммит должен…» — «…добавить главную страницу».
| Плохо | Почему | Хорошо |
|---|---|---|
fix | Что исправлено? Где? | Исправить ссылку на проекты |
asdf | Набор букв ничего не говорит | Добавить стили |
правки | Любой коммит — это правки | Добавить README |
Коммит без -m
Если выполнить просто git commit, без -m, Git откроет редактор, который вы выбрали в начале курса (VS Code или nano). В нём уже есть строки-подсказки, начинающиеся с #; они в сообщение не попадают. Нужно написать сообщение в первой строке, сохранить файл и закрыть редактор. Если сообщение пустое, Git отменяет коммит:
Aborting commit due to empty commit message.
Если вместо привычного редактора открылся Vim (экран с тильдами ~ и без подсказок), выход из него описан в уроке про настройку Git: нажмите Esc, затем введите :q! и Enter.
Практика у себя
Репозиторий уже создан, index.html лежит в нём неотслеживаемым. Сделайте первый коммит.
Шаг 1. Откройте терминал в папке проекта и убедитесь, что вы в нужном месте:
$ cd ~/projects/portfolio
$ git status
On branch main
No commits yet
Untracked files:
(use "git add <file>..." to include in what will be committed)
index.html
nothing added to commit but untracked files present (use "git add" to track)
Шаг 2. Подготовьте файл и проверьте, что он перешёл в раздел Changes to be committed:
$ git add index.html
$ git status
Ожидаемый вывод — тот самый, что в разборе выше: new file: index.html в разделе Changes to be committed.
Шаг 3. Сделайте коммит. Сообщение пишите дословно, как в примере: ниже по курсу мы будем на него ссылаться.
$ git commit -m "Добавить главную страницу"
[main (root-commit) 027a150] Добавить главную страницу
1 file changed, 15 insertions(+)
create mode 100644 index.html
Номер в квадратных скобках у вас будет свой. Остальное должно совпасть.
Шаг 4. Убедитесь, что рабочая папка чиста:
$ git status
On branch main
nothing to commit, working tree clean
Проверьте себя
git commitвывел строку с(root-commit)и сообщением «Добавить главную страницу».git statusсообщаетnothing to commit, working tree clean.- Вы можете назвать три места, через которые проходит файл, и команды, которые его между ними перекладывают.
Частые ошибки
nothing added to commit but untracked files present. Вы запустили git commit, не сделав git add: в индексе пусто, и Git нечего фиксировать. Выполните git add index.html и повторите коммит.
Коммит без add после правки файла. Обновили уже закоммиченный файл и сразу сделали git commit -m "…", а Git ответил, что фиксировать нечего (no changes added to commit). Изменённый файл тоже нужно подготовить командой git add. Подробно разберём в следующем уроке.
Author identity unknown / Please tell me who you are. Git не знает, кого записать автором коммита: не настроены имя и почта. Выполните две команды из настройки Git, подставив свои данные, и повторите коммит:
$ git config --global user.name "Алекс Иванов"
$ git config --global user.email "alex@example.com"
Предупреждение про LF и CRLF на Windows. После git add в Git Bash может появиться строка вида warning: in the working copy of 'index.html', LF will be replaced by CRLF the next time Git touches it. Это не ошибка. Она про разные способы обозначать конец строки в Windows и других системах; Git решает это сам по настройке core.autocrlf, которую вы выбрали раньше. Коммит всё равно пройдёт.
Закрыли редактор без сообщения. Появилось Aborting commit due to empty commit message. — коммит не создан, файл остался в индексе. Запустите git commit снова и напишите сообщение.
Что важно запомнить
- Файл проходит три места: рабочая папка, индекс, репозиторий (история).
git addкладёт файл в индекс,git commitделает из индекса снимок.- Коммит — это не «сохранить файл», а снимок состояния проекта с подписью, автором и датой.
- Сообщение коммита отвечает на вопрос «что делает этот коммит» и пишется глаголом в инфинитиве: «Добавить стили».
git statusпосле коммита:working tree clean— всё закоммичено.
Дальше проект начнёт меняться: появятся стили, README, новые разделы. Как увидеть, что именно вы изменили, ещё до коммита, и как собрать коммит только из нужных файлов, расскажет следующий урок.