Git без мистики: рабочая шпаргалка

Что такое Git на практике

Git — это распределённая система контроля версий. Слово «распределённая» важно: когда вы делаете git clone, к вам на компьютер приезжает не просто последняя версия файлов, а почти вся история проекта. Поэтому git log, git diff, переключение веток и коммиты работают локально, даже без интернета. Сервер вроде GitHub — это не «главный Git», а общий узел синхронизации, через который команда обменивается коммитами.

Git хранит проект не как папку с кнопкой «сохранить», а как цепочку снимков состояния. Каждый commit указывает на предыдущий commit, поэтому получается история: что было раньше, что изменилось потом и от какой точки выросла ветка. Внутри Git есть специальная папка .git; именно там лежит история, настройки репозитория, ссылки на ветки и служебные данные. Если удалить .git, обычные файлы останутся, но проект перестанет быть Git-репозиторием.

Полезно думать так: файлы в редакторе — это черновик, commit — осмысленная точка в истории, branch — подвижная метка на одном из коммитов, а HEAD — указатель на то место, где вы сейчас находитесь. Большая часть «магии» Git становится проще, если помнить, что команды обычно двигают эти указатели или создают новые снимки, а не делают что-то непредсказуемое с проектом.

Git нужен не для того, чтобы «сохранять файлы», а чтобы уверенно отвечать на три вопроса: что изменилось, что я хочу сохранить как осмысленный шаг и как синхронизировать этот шаг с командой. Если держать в голове эту модель, команды перестают быть набором заклинаний.

Базовая схема такая: рабочая папка — это файлы, которые вы редактируете; stage, или индекс, — черновик будущего коммита; commit — зафиксированный снимок; remote — удалённый репозиторий, например на GitHub или GitLab.

