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

Как работать с Git?

Разработчику Архитектору Инженеру
Где вы в разделе про 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 и pull

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/indexgit diff --stagedgit add, git restore --staged
Репозиторий (HEAD)объекты в .git/objectsgit log, git showgit commit

Коммит — это снимок всех отслеживаемых файлов, подготовленных в индексе, а не "сохранение по одному файлу".


Ежедневный цикл разработчика

У большинства VCS схожий стереотип работы — отличия в командах, но логика одна:

ШагДействиеВ GitЗачем
1Получить проектgit clone / git checkoutРабочая копия на диске
2Обновить копиюgit pull / git fetch + mergeСвести расхождение с общей версией, снизить риск конфликтов
3Править файлыредактор, IDEЛокально, без сети
4Зафиксироватьgit addgit 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 путь/к/файлу
Последний коммит, правки оставить stagedgit 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 — скачать коммиты с сервера, не меняя рабочие файлы. Pullfetch + слияние в текущую ветку (файлы в проекте обновляются). Таблица "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/pullgit fetch origin (и часть pull)
HEADтекущая позиция (ветка или коммит)switch, commit

Связь "моя ветка следит за remote" задаётся при первом push:

git push -u origin feature/login

Флаг -u (--set-upstream) запоминает пару: локальная feature/loginorigin/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.


Ветки и запросы на слияние

Когда базовый цикл addcommitpush освоен, следующий обязательный слой — ветки и pull request / merge request на сервере: так команда видит изменения до слияния в общую ветку. Пошагово, с примерами команд и разбором конфликтов — в статье Ветвление и слияние в Git. Отдельный гайд по diff, ревью и первому PRКод-ревью и pull request. Жёстко регламентированные схемы веток (GitFlow, релизы) — в разделе 8.03.


Рекомендую читать дальше

ТемаСтатья
12 команд — карманный наборСправочник-шпаргалка по Git — шпаргалка
Установка, user.name, клиентыУстановка и настройка Git — Установка и настройка
Ветки, PR, конфликтыВетвление и слияние в Git — Ветвление
Ошибки и восстановлениеТиповые ситуации с Git — Типовые ситуации
Внутреннее устройство Git8.03 — Архитектура Git
Процесс разработки с Git в командеПроцесс разработки ПО
Интерактивный тренажёрLearn Git Branching