Перейти к содержимому
RootPoligon

Репозиторий и первая история

Чтение и практика ~15 мин

Ситуация

Вы правите настройки сайта, и через неделю он перестаёт работать. Что вы поменяли? Когда? Как вернуть вчерашний вариант? Если изменения хранятся только в самих файлах, ответить нечем: файл помнит лишь последнюю версию. Git хранит историю — снимки файлов с описанием, кто, когда и зачем их изменил.

Главная мысль

Репозиторий — это папка, за которой следит Git. История живёт в скрытой папке .git внутри неё. Git ничего не сохраняет сам: снимок появляется, только когда вы его сделаете — это коммит. Чтобы понимать, что Git сделает дальше, спрашивайте его: git status.

Новые слова

  • Git — программа, которая ведёт историю изменений в папке.
  • Репозиторий — папка с историей Git (папка .git внутри).
  • Коммит — сохранённый снимок выбранных файлов: содержимое, автор, время, сообщение.
  • Ветка — имя линии истории. В новом репозитории она одна; мы назовём её main. Подробно — в главе 4.
  • Неотслеживаемый файл (untracked) — файл в папке, о котором Git пока ничего не хранит.

Разбор: первый репозиторий

Все команды выполняются от вашего пользователя в терминале. Исходное состояние: папки ~/git-course нет.

Создаём папку и репозиторий

if [ -e ~/git-course ]; then
  echo "Отказ: ~/git-course уже существует. Не продолжайте: сначала выберите отдельную учебную папку."
else
  mkdir -p ~/git-course/site && cd ~/git-course/site && git init -b main
fi
Initialized empty Git repository in /root/git-course/site/.git/

Продолжайте главу только если появилось сообщение Initialized empty Git repository. При отказе ничего не записано; не выполняйте следующие блоки поверх существующего проекта.

Путь в выводе зависит от вашей домашней папки. Ключ -b main задаёт имя первой ветки. Без него Git 2.43 назовёт её master и напечатает длинную подсказку (hint: Using 'master' as the name for the initial branch…) — это не ошибка, просто в курсе везде main.

Спросим, что видит Git:

git status
On branch main

No commits yet

nothing to commit (create/copy files and use "git add" to track)

Три факта: мы на ветке main, коммитов нет, сохранять нечего.

Создаём файлы

Конструкция cat > файл <<'EOF' записывает в файл все строки до строки EOF. Так файлы можно создать без редактора; если вам удобнее nano, создайте их в нём с тем же содержимым.

cat > index.html <<'EOF'
<!doctype html>
<html lang="ru">
<head><meta charset="utf-8"><title>Учебный сайт</title></head>
<body>
<h1>Учебный сайт</h1>
<p>Здесь будет расписание занятий.</p>
</body>
</html>
EOF
cat > site.conf <<'EOF'
# Настройки учебного сайта
PORT=8081
NAME=site
TITLE=Учебный сайт
EOF
cat > README.md <<'EOF'
# Учебный сайт

Запуск для проверки: python3 -m http.server 8081
EOF

Предскажите: что теперь скажет git status?

git status
On branch main

No commits yet

Untracked files:
  (use "git add <file>..." to include in what will be committed)
	README.md
	index.html
	site.conf

nothing added to commit but untracked files present (use "git add" to track)

Файлы есть в папке, но Git их не отслеживает. Он даже подсказывает следующий шаг — git add.

Говорим, что сохранить, и пробуем сохранить

git add отмечает файлы для следующего коммита. Подробно о том, куда они при этом попадают, — в главе 2.

git add index.html site.conf README.md
git commit -m "Первая версия учебного сайта"

Если автор Git ещё не настроен, коммит не получится (при уже заданном авторе он сразу создастся):

Author identity unknown

*** Please tell me who you are.

Run

  git config --global user.email "you@example.com"
  git config --global user.name "Your Name"

to set your account's default identity.
Omit --global to set the identity only in this repository.

fatal: unable to auto-detect email address (got 'root@vm.(none)')

Последняя строка у вас будет со своим именем машины. Git записывает в каждый коммит автора, и ему нужно знать, кто вы.

Настраиваем автора только для этого репозитория

Подсказка Git предлагает --global — настройку для всех репозиториев на машине. В учебной работе так делать не нужно: можно случайно подписать учебным именем настоящие коммиты, или наоборот. Без --global настройка пишется только в .git/config этого репозитория. Имя и почта учебные: домен example.invalid специально зарезервирован и никуда не ведёт.

git config user.name "Анна (учебный)"
git config user.email "anna@example.invalid"
git config --show-origin user.name
file:.git/config	Анна (учебный)

--show-origin показывает, откуда взята настройка: из файла этого репозитория.

Первый коммит

Если коммит выше не создался, файлы уже отмечены — проверим. Если создался, повторный коммит без изменений не нужен:

git status
On branch main

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
	new file:   README.md
	new file:   index.html
	new file:   site.conf
