Как переключиться на другую ветку с несохранёнными изменениями в Git?
Что проверяют
Знаете ли вы, что Git не всегда запрещает переключение с изменениями, и умеете ли выбрать способ под ситуацию: stash, WIP-коммит или отдельный worktree. Следом обычно спрашивают, чем stash pop отличается от stash apply и куда деваются новые файлы.
Как отвечать
Сначала поведение по умолчанию. git switch other (или старый git checkout other) переносит незакоммиченные изменения в целевую ветку, если они не конфликтуют с её файлами. Если конфликтуют, Git откажет с сообщением Your local changes to the following files would be overwritten и ничего не потеряет.
Дальше варианты:
- stash:
git stash push -m "описание", потомgit stash popилиapply.popудаляет запись из стека,applyоставляет. Неотслеживаемые файлы по умолчанию не прячутся, для них нужен флаг-u; - WIP-коммит:
git commit -m "wip", а по возвращенииgit reset --soft HEAD~1. Удобнее, если работа откладывается надолго: коммит привязан к ветке и не затеряется в общем стеке stash; - перенос в новую ветку:
git switch -c feature/x, если правки начаты не в той ветке; - слияние на лету:
git switch -m otherделает трёхстороннее слияние локальных правок с целевой веткой; - worktree:
git worktree add ../hotfix mainдаёт вторую рабочую копию, где можно чинить прод, не трогая текущую работу; - выбросить изменения:
git switch --discard-changes otherилиgit restore ., это необратимо.
Для Java-проекта полезно добавить, что в IntelliJ IDEA есть свой механизм Shelve, он хранит изменения на уровне IDE, и Smart Checkout, который прячет правки перед переключением и возвращает их после. А каталоги сборки target/ и build/ должны быть в .gitignore, иначе они будут мешать переключению постоянно.
Где спотыкаются
Уверены, что stash прячет всё. Новые неотслеживаемые файлы остаются в рабочей копии и уезжают на другую ветку вместе с вами.
Путают pop и apply. При конфликте pop запись не удаляет, и её потом забывают в стеке.
Предлагают checkout -f как обычный способ. Это потеря работы, про него говорят только с оговоркой.