Урок 5. Как попасть в реальный проект с автотестами?
Git, GitHub и Pull Request
Темы урока
Зачем Git автоматизатору, commit / branch / pull / merge, конфликт слияния, reset vs revert, cherry-pick, rebase, stash, Pull Request
Видео урока
Конспект урока
Конспект — Урок 5: Как попасть в реальный проект с автотестами?
Главное за урок
Git — не «сохранить файл», а история снимков, ветки и совместная работа. Коммит, ветка, pull и PR — ежедневный минимум. Рядом с ними живут опасные операции: они переписывают историю или переносят чужие коммиты. Их отрабатывают в тренажёре, не на общем main.
После конспекта вы должны отличать reset от revert, понимать cherry-pick и rebase, знать, когда stash, и читать конфликт слияния.
Git и хостинги
Git — движок контроля версий на вашей машине. GitHub — один из хостингов удалённых репозиториев, не синоним Git.
| Примеры | |
|---|---|
| СКВ (движок) | Git (раньше SVN, CVS) |
| Хостинг | GitHub, GitLab, Bitbucket, SourceCraft |
commit / branch / PR устроены так же на любом хостинге. Меняется оболочка, не идеи.
Базовые команды: снимок и ветка
Коммит — снимок проекта в момент времени плюс сообщение зачем. Это не Save в редакторе.
git status # что изменилось
git add tests/login.spec.ts
git commit -m "fix: ждать ошибку на неверном пароле"
git add выбирает, что войдёт в снимок (staging). git commit фиксирует выбранное. В сообщении пиши зачем, не «fix» и не то, что и так видно в diff.
Ветка — параллельная линия истории. main — стабильная. Своя ветка — черновик: пока вы в ней, чужой main не ломаете.
git checkout -b feature/login-error # создать и переключиться
git branch # список; звёздочка — текущая
Два шага вместо одного: git branch feature/login-error → git checkout feature/login-error. То же: git switch -c feature/login-error.
Подтянуть чужое и слить: pull, merge
Локальная копия — снимок на момент клона, не живая синхронизация. Пока вы работали, main на сервере мог уйти вперёд.
git checkout main
git pull origin main
git pull = git fetch (скачать коммиты) + git merge (влить в текущую ветку). Новую ветку заводят от свежего main, иначе потом лишние конфликты.
Merge соединяет две линии: «взять изменения из той ветки сюда».
git checkout main
git merge feature/login-error
Чистый merge — Git сам сложил истории. Если обе ветки правили одну и ту же строку — конфликт.
Конфликт слияния
Git не гадает, чью строку оставить. В файле маркеры:
<<<<<<< HEAD
ожидаем текст «Неверный пароль»
=======
ожидаем статус 401
>>>>>>> feature/login-error
<<<<<<< HEAD— то, что у вас сейчас.=======— разделитель.>>>>>>>— то, что пришло из другой ветки.
Это не поломка репозитория, а выбор руками: оставить одно, другое или оба. Потом:
# правите файл, убираете маркеры
git add путь/к/файлу
git commit # завершает merge
На rebase после правки — git add и git rebase --continue, не новый произвольный commit.
Опасные операции: что переписывает историю
«Опасно» здесь значит: команда меняет уже существующие коммиты или легко уничтожает незакоммиченное. На общей ветке, которую уже кто-то склонировал, так делать нельзя. На своей локальной, которую ещё не пушили, — можно, но сначала в тренажёре.
reset vs revert
| Команда | Что делает | Когда |
|---|---|---|
git reset --hard HEAD~1 |
Стирает последний коммит и рабочую папку до предыдущего снимка. Коммит как будто не существовал | Только свой незапушенный коммит. После push коллеги уже видят этот хеш — reset сломает им историю |
git revert HEAD |
Делает новый коммит, который отменяет изменения старого. История не врёт | Коммит уже в общем main / запушен. Честный откат: «вот правка, вот её отмена» |
git log --oneline # посмотреть хеши
git reset --hard HEAD~1 # убрать последний локальный коммит
git revert abc123 # отменить конкретный общий коммит новым
HEAD~1 — «родитель текущего коммита», на один шаг назад. --hard выкидывает и индекс, и файлы. Есть ещё --soft (коммит убрали, изменения остались в staging) и --mixed (изменения в рабочей папке). Для новичка достаточно: --hard = жёстко стереть, только если коммит ещё не общий.
cherry-pick — один коммит, не вся ветка
В чужой ветке десять коммитов, вам нужен один фикс (таймаут, опечатка в ассерт). Не мержить всю ветку.
git log feature/hotfix --oneline
git checkout main
git cherry-pick abc123
Git копирует патч этого коммита на текущую ветку. Получается новый коммит с тем же смыслом, но другим хешем. Если тот же патч не накладывается — конфликт, как при merge.
Не путать с merge: merge тащит всю историю ветки, cherry-pick — выбранные коммиты.
rebase — поставить свою ветку поверх свежего main
Пока вы писали фичу, в main влили чужие коммиты. Ваша ветка «отстала».
Merge main в фичу добавляет merge-коммит: история с развилкой.
Rebase отрывает ваши коммиты и накатывает их заново поверх нового main. История выглядит линейно: сначала чужое, потом ваше.
git checkout feature/login-error
git fetch origin
git rebase origin/main
# конфликт → правите файл → git add → git rebase --continue
# передумали → git rebase --abort
Почему опасно: rebase переписывает хеши ваших коммитов. Если ветку уже пушили и с неё кто-то ответвился, после rebase им придётся силой переписывать свою копию (push --force). Правило: rebase только свою ветку, которую ещё не шарят, или свою feature до мержа. Никогда не rebase чужой main на сервере.
| merge | rebase | |
|---|---|---|
| История | Развилка + merge-коммит | Линия: ваши коммиты «переехали» |
| Хеши ваших коммитов | Те же | Новые |
| На запушенной общей ветке | Безопасно | Опасно |
stash — спрятать незакоммиченное
Нужно срочно переключить ветку, а в файлах недоделанный тест. Коммитить рано, checkout ругается.
git stash # прячет правки
git checkout main # можно переключаться
git checkout feature/wip
git stash pop # вернуть правки на стол
stash кладёт WIP на полку. Это не коммит в истории ветки. Потерять полку можно (stash drop) — поэтому долгую работу лучше коммитить в свою ветку, а не жить в stash неделями.
Карта: что делать в какой ситуации
| Задача | Команда |
|---|---|
| Посмотреть статус | git status, git log --oneline |
| Своя ветка | git checkout -b имя |
| Снимок | git add … → git commit -m "…" |
| Отправить ветку | git push -u origin имя |
Подтянуть main |
git checkout main → git pull |
| Влить ветку | git merge имя |
| Конфликт | убрать маркеры → git add → git commit (или rebase --continue) |
| Стереть свой последний незапушенный коммит | git reset --hard HEAD~1 |
| Отменить уже общий коммит | git revert <хеш> |
| Забрать один чужой коммит | git cherry-pick <хеш> |
Поставить свою ветку на свежий main |
git rebase main (своя ветка, не общий main) |
| Спрятать WIP | git stash / git stash pop |
Опасные (reset --hard, rebase, cherry-pick на конфликтных файлах) сначала в Git-тренажёре, не на боевом main.
Pull Request
PR — просьба посмотреть diff вашей ветки относительно main, не «отправить файл в чат». В команде путь такой: ветка → коммит → push → PR → комментарии по строкам → новый коммит в ту же ветку (PR обновляется сам) → merge.
main часто защищён: пушить туда напрямую нельзя. Комментарий ревью — про строку кода, не про автора.
Ключевые тезисы для теста
- Git — движок; GitHub / GitLab / Bitbucket / SourceCraft — хостинги.
addвыбирает файлы,commitделает снимок; это не Save.pullподтягивает чужие коммиты; новую ветку заводят от свежегоmain.- Конфликт: маркеры
<<<<<<</=======/>>>>>>>, правка руками, затемadd+commit. reset --hardстирает незапушенный коммит;revertотменяет общий новым коммитом.cherry-pickкопирует один коммит, не всю ветку.rebaseпереносит ваши коммиты поверх другой ветки и меняет их хеши — не делать на общемmain.stashпрячет незакоммиченное, чтобы сменить ветку.
Домашнее задание
Индивидуальная проверка ДЗ — на Boosty
Конспект, видео и тест открыты всем. Текст задания и проверка работы — по подписке.
Индивидуальная проверка ДЗ на Boosty