🐛 Типичные ошибки — Ветви в Git

К оглавлению урока

⚡ Топ-4 ошибки при работе с ветками

  1. git branch -D вместо -d — уничтожает неслитые коммиты безвозвратно.
  2. Detached HEAD — коммиты без ветки потеряются. Сразу создайте ветку.
  3. Забыли .gitignore перед первым git add — чувствительные файлы уже в индексе.
  4. Переключение ветки с незакоммиченными изменениями — изменения могут конфликтовать. Используйте stash.

1. Принудительное удаление ветки (git branch -D)

⚠️ ОПАСНО: git branch -D <branch>
git branch -D feature безвозвратно удаляет все коммиты ветки, если они не были слиты в другую ветку. Git не спрашивает подтверждения. После удаления восстановить коммиты можно только если вы помните их хэши (через git reflog).

Безопасная альтернатива: используйте git branch -d feature (строчная «d»). Git откажет удалить ветку с неслитыми изменениями и защитит вас от случайной потери данных.
# Безопасное удаление — Git откажет если есть неслитые коммиты:
git branch -d feature

# Принудительное — ТОЛЬКО если уверены что всё слито:
git branch -D feature   # ⚠️ необратимо!
Способ проверить перед удалением: git log main..feature — показывает коммиты в feature, которых нет в main. Если вывод пустой — ветка безопасно удаляется.

2. Detached HEAD — коммиты без ветки

⚠️ ОПАСНО: Detached HEAD state
Если вы переключились на хэш коммита (git checkout abc1234), Git сообщает: «You are in 'detached HEAD' state». В этом состоянии новые коммиты не принадлежат ни одной ветке. Когда вы переключитесь на другую ветку, эти коммиты станут недостижимыми и будут удалены при следующей сборке мусора (git gc).

Что делать немедленно:
# Если вы уже в Detached HEAD и хотите сохранить работу:
git checkout -b my-save-branch

# Проверить, что вы уже не в detached HEAD:
git status  # должно показать: On branch my-save-branch

3. Создание .gitignore после первого git add

⚠️ Внимание: файлы уже в индексе

Ситуация: вы добавили .env с паролями в репозиторий, потом создали .gitignore — но файл всё равно отслеживается.

Причина: .gitignore игнорирует только файлы, которые ещё не добавлены в индекс. Если файл уже отслеживается — он остаётся в репозитории.

# Если файл уже в индексе — удалить из отслеживания (не удаляя локально):
git rm --cached .env
echo ".env" >> .gitignore
git add .gitignore
git commit -m "Remove .env from tracking, add to .gitignore"

Правило: создавайте .gitignore до первого git add.

4. Переключение ветки с незакоммиченными изменениями

Ошибка:

git checkout main
# error: Your local changes to the following files would be overwritten by checkout:
#     app.js
# Please commit your changes or stash them before you switch branches.

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

Решение:

# Вариант 1: закоммитить изменения
git add app.js
git commit -m "WIP: save progress"
git checkout main

# Вариант 2: спрятать через stash
git stash
git checkout main
# ... поработать в main ...
git checkout feature
git stash pop    # вернуть изменения

5. Переключение на удалённую ветку без fetch

Ошибка:

git checkout feature/remote
# error: pathspec 'feature/remote' did not match any file(s) known to git

Причина: локальный Git не знает об удалённой ветке — нужно сначала получить список.

Решение:

git fetch --all
git checkout feature/remote