flowchart LR A[Рабочая папка<br/>редактируете файлы] -->|git add| B[Stage / индекс<br/>черновик коммита] B -->|git commit| C[Локальная история<br/>commit] C -->|git push| D[Remote<br/>GitHub / GitLab] D -->|git fetch| E[Ссылки origin/*<br/>знание о сервере] D -->|git pull| A E -.->|merge или rebase| A
flowchart LR
    A[Рабочая папка<br/>редактируете файлы] -->|git add| B[Stage / индекс<br/>черновик коммита]
    B -->|git commit| C[Локальная история<br/>commit]
    C -->|git push| D[Remote<br/>GitHub / GitLab]
    D -->|git fetch| E[Ссылки origin/*<br/>знание о сервере]
    D -->|git pull| A
    E -.->|merge или rebase| A
Базовый поток Git: изменения проходят через stage, становятся коммитом и только потом отправляются на remote.

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

Один раз на машине задайте имя и email. Они попадут в авторство коммитов:

git config --global user.name "Ivan Petrov"
git config --global user.email "ivan@example.com"
git config --global init.defaultBranch main

Проверить настройки:

git config --list

Создать репозиторий в текущей папке:

git init

Скачать существующий проект:

git clone https://github.com/user/project.git

Ежедневный цикл: status, diff, add, commit

Самая полезная команда в Git — не commit, а status. Запускайте её постоянно: перед add, перед commit, перед push, перед любым рискованным действием.

git status

Посмотреть, что именно изменено, но ещё не добавлено в stage:

git diff

Посмотреть, что уже попадёт в следующий коммит:

git diff --staged

Добавить один файл:

git add src/app.js

Добавить все изменения в текущей папке:

git add .

Точечно выбрать куски файла, если в нём смешались разные задачи:

git add -p

Сделать коммит:

git commit -m "Fix login redirect"

Хорошее сообщение коммита отвечает на вопрос «что изменилось по смыслу?», а не «какие файлы тронуты?». Update files почти бесполезно. Fix empty search state уже помогает через месяц понять историю.

Ветки: безопасное место для работы

switch и checkout: почему есть две команды

В старых гайдах по Git вы часто увидите checkout вместо switch:

git checkout main
git checkout -b feature/search-empty-state

Это не ошибка. git checkout — старая универсальная команда: ей переключали ветки, создавали ветки, откатывали файлы к версии из коммита и доставали отдельные файлы из истории. Из-за этого она перегружена: одна команда делает несколько разных по смыслу вещей.

Чтобы снизить путаницу, в Git появились более явные команды: git switch для переключения веток и git restore для восстановления файлов. Поэтому в повседневной работе лучше писать так:

git switch main
git switch -c feature/search-empty-state
git restore src/app.js

Практическое правило простое: если вы переходите между ветками — используйте switch; если возвращаете файл к старому состоянию — restore; если читаете легаси-инструкцию с checkout, мысленно уточняйте, что именно она делает. Например, git checkout main сейчас лучше заменить на git switch main, а git checkout -- src/app.js — на git restore src/app.js.

Ветка — это указатель на линию разработки. Для новой задачи обычно лучше не работать прямо в main:

git switch -c feature/search-empty-state

Посмотреть ветки:

git branch

Переключиться:

git switch main

Слить готовую ветку в текущую:

git merge feature/search-empty-state

Если нужно подтянуть main в свою ветку аккуратной линейной историей, часто используют rebase:

git switch feature/search-empty-state
git fetch origin
git rebase origin/main

Практическое правило: rebase удобен для своей локальной ветки; не переписывайте историю общей ветки, если другие люди уже от неё работают.

Remote: fetch, pull, push

origin — стандартное имя удалённого репозитория. Проверить remote:

git remote -v

Скачать информацию с сервера, но не менять ваши файлы:

git fetch origin

Скачать и сразу применить изменения к текущей ветке:

git pull

Отправить вашу ветку первый раз:

git push -u origin feature/search-empty-state

Дальше обычно достаточно:

git push

Если Git просит pull перед push, значит на сервере есть коммиты, которых у вас нет. Не делайте push --force на автомате. Сначала git fetch, git status, затем решайте: merge, rebase или обсудить с командой.

Отмена без паники

Главное различие: вы хотите убрать изменение из stage, отменить изменение в файле или отменить уже созданный коммит?

Убрать файл из stage, но оставить правки в рабочей папке:

git restore --staged src/app.js

Выкинуть локальные незакоммиченные правки в файле:

git restore src/app.js

Это опасно: изменения в файле пропадут. Перед запуском проверьте git diff.

Исправить последний коммит, если забыли файл или ошиблись в сообщении:

git add forgotten-file.js
git commit --amend

Создать новый коммит, который отменяет старый, безопасно для общей истории:

git revert <commit>

Посмотреть журнал действий, если кажется, что «всё потерялось»:

git reflog

reflog часто спасает после неудачного reset или rebase, потому что показывает, где раньше был HEAD.

Stash: временно убрать незавершённую работу

Если нужно срочно переключиться на другую ветку, а текущие правки ещё рано коммитить:

git stash push -m "wip search form"

Вернуть последнюю заначку:

git stash pop

Посмотреть список:

git stash list

Не превращайте stash в долгосрочное хранилище. Если работа важна, лучше сделать черновой коммит в отдельной ветке.

Конфликты: что делать по шагам

Конфликт — не авария, а ситуация, где Git не может сам выбрать между двумя изменениями. Откройте файлы с конфликтами и найдите маркеры:

<<<<<<< HEAD
ваша версия
=======
версия из другой ветки
>>>>>>> feature

Оставьте правильный итоговый текст без маркеров, затем:

git add conflicted-file.js
git status
git commit

При rebase вместо git commit обычно будет:

git rebase --continue

Если запутались во время rebase:

git rebase --abort

Частые ошибки

Не коммитьте секреты: .env, токены, приватные ключи. Добавьте такие файлы в .gitignore до первого коммита.

Не используйте git reset --hard как «почистить проект», пока не понимаете, что именно потеряете. Сначала git status и git diff.

Не делайте огромные коммиты «за весь день». Лучше несколько небольших коммитов: один смысл — один коммит. Так проще ревьюить, откатывать и искать причину бага.

Не путайте fetch и pull: fetch только обновляет знание о сервере, pull ещё и меняет текущую ветку.

Мини-практика на 10 минут

Создайте папку git-practice, выполните git init, добавьте файл notes.md, сделайте первый коммит. Затем создайте ветку experiment, измените файл, сделайте второй коммит, вернитесь в main и слейте ветку через git merge experiment. На каждом шаге запускайте git status и один раз посмотрите историю:

git log --oneline --graph --all

Запомните короткую рабочую привычку: status -> diff -> add -> diff --staged -> commit -> push. Эта цепочка закрывает большую часть повседневной работы с Git и резко снижает шанс сделать что-то вслепую.

Beginner Git commands you need to know (WITH EXAMPLES) - Официальный ролик GitHub показывает те же базовые команды на реальных примерах; удобно смотреть после чтения шпаргалки.
Quick recall
Зачем в повседневной работе с Git постоянно запускать `git status` перед `add`, `commit`, `push` и рискованными командами?

Sources

  1. Git Reference
  2. Git Cheat Sheet
  3. git-status Documentation
  4. git-restore Documentation
  5. git-pull Documentation
  6. Top 12 Git commands every developer must know
  7. Beginner Git commands you need to know (WITH EXAMPLES)