Git: продвинутые паттерны¶
Зачем это DE?¶
Git — не только add-commit-push. Rebase для чистой истории, bisect для поиска сломавшего коммита, hooks для автопроверок, cherry-pick для точечных фиксов — инструменты, которые экономят часы.
Rebase vs Merge¶
Merge — сохраняет историю¶
Bash
git checkout main
git merge feature/orders
# Создаёт merge-коммит, сохраняет все коммиты feature-ветки
Rebase — линейная история¶
Не ребейси опубликованные коммиты
git rebase меняет хеши. Если ветка уже в remote — force push сломает коллегам историю. Ребейсь только свои локальные коммиты.
Interactive rebase — редактирование истории¶
Bash
git rebase -i HEAD~3
# Открывается редактор:
# pick abc1234 Add orders model
# pick def5678 Fix typo
# pick ghi9012 Add tests
# Можно:
# squash def5678 — объединить с предыдущим
# reword abc1234 — изменить сообщение
# drop ghi9012 — удалить коммит
# edit abc1234 — остановиться для изменений
Cherry-pick — точечный перенос¶
Bash
# Перенести конкретный коммит из другой ветки
git cherry-pick abc1234
# Несколько коммитов
git cherry-pick abc1234 def5678
# Без автокоммита (для доработки)
git cherry-pick --no-commit abc1234
Когда: hotfix в main нужно перенести в release-ветку. Или один коммит из feature нужен в другой feature.
Bisect — бинарный поиск бага¶
Bash
# Знаем: в HEAD баг есть, в v1.0 — нет
git bisect start
git bisect bad HEAD
git bisect good v1.0
# Git переключает на середину. Проверяем:
python -m pytest tests/
git bisect good # или git bisect bad
# Повторяем, пока Git не найдёт виновный коммит
# Результат: abc1234 is the first bad commit
git bisect reset # вернуться к HEAD
Автоматический bisect¶
Bash
git bisect start HEAD v1.0
git bisect run python -m pytest tests/test_orders.py
# Git сам прогоняет тест на каждом шаге
Hooks — автоматизация¶
Pre-commit hook¶
Bash
# .git/hooks/pre-commit (или через pre-commit framework)
#!/bin/bash
set -e
# Проверить форматирование Python
black --check .
# Проверить SQL-файлы
sqlfluff lint models/
# Запретить коммит секретов
grep -rn "password\s*=" --include="*.py" && exit 1
echo "All checks passed"
Pre-commit framework¶
YAML
# .pre-commit-config.yaml
repos:
- repo: https://github.com/psf/black
rev: 24.4.2
hooks:
- id: black
- repo: https://github.com/sqlfluff/sqlfluff
rev: 3.0.0
hooks:
- id: sqlfluff-lint
args: [--dialect, postgres]
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.6.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: detect-private-key
- id: no-commit-to-branch
args: [--branch, main]
Stash — временное сохранение¶
Bash
# Сохранить незакоммиченные изменения
git stash
# Вернуть
git stash pop
# Список stash'ей
git stash list
# Применить конкретный stash
git stash apply stash@{2}
# Stash с сообщением
git stash push -m "WIP: orders refactoring"
Работа с историей¶
log — чтение истории¶
Bash
# Красивый лог
git log --oneline --graph --all
# Кто менял файл
git log --follow -p models/orders.sql
# Что менялось за последнюю неделю
git log --since="1 week ago" --oneline
# Поиск по содержимому коммита
git log -S "def transform_orders" --oneline
blame — кто написал строку¶
reflog — страховка¶
Bash
# Все перемещения HEAD (даже после reset!)
git reflog
# Восстановить «потерянный» коммит
git checkout abc1234
# или
git reset --hard abc1234
Стратегии ветвления¶
Git Flow¶
Text Only
main ─────────────────────────────→
hotfix └──fix──┘
release └──────rc──────┘
develop ─────────────────────────────→
feature └──feat/orders──┘
Когда: релизный цикл, версионирование (v1.0, v2.0).
Trunk-Based Development¶
Когда: CI/CD, частые деплои, маленькие PR. Рекомендуется для DE-проектов (dbt, Airflow DAGs).
Что запомнить¶
| Инструмент | Когда использовать |
|---|---|
| rebase | Чистая линейная история перед merge |
| cherry-pick | Точечный перенос коммита между ветками |
| bisect | Поиск коммита, сломавшего тест |
| hooks | Автопроверки перед коммитом |
| stash | Переключение контекста без коммита |
| reflog | Восстановление после ошибочного reset |