git commit -m "Первая версия учебного сайта"
[main (root-commit) be0a128] Первая версия учебного сайта
 3 files changed, 15 insertions(+)
 create mode 100644 README.md
 create mode 100644 index.html
 create mode 100644 site.conf

be0a128 — начало хеша коммита, его уникального имени. У вас он будет другим: хеш зависит от автора и времени. root-commit значит «первый коммит в истории».

git log
commit be0a1281bbc16e505e02be6b2fbe75d2b36c8c61
Author: Анна (учебный) <anna@example.invalid>
Date:   Fri Oct 16 14:27:09 2026 +0300

    Первая версия учебного сайта
git status
On branch main
nothing to commit, working tree clean

working tree clean — в папке нет ничего, что отличалось бы от последнего коммита.

Где живёт история

ls -a
.
..
.git
README.md
index.html
site.conf

Вся история — в .git. Руками туда не заходим и ничего не правим. Если удалить .git, файлы останутся, а история и настройки репозитория исчезнут. Вне репозитория Git честно скажет, что следить не за чем:

cd ~ && git status
fatal: not a git repository (or any of the parent directories): .git

Практика: второй коммит

Вернитесь в репозиторий: cd ~/git-course/site. Исходное состояние — один коммит, working tree clean.

Добавьте страницу about.html отдельным коммитом с сообщением «Добавить страницу «О нас»». Содержимое:

<!doctype html>
<html lang="ru">
<head><meta charset="utf-8"><title>О нас</title></head>
<body>
<h1>О нас</h1>
<p>Учебный сайт курса «Git: основы».</p>
</body>
</html>

Перед каждой командой Git предскажите, что покажет git status --short — краткая форма статуса: одна строка на файл, слева двухбуквенный код.

Признаки успеха:

  • git log --oneline показывает два коммита, новый сверху;
  • git status — nothing to commit, working tree clean.
Подсказка 1

Шаги те же, что в разборе: создать файл → отметить его для коммита → сохранить коммит.

Подсказка 2

Файл создаётся так же, как index.html: cat > about.html <<'EOF' … EOF. Отметить — git add, сохранить — git commit -m "…".

Подсказка 3

В кратком статусе неотслеживаемый файл помечен ??, а отмеченный для коммита новый файл — A .

Решение — в answers/01-first-repo.md.

Если результат другой

  • fatal: not a git repository. Вы не в папке репозитория. pwd должен показать …/git-course/site.
  • Author identity unknown при коммите. Автор настроен в другом репозитории, а этот — новый. Повторите git config user.name … и git config user.email … в этой папке.
  • В git log одна строка, а git status показывает about.html под Untracked files. Вы выполнили git commit, но не git add: Git сохраняет только отмеченное. Коммит при этом не создался — Git ответил nothing added to commit but untracked files present.
  • Ветка называется master. Вы создали репозиторий без -b main. Для курса переименуйте: git branch -m main.

Проверка понимания

  1. Вы создали файл и сразу выполнили git commit -m "…". Что сохранится?
  2. Зачем в учебном репозитории настраивать автора без --global?

Ответы — в answers/01-first-repo.md.

Дальше: 2. Осмысленный коммит.

Проверка автора и источники

  • Воспроизведено: вся последовательность главы и практики в отдельном временном репозитории с пустой домашней папкой и без системных настроек Git — Git 2.43.0, Ubuntu 24.04, bash 5.2, LANG=C.UTF-8. Хеши, даты и имя машины в выводе — из этого запуска, у ученика будут другими.
  • При русской локали с установленными переводами Git может печатать сообщения по-русски; в курсе выводы на английском, в примерах этого курса.
  • Источники: git-init (-b, init.defaultBranch), git-config (уровни настроек, --show-origin), git-status (краткий формат), git-commit, RFC 2606 (зарезервированный домен .invalid).
Разбор и ответы — откройте после своей попытки

Практика

Папка: ~/git-course/site.

cat > about.html <<'EOF'
<!doctype html>
<html lang="ru">
<head><meta charset="utf-8"><title>О нас</title></head>
<body>
<h1>О нас</h1>
<p>Учебный сайт курса «Git: основы».</p>
</body>
</html>
EOF
git status --short
?? about.html

?? — файл неотслеживаемый.

git add about.html
git status --short
A  about.html

A в первой колонке — новый файл отмечен для коммита.

git commit -m "Добавить страницу «О нас»"
git log --oneline
f6d4ea3 Добавить страницу «О нас»
be0a128 Первая версия учебного сайта

Хеши у вас другие. git status → nothing to commit, working tree clean.

Воспроизведено: Git 2.43.0, Ubuntu 24.04.

Проверка понимания

  1. Ничего. Git сохраняет в коммит только отмеченное через git add. Для неотслеживаемого файла он ответит nothing added to commit but untracked files present и коммит не создаст.
  2. Настройка без --global действует только в этом репозитории. Учебное имя не попадёт в ваши настоящие проекты, а настоящее — в учебные. Проверить, откуда взята настройка: git config --show-origin user.name.

Прочитали и разобрались? Отметьте урок — прогресс сохранится в этом браузере.