В общем решил так же написать шпаргалку по Git, т.к часто многое вылетает из головы между сессиями и кодинга, так же в конце прикрепил правила оформления коммитов для себя, возможно вам тоже поможет в сопровождении своих проектов, т.к недавно обновил документ по командам OpenSUSE с коммитом "chore(docs): update bla bla bla", в общем не делайте так, делайте правильно.

Базовые команды

git init                        # создать репозиторий в текущей папке
git clone <url>                 # склонировать существующий
git status                      # что вообще происходит: что изменено, что staged
git status --short              # то же самое, но одной строкой на файл — быстрее читать
git add <file>                  # добавить файл в staging (подготовить к коммиту)
git add .                       # добавить всё изменённое и новое в текущей папке
git add -A                      # добавить вообще всё по всему репозиторию
git commit -m "сообщение"       # закоммитить staged-изменения
git push                        # отправить коммиты в origin
git pull                        # забрать и применить изменения из origin (fetch + merge)

Что важно помнить про add: если просто сделал git commit -a, staged будут только отслеживаемые файлы. Новые файлы без git add в коммит не попадут. Я вечно про это забываю.

Ветки

git branch                      # показать локальные ветки
git branch -a                   # показать вообще все (и remote тоже)
git branch <name>               # создать ветку, но НЕ переключиться в неё
git checkout <name>             # переключиться в ветку (старый синтаксис)
git switch <name>               # переключиться в ветку (новый, с Git 2.23+)
git checkout -b <name>          # создать и сразу переключиться
git switch -c <name>            # то же самое, но новым синтаксисом
git merge <branch>              # влить указанную ветку в текущую
git rebase <branch>             # переложить коммиты текущей ветки поверх указанной
git branch -d <name>            # удалить локальную ветку (безопасно: только если всё слито)
git branch -D <name>            # удалить локальную ветку (жёстко, даже если не слито)
git push origin --delete <name> # удалить ветку на remote

Я обычно использую switch вместо checkout — меньше путаницы, потому что checkout умеет слишком много всего (переключение веток, восстановление файлов, создание веток...). switch делает ровно одно дело.

Исправление ошибок

Ситуации, в которые я попадаю регулярно: закоммитил не то, не туда, или с кривым сообщением.

# --- Поправить последний коммит ---

git commit --amend -m "новое сообщение"   # изменить сообщение последнего коммита
git commit --amend --no-edit              # добавить забытые изменения в последний коммит,
                                          # не трогая сообщение

# --- Отменить staged (убрать из staging, но сохранить изменения) ---

git restore --staged <file>               # новый синтаксис (Git 2.23+)
git reset HEAD <file>                     # старый синтаксис, всё ещё работает

# --- Откатить изменения в файле (сбросить до последнего коммита) ---

git restore <file>                        # новый синтаксис
git checkout -- <file>                    # старый синтаксис

# --- Откатить коммиты ---

git reset --soft HEAD~1                   # отменить последний коммит, оставить изменения в staging
git reset --mixed HEAD~1                  # отменить коммит, снять staging, но оставить изменения в файлах
git reset --hard HEAD~1                   # отменить коммит и ВСЁ удалить (осторожно!)
git revert <commit-hash>                  # создать новый коммит, отменяющий указанный (безопасно для shared веток)

# --- Временно спрятать изменения ---

git stash                                 # спрятать все незакоммиченные изменения
git stash push -m "описание"              # спрятать с комментарием (через месяц иначе не вспомню что там)
git stash pop                             # вернуть последний stash и удалить его из списка
git stash list                            # посмотреть всё что спрятано
git stash drop stash@{n}                  # удалить конкретный stash

# --- Перенести коммит из другой ветки ---

git cherry-pick <commit-hash>             # применить чужой коммит к текущей ветке

Важное про reset vs revert: reset переписывает историю, revert добавляет новый коммит. Если ветка уже запушена и её кто-то мог склонировать — только revert. Если ветка локальная и кроме меня её никто не видел — reset ок.

Просмотр истории

git log                                    # классика
git log --oneline                          # каждый коммит в одну строку — для быстрого обзора
git log --oneline --graph --all            # дерево всех веток, удобно перед merge
git log --oneline -n 10                    # только последние 10 коммитов
git log --grep="pattern"                   # найти коммиты по тексту в сообщении
git log -S "строка кода"                   # найти коммиты, где строка была добавлена или удалена (pickaxe)

git diff                                   # что изменилось, но ещё не staged
git diff --staged                          # что staged и уйдёт в следующий коммит
git diff <branch1>..<branch2>              # разница между ветками

git blame <file>                           # кто последний трогал каждую строку (и в каком коммите)
git show <commit-hash>                     # показать полный диф конкретного коммита

Мой любимый алиас, без которого уже не могу:

git log --oneline --graph --all -n 20

Показывает полную картину проекта за последние 20 коммитов. Надо бы только не спешить и чаще ее применять, возможно и ошибок было бы меньше...

Удалённые репозитории

