docs: add Git Flow tutorial and organize Git guides
This commit is contained in:
@@ -0,0 +1,122 @@
|
||||
# Работа с зависимостями между Git-ветками
|
||||
|
||||
## Сценарий
|
||||
|
||||
Предположим, мы находимся в ветке:
|
||||
|
||||
```bash
|
||||
feature/student
|
||||
```
|
||||
|
||||
В этой ветке реализуется функциональность, связанная со `Student`.
|
||||
|
||||
При этом у нас появляется новая, независимая по смыслу фича:
|
||||
|
||||
```bash
|
||||
feature/sorting
|
||||
```
|
||||
|
||||
Для реализации сортировки нам необходим класс или интерфейс `Student`, который уже был создан в `feature/student`.
|
||||
|
||||
## Как создать новую ветку
|
||||
|
||||
Если нам необходимо продолжить разработку `feature/sorting`, используя текущее состояние `feature/student`, создаём новую ветку **от `feature/student`**.
|
||||
|
||||
Сначала переключаемся на `feature/student`:
|
||||
|
||||
```bash
|
||||
git checkout feature/student
|
||||
```
|
||||
|
||||
Затем создаём новую ветку:
|
||||
|
||||
```bash
|
||||
git branch feature/sorting
|
||||
```
|
||||
|
||||
После этого история будет выглядеть примерно так:
|
||||
|
||||
```text
|
||||
feature/sorting
|
||||
/
|
||||
---------------●
|
||||
\
|
||||
feature/student
|
||||
```
|
||||
|
||||
Обе ветки на момент создания указывают на один и тот же коммит.
|
||||
|
||||
Теперь в `feature/sorting` доступен весь код, который был добавлен в `feature/student`, в том числе `Student`.
|
||||
|
||||
Чтобы перейти в новую ветку:
|
||||
|
||||
```bash
|
||||
git checkout feature/sorting
|
||||
```
|
||||
|
||||
## Почему важно создавать ветку именно таким образом
|
||||
|
||||
В данном случае `feature/sorting` зависит от кода, находящегося в `feature/student`.
|
||||
|
||||
При этом сами фичи логически разные:
|
||||
|
||||
- `feature/student` — разработка `Student`;
|
||||
- `feature/sorting` — реализация сортировки;
|
||||
- `Student` нужен в `feature/sorting` как зависимость для реализации сортировки.
|
||||
|
||||
Поэтому не стоит продолжать разработку сортировки непосредственно в `feature/student`. Лучше создать отдельную ветку от того состояния, где необходимый код уже существует.
|
||||
|
||||
---
|
||||
|
||||
## Если ветки уже разошлись
|
||||
|
||||
Иногда невозможно создать `feature/sorting` непосредственно от нужного места в истории `feature/student`.
|
||||
|
||||
Например, `feature/sorting` уже была создана раньше:
|
||||
|
||||
```text
|
||||
A---B---C---D feature/student
|
||||
\
|
||||
E---F---G feature/sorting
|
||||
```
|
||||
|
||||
В таком случае можно получить изменения из `feature/student` посредством слияния (merge).
|
||||
|
||||
Находясь в `feature/sorting`, выполняем:
|
||||
|
||||
```bash
|
||||
git checkout feature/sorting
|
||||
git merge feature/student
|
||||
```
|
||||
|
||||
История станет примерно такой:
|
||||
|
||||
```text
|
||||
A---B---C---D feature/student
|
||||
\ \
|
||||
E---F---G---M feature/sorting
|
||||
```
|
||||
|
||||
Коммит `M` — результат слияния двух веток.
|
||||
|
||||
После этого в `feature/sorting` будут доступны изменения из `feature/student`, в том числе необходимый `Student`.
|
||||
|
||||
## Главное правило
|
||||
|
||||
**Если новая фича зависит от кода из другой ветки, но при этом является самостоятельной по смыслу — создаём для неё отдельную ветку, используя нужную ветку как основу.**
|
||||
|
||||
Если новую ветку можно создать непосредственно от нужного состояния исходной ветки:
|
||||
|
||||
```bash
|
||||
git checkout feature/student
|
||||
git branch feature/sorting
|
||||
```
|
||||
|
||||
Если ветки уже разошлись и создать её от нужного состояния невозможно:
|
||||
|
||||
```bash
|
||||
git checkout feature/sorting
|
||||
git merge feature/student
|
||||
```
|
||||
|
||||
Таким образом, мы сохраняем логическое разделение фич и одновременно можем использовать необходимый код из другой ветки.
|
||||
@@ -0,0 +1,78 @@
|
||||
# Настройка Git для проекта
|
||||
|
||||
Перед началом работы с проектом необходимо настроить имя и email автора коммитов
|
||||
|
||||
Настройки необходимо выполнить непосредственно в директории проекта:
|
||||
|
||||
```bash
|
||||
git config user.name "Фамилия Имя"
|
||||
git config user.email "email@example.com"
|
||||
```
|
||||
|
||||
### Требования к `user.name`
|
||||
|
||||
`user.name` необходимо указывать в формате:
|
||||
|
||||
```text
|
||||
Фамилия Имя
|
||||
```
|
||||
|
||||
Требования:
|
||||
|
||||
- Фамилия и Имя указываются на русском языке
|
||||
- Первые буквы Фамилии и Имени должны быть заглавными
|
||||
- Между Фамилией и Именем используется один пробел
|
||||
|
||||
Пример:
|
||||
|
||||
```bash
|
||||
git config user.name "Иванов Иван"
|
||||
```
|
||||
|
||||
### Требования к `user.email`
|
||||
|
||||
`user.email` должен быть действующим email-адресом, по которому можно связаться с разработчиком
|
||||
|
||||
Пример:
|
||||
|
||||
```bash
|
||||
git config user.email "ivan.ivanov@example.com"
|
||||
```
|
||||
|
||||
### Почему без `--global`
|
||||
|
||||
В командах намеренно не используется параметр `--global`:
|
||||
|
||||
```bash
|
||||
git config user.name "Фамилия Имя"
|
||||
git config user.email "email@example.com"
|
||||
```
|
||||
|
||||
В таком случае настройки применяются **только к текущему Git-репозиторию**
|
||||
|
||||
Использование:
|
||||
|
||||
```bash
|
||||
git config --global user.name "Фамилия Имя"
|
||||
git config --global user.email "email@example.com"
|
||||
```
|
||||
|
||||
изменило бы глобальные настройки Git на компьютере разработчика и повлияло бы на все его репозитории
|
||||
|
||||
Данное требование относится именно к этому проекту, поэтому настройки должны быть локальными для репозитория
|
||||
|
||||
### Проверка настроек
|
||||
|
||||
После настройки можно проверить значения:
|
||||
|
||||
```bash
|
||||
git config user.name
|
||||
git config user.email
|
||||
```
|
||||
|
||||
Ожидаемый результат:
|
||||
|
||||
```text
|
||||
Фамилия Имя
|
||||
email@example.com
|
||||
```
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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