↓Перейти к содержанию
  1. Git: руководства и команды/

10 частых ошибок в Git и как их избежать

·5 минут·

Git прощает многие ошибки — большинство можно отменить. Но некоторые ошибки дорого обходятся команде. Вот 10 наиболее распространённых, с объяснением почему они происходят и как их исправить.

1. Забыли сделать git add для новых файлов #

# Ошибка: git commit -a не добавляет новые файлы
touch new-feature.js
git commit -am "Add new feature"
# new-feature.js НЕ попал в коммит!

git status
# Untracked files:
#   new-feature.js

# Исправление:
git add new-feature.js
git commit --amend --no-edit  # добавить в последний коммит
# или
git commit -m "Add new-feature.js (forgot in previous commit)"

Профилактика: всегда проверяйте git status перед git commit.

2. Плохие сообщения коммитов #

# Плохо:
git commit -m "fix"
git commit -m "update"
git commit -m "wip"
git commit -m "asdfgh"
git commit -m "изменения"

# Хорошо:
git commit -m "fix: resolve null pointer in user login"
git commit -m "feat: add password strength indicator"
git commit -m "docs: update API authentication guide"

Почему важно: через 6 месяцев git log с плохими сообщениями — бесполезен. Невозможно найти когда и почему был внесён конкретный баг.

Исправление: git commit --amend -m "new message" для последнего коммита. Для предыдущих — interactive rebase.

3. Слишком большие коммиты #

# Плохо: один коммит с 20 несвязанными изменениями
git add -A
git commit -m "Various updates"  # изменено 15 файлов в 5 разных фичах

# Хорошо: отдельный коммит для каждого логического изменения
git add src/auth.js src/auth.test.js
git commit -m "feat: implement JWT authentication"

git add src/profile.js src/profile.test.js
git commit -m "feat: add user profile editing"

Почему важно: при бисекции (git bisect) или revert, маленькие коммиты позволяют точно найти проблему.

4. Работа напрямую в main #

# Плохо:
git switch main
git commit -am "feat: add experimental feature"
git push origin main

# Хорошо:
git switch -c feature/experimental-feature
git commit -am "feat: add experimental feature"
git push origin feature/experimental-feature
# → Pull Request → Review → Merge

Почему важно: прямые коммиты в main обходят code review, могут сломать production, усложняют откат.

5. Игнорирование .gitignore #

# Распространённые проблемы:
git add .
# Случайно добавлены: node_modules/, .env, *.log, dist/

# Исправление: создать .gitignore до первого git add
cat > .gitignore << 'EOF'
node_modules/
.env
*.log
dist/
.DS_Store
*.swp
EOF

# Если уже закоммитили:
git rm --cached -r node_modules/
git rm --cached .env
git commit -m "Remove accidentally tracked files"

Совет: используйте gitignore.io для генерации по языку/фреймворку.

6. Force push в общие ветки #

# Опасно:
git push --force origin main  # НИКОГДА не делайте это в main!

# Что происходит:
# - Коллеги теряют коммиты из своих локальных копий
# - История расходится
# - Данные могут быть безвозвратно потеряны

# Безопаснее: --force-with-lease
git push --force-with-lease origin feature/my-branch
# Отклонит push если remote ветка изменилась (защита от перезаписи чужих коммитов)

Правило: force push допустим только в вашей личной feature ветке (которую никто не использует). В main — никогда.

7. Большие бинарные файлы в репозитории #

# Плохо: коммит больших файлов
git add video.mp4        # 200 МБ
git add database.sql     # 50 МБ dump
git add design.psd       # 100 МБ

# Git репозиторий разрастается и клонирование становится медленным

# Решение 1: .gitignore для больших файлов
echo "*.sql" >> .gitignore
echo "*.psd" >> .gitignore

# Решение 2: Git LFS для нужных больших файлов
git lfs install
git lfs track "*.mp4"
git lfs track "*.psd"
git add .gitattributes

Если уже закоммитили: git filter-repo --path-glob '*.sql' --invert-paths

8. Merge вместо rebase для обновления ветки #

# Результат: засорённая история с merge коммитами
# "Merge branch 'main' into feature/my-feature" повторяется 10 раз

# Лучше: rebase для обновления feature ветки
git fetch origin
git rebase origin/main

# Чистая линейная история
git log --oneline
# a1b2c3d feat: add user profile
# c3d4e5f feat: implement JWT auth
# ... (далее коммиты main)

Правило: rebase для обновления вашей feature ветки, merge для финального слияния в main.

9. Не использовать git stash или worktree #

# Ошибка: переключение веток с незакоммиченными изменениями
git switch main
# error: Your local changes to the following files would be overwritten

# Или хуже: запустить git switch -f и потерять изменения

# Правильно: сохранить изменения перед переключением
git stash push -m "WIP: user profile form"
git switch main
# ... исправить баг ...
git switch feature/user-profile
git stash pop

10. Путаница reset и revert #

# git reset — переписывает историю (опасно для shared branches)
git reset --hard HEAD~2  # УДАЛЯЕТ 2 последних коммита

# git revert — создаёт новый коммит-отмену (безопасно)
git revert HEAD          # создаёт коммит отменяющий последний

# Правило:
# - reset: только для локальных, ещё не запушенных коммитов
# - revert: для коммитов которые уже на remote

# Если случайно сделали reset — восстановить через reflog
git reflog
git reset --hard HEAD@{2}  # вернуться к состоянию 2 операции назад

Общие принципы избежания ошибок #

# 1. Всегда проверять статус перед коммитом
git status
git diff --staged

# 2. Использовать dry-run где возможно
git add --dry-run -A
git rm --dry-run *.log

# 3. Атомарные коммиты
# Один коммит = одно логическое изменение

# 4. Регулярно пушить feature ветки (backup)
git push origin feature/my-feature

# 5. Настроить алиасы для безопасности
git config --global alias.pushfl 'push --force-with-lease'

# 6. Изучить git reflog как инструмент восстановления
git reflog  # история всех операций HEAD

Часто задаваемые вопросы #

Можно ли полностью удалить файл из истории? Да, через git filter-repo --path file.txt --invert-paths, но это требует force push и пересинхронизации всей команды. Смените скомпрометированные секреты немедленно.

Как предотвратить случайные коммиты секретов? Используйте pre-commit хуки (detect-secrets пакет), .gitignore для .env файлов, и git-secrets инструмент.

Что делать если запушил что-то плохое? Не паникуйте. Если секреты — немедленно смените их (они уже скомпрометированы). Затем git filter-repo для очистки истории. Если просто плохой коммит — git revert или force push с --force-with-lease если ветка личная.

Заключение #

Большинство Git ошибок можно исправить через git reflog, git revert или git reset. Ключевые правила: маленькие осмысленные коммиты, никогда не force push в main, используйте .gitignore с самого начала, rebase вместо merge для обновления feature веток. Подробнее об отмене изменений — git revert и git reflog.

По теме #