Перейти к содержанию

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-ветки
Text Only
main:    A─B─C───────M
              \     /
feature:       D─E─F

Rebase — линейная история

Bash
git checkout feature/orders
git rebase main
# Перемещает коммиты feature на вершину main
Text Only
main:    A─B─C
feature:       D'─E'─F'  (новые хеши!)

Не ребейси опубликованные коммиты

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

Bash
pip install pre-commit
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]
Bash
pre-commit install      # установить hooks
pre-commit run --all    # прогнать на всех файлах

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 — кто написал строку

Bash
git blame models/orders.sql
# Показывает автора и коммит для каждой строки

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

Text Only
main     ─A──B──C──D──E──F──G──────→
feature    └─x─┘  └─y─┘

Когда: CI/CD, частые деплои, маленькие PR. Рекомендуется для DE-проектов (dbt, Airflow DAGs).


Что запомнить

Инструмент Когда использовать
rebase Чистая линейная история перед merge
cherry-pick Точечный перенос коммита между ветками
bisect Поиск коммита, сломавшего тест
hooks Автопроверки перед коммитом
stash Переключение контекста без коммита
reflog Восстановление после ошибочного reset

Проверь себя


Источники