git remote -v                              # посмотреть все remote
git remote add <name> <url>                # добавить новый remote
git remote remove <name>                   # удалить
git fetch <remote>                         # забрать изменения, но не применять
git pull <remote> <branch>                 # fetch + merge в одной команде
git push -u origin <branch>                # запушить ветку и запомнить upstream (чтобы потом просто git push)

Conventional Commits — правила оформления коммитов

Конвенция, по которой живёт большинство проектов в 2026 году. Спецификация: conventionalcommits.org v1.0.0. Штука не новая, но до сих пор актуальная — ничего не поменялось с момента принятия спеки, и менять, судя по всему, не планируют.

Суть: коммит-сообщение пишется так, чтобы его могла прочитать и машина (для автосборок, changelog'ов, определения версии), и человек.

Структура

<type>[optional scope]: <description>

[optional body]

[optional footer(s)]

Вот так в одну строку:

docs(git): add stash section to cheatsheet

Или с телом:

fix(auth): handle expired refresh token

The token refresh was silently failing when the refresh endpoint
returned 401, leaving the user stuck on a blank screen. Now we
catch the error and redirect to login.

Closes #142

Типы (type)

Вот полный список. Жирным выделил те, которыми реально пользуюсь.

ТипНазначение
featНовая функциональность. Тянет за собой minor-версию при авторелизе.
fixИсправление бага. Тянет patch-версию.
docsТолько документация. Никаких изменений кода.
styleФорматирование, пробелы, точки с запятой — всё что не меняет логику.
refactorПереписал код, но поведение не изменилось. Ни багов, ни фич.
perfОптимизация производительности.
testДобавил или поправил тесты.
buildСистема сборки, зависимости (npm, cargo, pip, и т.д.).
ciCI/CD пайплайны, конфигурация деплоя.
choreВсё остальное: обновил либу, поправил .gitignore, подтёр мусор. Не меняет production-код.
revertОткат предыдущего коммита. Сообщение: revert: <original-commit-message>.

Scope (необязательно)

Уточняет, какую часть проекта затронул коммит. Пишется в скобках сразу после типа:

feat(auth): add OAuth2 login
fix(ui): correct button alignment on mobile
docs(api): document v2 endpoints

Scope — не тип, и не описание. Он отвечает на вопрос «где?», а не «что?».

Описание (description)

  • На английском. Даже если весь проект на русском — сообщения коммитов пишутся на английском. Так принято в open-source, и так работает автосборка changelog'ов.
  • В повелительном наклонении (imperative mood): «add feature», а не «added feature» или «adds feature». Проверка: сообщение должно продолжать фразу «If applied, this commit will...».
  • Без точки в конце.
  • До 72 символов (по возможности, не догма).

BREAKING CHANGE (критично!)

Если коммит ломает обратную совместимость, это нужно обозначить явно. Два способа:

Способ 1 — восклицательный знак после типа/scope:

feat(api)!: drop support for legacy tokens

Способ 2 — футер BREAKING CHANGE:

feat(api): drop support for legacy tokens

BREAKING CHANGE: All clients must migrate to OAuth2 tokens.
The /v1/auth endpoint is removed.

Оба варианта корректны по спеке. ! короче, но футер даёт больше места для объяснения миграции.

Примеры: правильно и неправильно

Правильно:

feat: add dark mode toggle
fix(parser): handle empty input gracefully
docs: explain branching strategy
chore: bump zola to 0.20.0
refactor(database): extract connection pool to separate module

Неправильно — и почему:

chore(docs): update git.md

docs — это тип коммита, а не scope. Не надо запихивать один тип в scope другого. Если меняешь документацию, пиши docs: update git.md. Если это правда chore (поправил сборку, конфиг, что-то около), то scope — не docs, а что-то другое, либо без scope вообще.

feat: added new button

→ «added» — прошедшее время. Правильно: «add new button».

Feat: add new button

→ Тип всегда lowercase. feat, не Feat.

fix: исправил баг с кодировкой

→ Описание на русском. Пиши на английском. Даже если кажется что «никто кроме меня не увидит» — через месяц сам себе спасибо скажешь.

Update file

→ Нет типа. git log без типа выглядит как свалка. Минимум: chore: update file.

Зачем вообще это всё

  1. Автоматический changelog. Инструменты типа git-cliff, release-please, semantic-release парсят историю коммитов и генерируют CHANGELOG.md сами. Без конвенции — не могут.
  2. Поиск по истории. git log --grep="^feat" — все фичи за раз. git log --grep="^fix" — все багфиксы.
  3. Человекочитаемость. Открываешь git log --oneline и сразу понятно, что происходило, без вчитывания в каждое сообщение.
  4. Semantic Versioning на автомате. fix: → patch, feat: → minor, BREAKING CHANGE: → major. CI делает это сам.

Проверка перед коммитом

Перед git push прогоняю глазами последние 3-5 коммитов:

git log --oneline -5

Если вижу что-то вроде chore(docs): или сообщение на русском — правлю через git rebase -i или git commit --amend, пока не поздно.


Буду дополнять по мере того, как выстрелю себе в ногу новым способом.