diff --git a/GIT_FORCE_WITH_LEASE_RECOVERY.ru.md b/GIT_FORCE_WITH_LEASE_RECOVERY.ru.md new file mode 100644 index 0000000..8631d4c --- /dev/null +++ b/GIT_FORCE_WITH_LEASE_RECOVERY.ru.md @@ -0,0 +1,175 @@ +# Памятка: как синхронизировать локальную ветку после `git push --force-with-lease` + +Эта инструкция подходит для ситуации, когда удалённая ветка была переписана через `git push --force-with-lease`, и теперь локальная ветка расходится с `origin`. + +## Если локальных изменений нет + +Если у тебя **нет никаких локальных изменений, которые нужно сохранить**, это хорошо: можно безопасно заменить указатель локальной ветки на удалённую. + +В таком случае ничего нужного не пропадёт. + +### 1. Сделай `git fetch` + +```bash +git fetch +``` + +### 2. Посмотри, где расходятся ветки + +```bash +git log --oneline --decorate --color --graph --all +``` + +С помощью графа можно увидеть, где локальная и удалённая ветки расходятся в истории. + +Например: + +```text +feature/student +origin/feature/student +``` + +`feature/student` — локальная ветка, `origin/feature/student` — состояние этой ветки в удалённом репозитории. + +### 3. Перемести указатель локальной ветки на удалённую + +Сначала перейди на нужную локальную ветку: + +```bash +git checkout feature/student +``` + +Затем: + +```bash +git reset --hard origin/feature/student +``` + +После этого локальная `feature/student` будет указывать на тот же коммит, что и `origin/feature/student`. + +### Весь сценарий целиком + +```bash +git fetch +git log --oneline --decorate --color --graph --all +git checkout feature/student +git reset --hard origin/feature/student +``` + +--- + +# Если локальные изменения нужно сохранить + +В этом случае **не нужно сразу делать `git reset --hard`**. + +`reset --hard` изменит состояние рабочей директории и может удалить незакоммиченные изменения. + +Сначала нужно сохранить свою работу. + +## Вариант 1. Изменения уже закоммичены + +Если твои изменения находятся в локальных коммитах, самый простой и надёжный вариант — сначала создать дополнительную ветку, которая будет указывать на текущее состояние: + +```bash +git checkout feature/student +git branch backup/feature-student +``` + +Теперь у тебя есть резервная ветка: + +```text +backup/feature-student + ↓ + твои старые коммиты + +feature/student + ↓ + твои старые коммиты +``` + +После этого можно безопаснее двигать `feature/student`: + +```bash +git fetch +git reset --hard origin/feature/student +``` + +Резервная ветка `backup/feature-student` при этом никуда не исчезнет. + +Если позже выяснится, что какие-то коммиты из старой истории нужны, их можно перенести в новую историю с помощью `git cherry-pick`. + +Например: + +```bash +git cherry-pick +``` + +## Вариант 2. Есть незакоммиченные изменения + +Если ты что-то изменил, но ещё не сделал `git commit`, сначала сохрани изменения. + +Один из удобных вариантов — временно убрать их в `stash`: + +```bash +git stash push -u -m "backup before force-push recovery" +``` + +После этого рабочая директория станет чистой, и можно выполнять: + +```bash +git fetch +git checkout feature/student +git reset --hard origin/feature/student +``` + +Затем можно вернуть сохранённые изменения: + +```bash +git stash pop +``` + +Git попытается применить их поверх новой истории. + +Если возникнут конфликты, их нужно будет разрешить вручную. + +--- + +# Самое важное правило + +Перед: + +```bash +git reset --hard origin/feature/student +``` + +нужно ответить на вопрос: + +> **Есть ли у меня локальные изменения, которые я не хочу потерять?** + +### Если нет + +Можно: + +```bash +git reset --hard origin/feature/student +``` + +### Если да, но изменения закоммичены + +Сначала создай резервную ветку: + +```bash +git branch backup/feature-student +``` + +### Если да, но изменения ещё не закоммичены + +Сначала используй `stash`: + +```bash +git stash push -u -m "backup before force-push recovery" +``` + +И только после этого выполняй `reset --hard`. + +**Принцип простой: сначала сохранить то, что может понадобиться, потом двигать указатель ветки.**