Как работать с Git?
Перед этой главой — Установка и настройка Git.
Дальше — Ветвление и слияние, Рекомендации в команде, справочник по симптомам — Типовые ситуации.
Карта раздела — о разделе 4.13. push, pull, ветки и остальные команды из ежедневного цикла — в 12 команд на каждый день.
Готовые блоки команд — лабораторная шпаргалка сценариев.
Практика выкладки после push — кейс GitHub Pages.
Как работать с Git?
Git в повседневной работе — это повторяемый цикл: правки в файлах → осознанный выбор, что войдёт в снимок → коммит с понятным сообщением → обмен с удалённым репозиторием. Ниже — тот же цикл, что вы уже видели в GitHub Desktop, но с терминалом и с пояснением четырёх уровней — от папки проекта до GitHub (схема цепочки команд).
Работа с Git строится по определённому алгоритму:
Play ITЗагрузка интерактивного демо…
Play ITЗагрузка интерактивного демо…
Четыре уровня — от папки проекта до GitHub
Проект на диске, индекс, локальная история и копия на сервере — разные "этажи". Команды Git переносят изменения между ними. git push отправляет ваши коммиты на GitHub (или другой хостинг). git pull подтягивает обновления с сервера и сразу обновляет файлы в папке проекта. git fetch тоже забирает новое с сервера, но не трогает рабочие файлы — только локальную историю.
| Уровень | Где это | Смысл |
|---|---|---|
| Рабочее пространство | папка проекта (src/, README.md…) | правите файлы в редакторе |
| Индекс (staging) | .git/index | черновик следующего коммита — что войдёт в снимок |
| Локальный репозиторий | .git/objects, ветки в .git/refs | сохранённая история на вашем ПК |
| Удалённый репозиторий | GitHub, GitLab, origin на сервере | общая копия для команды и CI |
Отправить изменения "вверх" (к команде):
| Команда | Откуда → куда | Зачем |
|---|---|---|
git add | рабочее пространство → индекс | подготовить правки к сохранению |
git commit | индекс → локальный репозиторий | зафиксировать снимок с сообщением |
git push | локальный репозиторий → удалённый | передать коммиты на сервер; коллеги и пайплайны увидят ветку |
Получить изменения "вниз" (с сервера):
| Команда | Откуда → куда | Зачем |
|---|---|---|
git fetch | удалённый → только локальный репозиторий | узнать, что появилось на GitHub, без правки файлов в проекте |
git pull | удалённый → рабочее пространство | подтянуть обновления и влить их в текущую ветку (fetch + слияние) |
fetch — "скачать новости с сервера, файлы в IDE пока не трогать". pull — "скачать и сразу влить в мою ветку и рабочую копию".
Если не уверены, что придёт с сервера, сначала git fetch origin, посмотрите git log HEAD..origin/main, затем осознанно merge или rebase — см. ниже.
Локально Git ещё разделяет рабочую копию, индекс и HEAD — удобно смотреть через git status и git diff:
| Область | Где хранится | Посмотреть | Изменить |
|---|---|---|---|
| Рабочая копия | файлы в папке проекта | git status, git diff | редактор, git restore <file> |
| Индекс (staging) | .git/index | git diff --staged | git add, git restore --staged |
| Репозиторий (HEAD) | объекты в .git/objects | git log, git show | git commit |
Коммит — это снимок всех отслеживаемых файлов, подготовленных в индексе, а не "сохранение по одному файлу".
Ежедневный цикл разработчика
У большинства VCS схожий стереотип работы — отличия в командах, но логика одна:
| Шаг | Действие | В Git | Зачем |
|---|---|---|---|
| 1 | Получить проект | git clone / git checkout | Рабочая копия на диске |
| 2 | Обновить копию | git pull / git fetch + merge | Свести расхождение с общей версией, снизить риск конфликтов |
| 3 | Править файлы | редактор, IDE | Локально, без сети |
| 4 | Зафиксировать | git add → git commit | Сохранить снимок с сообщением "что и зачем" |
| 5 | Обменяться | git push | Передать коммиты команде или на CI — шпаргалка |
Пока коллеги вносят правки в общую ветку, ваша рабочая копия устаревает — расхождение растёт, выше шанс конфликта при слиянии. Поэтому pull (или fetch перед rebase) делают регулярно, а не только перед релизом. VCS может требовать обновления перед commit; в Git это политика команды и настройки сервера, а не жёсткое правило клиента.
Крупные задачи оформляют веткой — промежуточные коммиты живут там, пока фича не готова к merge в main. Подробнее — в Ветвление и слияние.
Тот же сценарий, что в первой главе — через CLI
Повторим путь из главы про GitHub Desktop, но в терминале (после установки Git):
mkdir my-demo && cd my-demo
git init
echo "Hello" > test.txt
git status # untracked: test.txt
git add test.txt
git status # staged: test.txt
git commit -m "Первый коммит"
Если репозиторий уже создан на GitHub, привяжите remote и отправьте ветку (имя main задаётся при git config init.defaultBranch main):
git remote add origin https://github.com/USER/my-demo.git
git branch -M main
git push -u origin main
Флаг -u запоминает связь: дальше достаточно git push и git pull из этой ветки. Тот же сценарий с таблицей по каждой строке — лаборатория "залить на GitHub".
1. Выбор директории
Выбираем директорию - папку, где находится проект.
Обычно это корень проекта (там же, где package.json, .sln, pyproject.toml или хотя бы README). Git хранит историю для всей папки и подпапок внутри неё; не стоит инициализировать репозиторий в C:\Users\... — только в каталоге одного продукта. Если клонировали чужой проект с GitHub, этот шаг уже сделан: папка клона и есть рабочая копия.
2. Инициализация
Инициализируем репозиторий - говорим Git, что эта папка теперь будет под его контролем. Репозиторий на нашем компьютере будет локальным, а на сервере (в облаке) - удалённым.
Команда git init создаёт скрытую папку .git — в ней объекты, ветки, настройки. Пока вы не сделали git add и git commit, истории коммитов ещё нет, но Git уже "ведёт" каталог. Удалённый репозиторий (GitHub/GitLab) появляется позже: git remote add origin … привязывает имя origin к URL на сервере. Один локальный клон может иметь несколько remote (например, origin и форк upstream) — это тема ветвления.
3. Изменение и работа
Изменяем файлы (собственно, работаем).
Git умеет отслеживать состояние каждого файла в проекте. Файлы проходят через состояния:
- Неотслеживаемый (untracked) — файл есть на диске, Git о нём ещё не ведёт учёт (новый файл, не попавший в репозиторий).
- Модифицированный (modified) — Git знает файл, вы его изменили после последнего коммита, но в индекс изменения ещё не попали.
- Индексированный (staged) — вы явно отметили версию для следующего коммита (
git add, отмена из индекса —git restore --staged):
git add test.txt
git restore --staged test.txt
- Зафиксированный (committed) — снимок сохранён в истории; рабочая копия может снова уйти в modified, если вы продолжите правки.
git statusБлок Changes to be committed — staged (попадёт в следующий commit).
Changes not staged — modified, но не в индексе.
Untracked files — Git ещё не отслеживает. Цвета и формулировки зависят от терминала; смысл всегда один.
4. Индекс
Добавляем файлы в индекс (Stage) - выбираем, какие именно изменения мы хотим сохранить. Git не автоматически отслеживает все изменения. Нужно явно сказать ему: "Я хочу сохранить эти файлы" — сначала добавляя их в индекс (stage), а затем делая коммит. К примеру, если мы изменили три файла - test.html, test.js и test.css, но хотим отправить изменения только двух файлов - test.html, test.js. Тогда мы только их и добавляем в индекс, промежуточную зону, куда мы складываем те изменения, которые хотим зафиксировать в следующем коммите.
Выборочный stage и просмотр последнего коммита
Иногда в одном файле смешаны две задачи. Команда git add -p (patch) предлагает по очереди фрагменты diff и спрашивает, включать ли их в индекс:
git add -p src/utils.ts
git diff --staged # что попадёт в следующий коммит
git commit -m "Часть 1: валидация"
# оставшиеся правки останутся modified — снова add -p или git add
Забыли файл в только что созданном коммите (ещё без push):
git add пропущенный.ts
git commit --amend --no-edit
Посмотреть, что вошло в последний коммит:
git show HEAD --stat
git show HEAD # полный diff
| Отменить… | Команда |
|---|---|
| Правки в файле (не в индексе) | git restore путь/к/файлу |
| Только из индекса | git restore --staged путь/к/файлу |
| Последний коммит, правки оставить staged | git reset --soft HEAD~1 |
Развернутые сценарии (stash, неверная ветка, отклонённый push) — в главе Типовые ситуации с Git. Те же ситуации короткими блоками команд с построчным разбором — лаборатория 1123 (ежедневный цикл, push отклонён, stash).
5. Коммит
Делаем коммит - фиксируем изменения с описанием того, что мы сделали. Коммит — это моментальная "фотография" состояния проекта в определённый момент времени.
Снимок в истории всегда собирается в два шага: git add (что войдёт в снимок) → git commit (записать снимок с сообщением).
Пропустить add нельзя — иначе правки останутся только в рабочей копии.
Зоны Git на схеме — в архитектуре Git (8.03) и в четырёх уровнях выше.
К этой "фотографии" мы добавляем подпись (сообщение), указав, к примеру "Исправил баг с кнопкой запуска". Это поможет нам через месяц, чтобы вспомнить, зачем сделан именно этот коммит.
Даты коммита — author и committer
Помимо сообщения Git сохраняет две метки времени (см. портфолио и календарь GitHub — зачем это важно для профиля):
| Поле | Кто задаёт | Типичный смысл |
|---|---|---|
| Author date | автор правок | когда изменение сделано |
| Committer date | тот, кто записал коммит в историю | момент commit, rebase, cherry-pick |
По умолчанию обе даты совпадают с моментом git commit. Явно задать author date:
git commit -m "docs: README" --date="2024-04-20T12:00:00"
Чтобы author и committer совпали (миграция, перенос зеркала):
export GIT_AUTHOR_DATE="2024-04-20T12:00:00"
export GIT_COMMITTER_DATE="2024-04-20T12:00:00"
git commit -m "docs: README"
Посмотреть обе даты в логе:
git log --format=fuller -1
Переписать даты у коммитов, которые уже на сервере, можно только изменением истории (rebase, filter-repo) с новыми хешами; на общих ветках это согласуют с командой. Подмена дат ради "зелёного" календаря на GitHub не даёт навыков и рискована на собеседовании — см. карьерный разбор по ссылке выше.
6. Fetch, pull и push
Схема четырёх уровней и направлений команд — выше. Здесь — те же три команды с примерами в терминале.
Push — отправка локальных коммитов на удалённый репозиторий. Fetch — скачать коммиты с сервера, не меняя рабочие файлы. Pull — fetch + слияние в текущую ветку (файлы в проекте обновляются). Таблица "12 команд" — в шпаргалке.
git fetch origin
git pull origin main
git push origin main
Когда и зачем делать git fetch
git fetch обновляет удалённые ссылки (например, origin/main, origin/feature-x), но не трогает ваши файлы и индекс. Это безопасный "шаг проверки обстановки" перед merge/rebase.
Практический сценарий перед интеграцией:
git fetch origin
git log --oneline --decorate --graph --all -15
git switch feature/my-task
git merge origin/main
# или: git rebase origin/main
Что полезно запомнить:
-
git fetch origin— получить обновления с конкретного remote;Скачиваются коммиты и обновляются ссылки вроде
origin/main, но ваши файлы в рабочей копии не меняются. Удобно "подглядеть", что появилось на сервере, перед merge. -
git fetch --all --prune— обновить все remotes и убрать удалённые на сервере ветки изrefs/remotes/*;После переименования или удаления ветки на GitHub локальные
origin/feature-oldмогут висеть мёртвым грузом —--pruneих убирает. -
после
fetchсравнивайтеHEADиorigin/ваша-ветка, чтобы понимать, что именно придёт при pull/push.Команда
git log HEAD..origin/mainпоказывает коммиты, которые вы ещё не влили;git log origin/main..HEAD— что уйдёт на сервер приpush.
Типичная ошибка новичка — сразу делать pull, не понимая, что он ещё и сливает изменения. Если не уверены, сначала fetch, потом осознанно merge или rebase.
Remote-tracking ветки и upstream
После git clone или git fetch Git хранит зеркала веток с сервера в каталоге refs/remotes/ — их называют remote-tracking ветками. Имя обычно origin/main, origin/feature-x: это не ваши локальные ветки, а "где сейчас ветка на origin".
| Что видите | Что это | Как обновляется |
|---|---|---|
main | локальная ветка, на которой вы стоите | commit, merge, rebase |
origin/main | снимок main на сервере после последнего fetch/pull | git fetch origin (и часть pull) |
HEAD | текущая позиция (ветка или коммит) | switch, commit |
Связь "моя ветка следит за remote" задаётся при первом push:
git push -u origin feature/login
Флаг -u (--set-upstream) запоминает пару: локальная feature/login ↔ origin/feature/login. Дальше достаточно git push и git pull без имени ветки.
Полезные команды:
git branch -vv # локальные ветки и их upstream
git status # «Your branch is ahead/behind 'origin/main' by N commits»
git pull # fetch + влить upstream текущей ветки
git pull --rebase # то же, но rebase вместо merge (если так принято в команде)
Upstream — та remote-tracking ветка, с которой связана ваша локальная. Если upstream не задан, git push / git pull без аргументов выдадут подсказку с -u. На форке оригинал часто называют upstream, свой клон — origin — см. форк в 113.
Трёхстороннее слияние при расхождении с origin — в Ветвление и слияние.
Ежедневный цикл в команде (типовой день)
Схема повторяется изо дня в день, когда ветка уже создана и remote настроен:
git switch feature/TASK-123-short-title
git pull --rebase origin main # подтянуть общую ветку (регламент команды может отличаться)
# ... правки в IDE ...
git status
git add src/ tests/
git commit -m "TASK-123: валидация email при регистрации"
git push origin feature/TASK-123-short-title
На GitHub/GitLab открываете pull request или merge request — ревью, CI, слияние. Подробно про ветки, конфликты и PR — в Ветвление и слияние; сравнение merge и rebase при подтягивании main — в том же разделе. Про сообщения коммитов и процесс — в Рекомендации в команде.
| Ситуация | Что сделать |
|---|---|
Забыли pull перед работой | git fetch, затем merge/rebase по правилам команды |
push отклонён (non-fast-forward) | Сначала интегрировать удалённые коммиты, потом снова push — см. Типовые ситуации |
| Нужно спрятать незакоммиченное | git stash push -m "WIP: TASK-123" |
| Случайно правили не в той ветке | перенос в другую ветку |
Опасные команды (reset --hard, push --force) — только по регламенту; см. стоп-лист.
Сообщение коммита — зачем оно важно
Коммит — не только снимок файлов, но и запись для будущего вас и ревьюера. Минимально полезный шаблон:
TASK-123: кратко что сделано
Почему: ограничение API / баг из тикета.
Как проверить: запустить тест X, открыть /register.
Соглашения в команде могут требовать номер задачи, тип (fix:, feat:) или язык — уточняйте у лида. Разбор стиля — в Рекомендации в команде.
Локальный репозиторий и .gitignore
Перед первым git add проверьте, что в коммит не попадут артефакты сборки и секреты. Шаблоны под стек — в .gitignore (раздел 4.13). Секрет, уже попавший в историю, нельзя "просто удалить файлом" — см. Типовые ситуации — секрет в Git.
Ветки и запросы на слияние
Когда базовый цикл add → commit → push освоен, следующий обязательный слой — ветки и pull request / merge request на сервере: так команда видит изменения до слияния в общую ветку. Пошагово, с примерами команд и разбором конфликтов — в статье Ветвление и слияние в Git. Отдельный гайд по diff, ревью и первому PR — Код-ревью и pull request. Жёстко регламентированные схемы веток (GitFlow, релизы) — в разделе 8.03.
Рекомендую читать дальше
| Тема | Статья |
|---|---|
| 12 команд — карманный набор | Справочник-шпаргалка по Git — шпаргалка |
Установка, user.name, клиенты | Установка и настройка Git — Установка и настройка |
| Ветки, PR, конфликты | Ветвление и слияние в Git — Ветвление |
| Ошибки и восстановление | Типовые ситуации с Git — Типовые ситуации |
| Внутреннее устройство Git | 8.03 — Архитектура Git |
| Процесс разработки с Git в команде | Процесс разработки ПО |
| Интерактивный тренажёр | Learn Git Branching |