docs(git): add force-with-lease recovery guide
This commit is contained in:
@@ -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 <commit>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Вариант 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`.
|
||||||
|
|
||||||
|
**Принцип простой: сначала сохранить то, что может понадобиться, потом двигать указатель ветки.**
|
||||||
Reference in New Issue
Block a user