2.1 Установка
Git - кроссплатформенный. Команды и поведение одинаковы на Windows, macOS и Linux. Различается только способ установки.
Linux
Пакет называется git. Поставить через системный менеджер
пакетов:
# Debian, Ubuntu
sudo apt update && sudo apt install git
# Fedora, RHEL
sudo dnf install git
# Arch
sudo pacman -S git
После установки проверить версию:
git --version
# git version 2.43.0
Цифры могут отличаться. Любая версия 2.30+ подойдёт без оговорок.
macOS
На macOS Git встроен - но это старая версия из Xcode Command Line Tools. Лучше поставить свежий:
# через Homebrew (рекомендуется)
brew install git
Windows
На Windows нативного Git нет, ставится отдельным дистрибутивом - Git for Windows. Он включает сам Git и эмулятор bash-окружения (Git Bash), потому что Git исторически - про Unix-команды.
Скачать с git-scm.com/download/win. Установщик предложит много опций - большинство значений по умолчанию правильные. Внимания заслуживают два:
- Default editor. По умолчанию предлагает Vim. Если Vim незнаком - поменять на VS Code, Notepad или Nano.
- Line endings. По умолчанию выставлено
Checkout Windows-style, commit Unix-style. Оставить.
2.1.1 Подводный камень: PowerShell vs Git Bash
На Windows есть соблазн запускать Git из PowerShell - всё-таки родная оболочка. Это работает, но изредка ломается на скриптах и hook-ах, написанных под Unix. Если что-то странно себя ведёт - повтори ту же команду в Git Bash. Часто разница именно в этом.
2.2 Первая настройка
Сразу после установки Git ничего не знает о тебе. У него нет имени и нет email-а, которые он мог бы поставить под коммитами. Без этого первый коммит не получится - Git откажется его делать.
Глобальная настройка делается один раз:
git config --global user.name "Имя Фамилия"
git config --global user.email "email@example.com"
Имя и email будут видны всем, кто получит твои коммиты. Если репозиторий публичный - это виден весь интернет.
Дополнительно полезно настроить:
git config --global core.editor "code --wait" # VS Code
git config --global init.defaultBranch main
git config --global color.ui auto
Эти настройки хранятся в файле ~/.gitconfig (на Windows - в
профиле пользователя). Это обычный текстовый файл.
2.2.1 Копнуть глубже: три уровня конфигурации
Флаг --global относится к текущему пользователю - ~/.gitconfig.
Есть ещё два уровня:
--system- для всех пользователей машины. Лежит в/etc/gitconfig(Linux/macOS) илиC:\ProgramData\Git\config(Windows). Редко нужен.--local(по умолчанию, если флаг не указан) - только для текущего репозитория. Лежит в.git/configвнутри репо.
Более узкий уровень перекрывает более широкий. Это удобно, когда работа разделена на личные и рабочие проекты.
2.3 Создание репозитория
Репозиторий в Git - это директория с особым подкаталогом .git/.
Этот подкаталог - мозг репозитория. В нём история, конфигурация,
объекты, ссылки. Без .git/ директория не репозиторий, а просто
папка с файлами.
Превратить директорию в репозиторий - одной командой:
mkdir my-portfolio
cd my-portfolio
git init
# Initialized empty Git repository in /home/user/my-portfolio/.git/
Команда git init создаёт подкаталог .git/ внутри текущей
директории. Файлы в самой директории не трогаются - они
становятся «рабочим деревом» (working tree) этого репозитория.
Этот набор разберётся подробно в главе 3. Сейчас - оставить как есть и продолжать.
2.4 Три состояния файла
В Git каждый файл в директории может быть в одном из трёх состояний:
- Untracked - файл существует, но Git ничего о нём не знает.
Это значение по умолчанию для всего, что появилось в рабочем
дереве.
- Modified - файл уже отслеживается (то есть когда-то был закоммичен), но с тех пор изменился, и изменения ещё не зафиксированы.
- Staged - изменения подготовлены к попаданию в следующий коммит. Это особое состояние, его проще всего понять через пример.
Узнать состояние всех файлов в текущей директории - git status.
Это самая часто используемая команда после git log. Её стоит
запускать постоянно.
В свежем репозитории:
git status
# On branch main
#
# No commits yet
#
# nothing to commit (create/copy files and use "git add" to track)
Создадим первый файл - README.md:
echo "# Моё портфолио" > README.md
git status
# ...
# Untracked files:
# README.md
Файл появился - Git его видит, но в категории «untracked». Чтобы Git начал его отслеживать, нужно его проиндексировать:
git add README.md
git status
# ...
# Changes to be committed:
# new file: README.md
Теперь файл в состоянии staged. Git готов положить его в следующий коммит.
См. add, status и working-tree.
2.5 Первый коммит
Коммит - это снимок состояния всех проиндексированных файлов плюс метаданные: автор, время, сообщение.
git commit -m "Первый коммит: README"
# [main (root-commit) a1b2c3d] Первый коммит: README
# 1 file changed, 1 insertion(+)
Что произошло:
[main (root-commit) a1b2c3d]- в веткеmainсоздан root commit (первый коммит, у него нет родителя), его сокращённый SHA -a1b2c3d.1 file changed, 1 insertion(+)- затронут один файл, добавлена одна строка.
SHA - это идентификатор коммита, 40 символов в полной форме, обычно показывается первыми 7 для краткости. О том, почему именно SHA и как он считается - в главе 3.
Проверить:
git log --oneline
# a1b2c3d Первый коммит: README
git status
# On branch main
# nothing to commit, working tree clean
2.6 Цикл: правка → add → commit
Дальше всё повторяется. Базовый цикл работы в Git состоит из трёх шагов:
┌──────────────┐
│ правишь │
│ файлы в │
│ редакторе │
└──────┬───────┘
│
▼
┌──────────────┐
│ git add │
└──────┬───────┘
│
▼
┌──────────────┐
│ git commit │
└──────────────┘
В лабе ниже - пятикратно повторяющийся цикл на конкретном примере.
2.7 Что делает git add на самом деле
В пункте 2.4 staged представлено как «готов к коммиту». Это
верно, но недостаточно. Точнее: git add копирует текущее
состояние файла в особую область, которая называется индекс
(index) или staging area. Коммит делает снимок именно с
индекса, а не с рабочего дерева.
Это важно. Если изменить файл, добавить его (git add), потом
снова изменить - в коммит попадёт то состояние, которое было на
момент add. Текущие правки в файл - нет.
echo "версия 1" > file.txt
git add file.txt
echo "версия 2" > file.txt # перезаписали после add
git commit -m "что попадёт в коммит?"
# в коммите будет "версия 1"
Эта особенность даёт мощный приём - staging by hunks: можно
положить в коммит только часть изменений из файла через git add -p. Подробно индекс разбирается в главе 5.
2.8 Два главных окна в Git
Через всю работу в Git проходят две команды:
git status - что прямо сейчас. Запускать постоянно.
Стоимость нулевая, информации много.
git log - что было раньше. Список коммитов в обратном
порядке (новые сверху).
Полезные варианты git log:
git log --oneline # одна строка на коммит
git log --oneline --graph --decorate --all # с графиком ветвлений
git log -5 # последние пять
git log --author="Имя" # по автору
git log --follow index.html # по файлу
git log -p # с дельтами
2.9 Что делать, если ошибся
Тема разбирается отдельно в главе 9, но три самых частых сценария - здесь.
Опечатка в сообщении последнего коммита:
git commit --amend -m "Новое сообщение"
Перезапишет последний коммит. Старый SHA исчезнет, появится
новый. Если коммит уже отправлен на сервер - --amend опасен.
Случайно добавил не тот файл:
git restore --staged secret.txt
# или в старом стиле:
git reset HEAD secret.txt
Выкинуть правки в файле и вернуть как было:
git restore index.html
Команда git restore . восстановит все непроиндексированные
файлы из последнего коммита, выкинув все текущие правки. Это
безвозвратно.
Уроки в sandbox
lab-2.1. Первые пять коммитов
Цель: построить базу сайта-портфолио. К концу должно быть пять коммитов и работающее рабочее дерево из трёх файлов.
Создай директорию
my-portfolio, перейди в неё, инициализируй репозиторий:mkdir my-portfolio && cd my-portfolio && git init.Создай файл
index.htmlс минимальным HTML5-каркасом (DOCTYPE, html, head с charset, title 'Моё портфолио', body с h1 'Привет'). Закоммить с сообщением"Добавлен index.html".Создай файл
style.cssпустым с комментарием/* стили будут позже */. Закоммить с сообщением"Добавлен пустой style.css".В
index.htmlподключиstyle.cssчерез<link rel="stylesheet" href="style.css">между<head>и</head>. Закоммить:"index.html подключает style.css".В
style.cssдобавь базовые стили:body { font-family: system-ui, sans-serif; max-width: 720px; margin: 2rem auto; padding: 0 1rem; }иh1 { color: #2a2a2a; }. Закоммить:"Базовые стили: типографика, центрирование".Создай
README.mdс описанием проекта на свободную тему (2-3 строки). Закоммить:"README с описанием проекта".Проверь результат через
git log --oneline- должно быть пять строк. Откройindex.htmlв браузере, должна отобразиться страница с заголовком и стилями.
Резюме
- Git ставится одной командой на любой ОС. Любая версия 2.30+ подходит.
- Перед первой работой настраиваются user.name и user.email через git config --global.
- Репозиторий создаётся через git init - добавляет подкаталог .git/.
- Каждый файл бывает в одном из трёх состояний: untracked, modified, staged.
- Цикл работы: правка → git add → git commit.
- Две команды используются постоянно: git status (что сейчас) и git log (что было).
Контрольные вопросы
Если запустить `git init` в уже существующей директории с файлами - что произойдёт с файлами? Что появится нового?
Показать ответ
Существующие файлы остаются нетронутыми -
git initих не читает и не модифицирует. Появляется подкаталог.git/с пустым набором objects/ и refs/. Файлы в директории становятся untracked - Git их видит, но не отслеживает, пока не сделатьgit add.В чём разница между *untracked* и *modified*? Может ли файл одновременно быть в двух состояниях?
Показать ответ
Untracked - Git ничего не знает про файл, он не попадал ни в один коммит. Modified - Git знает файл (он есть в индексе или в HEAD-tree), и его содержимое отличается от того, что в HEAD. Это взаимоисключающие состояния: untracked → закоммитили → tracked. Tracked файл может быть unchanged, modified или staged.
Сделан `git add file.txt`, потом файл снова изменён, потом `git commit`. Какая версия попадёт в коммит?
Показать ответ
Версия, которая была на момент
git add. Командаaddкопирует состояние файла в индекс; коммит снимает снимок именно с индекса. Текущие правки послеaddостаются в рабочем дереве, они не закоммичены иgit statusпокажет файл как modified.Какой смысл указывать user.name и user.email глобально, если их видно в коммитах? Когда стоит переопределить локально?
Показать ответ
Восстанавливает все непроиндексированные файлы из последнего коммита (HEAD). Все текущие правки в рабочем дереве - пропадают без возможности восстановления (если они не были закоммичены и не лежали в индексе). Перед запуском убедиться, что в правках нет ничего важного.