Git: полезные настройки, алиасы и типичные проблемы

Пятая часть гида: ускорение работы, лайфхаки, инструменты и разбор ситуаций, с которыми сталкиваются почти все

Полезные настройки

# Цвета и удобный вид
git config --global color.ui auto
git config --global core.pager "less -FRX"

# Автоматически исправлять опечатки в командах (через 2 секунды)
git config --global help.autocorrect 20

# Перенос строк: input на Linux/macOS, true на Windows
git config --global core.autocrlf input

# Включить переиспользование решений конфликтов (rerere)
git config --global rerere.enabled true

# Более умный diff по перемещённым блокам
git config --global diff.colorMoved default

# Быстрее и аккуратнее при pull и push
git config --global pull.rebase true
git config --global push.default current
git config --global push.autoSetupRemote true

# Ветка по умолчанию
git config --global init.defaultBranch main

# Использовать конкретный ключ для подписи коммитов
git config --global user.signingkey ВАШ_КЛЮЧ
git config --global commit.gpgsign true

Алиасы: короткие команды

git config --global alias.st "status -sb"
git config --global alias.co "switch"
git config --global alias.br "branch -vv"
git config --global alias.lg "log --oneline --graph --decorate --all"
git config --global alias.last "log -1 HEAD --stat"
git config --global alias.unstage "restore --staged"
git config --global alias.undo "reset --soft HEAD~1"
git config --global alias.amend "commit --amend --no-edit"
git config --global alias.wip "!git add -A && git commit -m 'WIP'"

После этого git st, git lg и git undo работают как обычные команды. Восклицательный знак в начале делает алиас запуском внешней команды через оболочку.

Вывод истории: форматы

КомандаВариантЧто делает
git log --prettygit log --pretty=format:"%C(yellow)%h%Creset %s %C(blue)(%an)%Creset"Цветной формат: хэш, тема и автор.
git log --dategit log --date=relative -5Относительные даты: «3 days ago».
git log --name-statusgit log --name-status -3Изменённые файлы с типом: A, M, D, R.
git log --allgit log --all --oneline --graphВсе ветки и теги, а не только текущая.
git log -ngit log -n 5 --author="Ivan"Ограничить количество.
git log --no-mergesgit log --oneline --no-merges mainБез коммитов слияния, только реальная работа.
git log --first-parentgit log --first-parent --oneline mainИдти только по основной ветке, без веток фич.
git log ..git log main..feature --onelineКоммиты, которые есть в feature, но нет в main.
git diff --statgit diff --stat main...featureСводка изменений относительно общего предка веток.

Worktree: несколько рабочих папок одного репозитория

Если нужно срочно поправить ветку, не сохраняя текущую работу, создайте отдельную рабочую папку.

git worktree add ../hotfix hotfix/login       # новая папка на существующей ветке
git worktree add -b feat/new ../feat-new main # новая ветка в новой папке
git worktree list                             # все рабочие папки
git worktree remove ../hotfix                 # удалить папку (ветка остаётся)
git worktree prune                            # очистить записи о пропавших папках

Хуки

Хуки — скрипты в папке .git/hooks/, которые Git запускает на разных этапах. Для совместной работы их лучше хранить в репозитории и подключать через core.hooksPath.

ХукКогда запускается
pre-commitперед созданием коммита: линтеры, форматирование, поиск секретов
commit-msgпроверка формата сообщения коммита
pre-pushперед отправкой: тесты
post-checkout / post-mergeпосле переключения и слияния: например, пересборка зависимостей
# Пример: запретить коммит, если в индексе есть файлы .env
mkdir -p .githooks
cat > .githooks/pre-commit <<'EOF'
#!/bin/sh
if git diff --cached --name-only | grep -q '\.env$'; then
  echo "Нельзя коммитить .env"
  exit 1
fi
EOF
chmod +x .githooks/pre-commit
git config core.hooksPath .githooks

.gitignore

# Игнорировать сборочные артефакты
build/
dist/
*.pyc
__pycache__/

# Секреты
.env
*.pem
secrets/

# Редакторы и ОС
.idea/
.vscode/
.DS_Store

# Исключение из правила: оставить конкретный файл
!.env.example
КомандаВариантЧто делает
git check-ignoregit check-ignore -v app.logКакое правило игнорирует файл.
git ls-files -igit ls-files -i --exclude-standardОтслеживаемые файлы, которые при этом игнорируются.
git rm --cachedgit rm -r --cached logs/Перестать отслеживать уже добавленную папку, оставив её на диске.

Решение типичных проблем

1. Случайно закоммитил пароль или ключ

# Если не отправлял: убрать из последнего коммита
git rm --cached secrets.env
echo "secrets.env" >> .gitignore
git commit --amend --no-edit

# Если уже отправил: считайте секрет скомпрометированным.
# 1) немедленно смените его; 2) очистите историю (git filter-repo) и
# попросите коллег пересоздать клоны. Одного revert недостаточно: старый коммит остаётся в истории.

2. Detached HEAD

Вы перешли на тег или коммит, а не на ветку, и новые коммиты могут потеряться при переключении.

git status                        # подтвердит detached HEAD
git switch -c спасение           # создать ветку прямо здесь и сохранить работу
# или, если коммитов не было, просто:
git switch main

3. push отклонён: non-fast-forward

На сервере есть коммиты, которых нет у вас. Не используйте --force без причины.

git fetch origin
git log --oneline HEAD..origin/feature      # что пришло
git rebase origin/feature                   # перенести свои коммиты поверх
git push

4. Нужно «заморозить» файлы, но они уже отслеживаются

# Временно не учитывать локальные изменения в конфиге, не трогая репозиторий
git update-index --skip-worktree config/local.yml
# вернуть учёт
git update-index --no-skip-worktree config/local.yml

5. Слишком большой репозиторий

git count-objects -vH                 # размеры объектов
git gc --aggressive --prune=now       # сжать и очистить (осторожно)
git clone --depth 1 URL               # для сборки без истории
git clone --filter=blob:none URL      # частичный клон

6. Файлы показываются как полностью изменённые

Обычно это разные переводы строк (CRLF и LF). Проверьте core.autocrlf и .gitattributes:

# .gitattributes в корне репозитория
* text=auto eol=lf
*.bat text eol=crlf

7. Не могу удалить ветку, git говорит «not fully merged»

Git защищает от потери коммитов. Если работа действительно не нужна, удалите принудительно: git branch -D имя. Перед этим проверьте git log имя --oneline.

8. Файлы не добавляются в индекс, хотя не в .gitignore

Проверьте, не попадают ли они под правило в глобальном core.excludesFile: git config --get core.excludesFile и git check-ignore -v путь.

Чек-лист перед коммитом и пушем

git status -sb                 # что изменено и куда отстаём
git diff --staged             # что войдёт в коммит
git log --oneline -3          # последние коммиты для контекста
# тесты и линтеры
git commit                    # осмысленное сообщение
git fetch --prune && git rebase origin/main
git push
Не используйте git push --force на общих ветках (main, develop, release). Для собственных веток берите --force-with-lease. А команды git clean -fdx, git reset --hard и git gc --prune=now необратимо удаляют данные: сначала посмотрите, что они затронут (-n, git status).
Сообщения коммитов пишите в императивном стиле и в одну строку темы: «fix: таймаут подключения к БД», а не «исправил таймаут». Тело коммита используйте для объяснения причины. Так историю будет проще читать через git log --oneline и искать через bisect.